static void check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data, gpg_err_code_t decrypt_fail_code) { gcry_sexp_t plain; gcry_mpi_t x; int rc; /* Create plain text. */ x = gcry_mpi_new (nbits_data); gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM); rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x); if (rc) die ("converting data for encryption failed: %s\n", gcry_strerror (rc)); check_keys_crypt (pkey, skey, plain, decrypt_fail_code); gcry_sexp_release (plain); gcry_mpi_release (x); /* Create plain text. */ x = gcry_mpi_new (nbits_data); gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM); rc = gcry_sexp_build (&plain, NULL, "(data (flags raw no-blinding) (value %m))", x); gcry_mpi_release (x); if (rc) die ("converting data for encryption failed: %s\n", gcry_strerror (rc)); check_keys_crypt (pkey, skey, plain, decrypt_fail_code); gcry_sexp_release (plain); }
int ECDSA_verify(const char *msg, const struct affine_point *Q, const gcry_mpi_t sig, const struct curve_params *cp) { gcry_mpi_t e, r, s; struct affine_point X1, X2; int res = 0; r = gcry_mpi_new(0); s = gcry_mpi_new(0); gcry_mpi_div(s, r, sig, cp->dp.order, 0); if (gcry_mpi_cmp_ui(s, 0) <= 0 || gcry_mpi_cmp(s, cp->dp.order) >= 0 || gcry_mpi_cmp_ui(r, 0) <= 0 || gcry_mpi_cmp(r, cp->dp.order) >= 0) goto end; gcry_mpi_scan(&e, GCRYMPI_FMT_USG, msg, 64, NULL); gcry_mpi_mod(e, e, cp->dp.order); gcry_mpi_invm(s, s, cp->dp.order); gcry_mpi_mulm(e, e, s, cp->dp.order); X1 = pointmul(&cp->dp.base, e, &cp->dp); gcry_mpi_mulm(e, r, s, cp->dp.order); X2 = pointmul(Q, e, &cp->dp); point_add(&X1, &X2, &cp->dp); gcry_mpi_release(e); if (! point_is_zero(&X1)) { gcry_mpi_mod(s, X1.x, cp->dp.order); res = ! gcry_mpi_cmp(s, r); } point_release(&X1); point_release(&X2); end: gcry_mpi_release(r); gcry_mpi_release(s); return res; }
/* compute 2^m (mod phi(p)), for a prime p */ static gcry_mpi_t twopowmodphi(uint64_t m, const gcry_mpi_t p) { gcry_mpi_t phi, r; int n; phi = gcry_mpi_new(0); gcry_mpi_sub_ui(phi, p, 1); /* count number of used bits in m */ for (n = 0; ((uint64_t)1 << n) <= m; n++) ; r = gcry_mpi_new(0); gcry_mpi_set_ui(r, 1); while (n) { /* square and multiply algorithm for fast exponentiation */ n--; gcry_mpi_mulm(r, r, r, phi); if (m & ((uint64_t)1 << n)) { gcry_mpi_add(r, r, r); if (gcry_mpi_cmp(r, phi) >= 0) gcry_mpi_sub(r, r, phi); } } gcry_mpi_release(phi); return r; }
static char *test_serialization() { struct gotr_dhe_skey priv; struct gotr_dhe_pkey pub; gcry_mpi_t x1, x2, y1, y2; gcry_mpi_point_t p1, p2; unsigned char *ser; gotr_ecdhe_key_create(&priv); gotr_ecdhe_key_get_public(&priv, &pub); p1 = deserialize_point(pub.q_y, 32); ser = serialize_point(p1); mu_assert("ERROR: deserialization->serialization failed", memcmp(pub.q_y, ser, 32) == 0); x1 = gcry_mpi_new(0); x2 = gcry_mpi_new(0); y1 = gcry_mpi_new(0); y2 = gcry_mpi_new(0); p2 = deserialize_point(ser, 32); free(ser); gcry_mpi_ec_get_affine(x1, y1, p1, edctx); gcry_mpi_ec_get_affine(x2, y2, p2, edctx); int res = gcry_mpi_cmp(x1, x2) || gcry_mpi_cmp(y1, y2); gcry_mpi_point_release(p1); gcry_mpi_point_release(p2); mu_assert("ERROR: serialization->deserialization failed", res == 0); return 0; }
/* Check that right shifting actually works for an amount larger than the number of bits per limb. */ static void test_rshift (int pass) { gcry_mpi_t a, b; char *result, *result2; int i; wherestr = "test_rshift"; show ("checking that rshift works as expected (pass %d)\n", pass); a = gcry_mpi_new (0); b = gcry_mpi_new (0); gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM); for (i=0; i < 75; i++) { gcry_mpi_rshift (b, a, i); result = mpi2bitstr (b, 72); result2 = mpi2bitstr (a, 72); rshiftbitstring (result2, i); if (strcmp (result, result2)) { show ("got =%s\n", result); show ("want=%s\n", result2); fail ("rshift by %d failed\n", i); } xfree (result); xfree (result2); } /* Again. This time using in-place operation. */ gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM); for (i=0; i < 75; i++) { gcry_mpi_release (b); b = gcry_mpi_copy (a); gcry_mpi_rshift (b, b, i); result = mpi2bitstr (b, 72); result2 = mpi2bitstr (a, 72); rshiftbitstring (result2, i); if (strcmp (result, result2)) { show ("got =%s\n", result); show ("want=%s\n", result2); fail ("in-place rshift by %d failed\n", i); } xfree (result2); xfree (result); } gcry_mpi_release (b); gcry_mpi_release (a); }
/** * Unblind a blind-signed signature. The signature should have been generated * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with * #GNUNET_CRYPTO_rsa_blind(). * * @param sig the signature made on the blinded signature purpose * @param bkey the blinding key used to blind the signature purpose * @param pkey the public key of the signer * @return unblinded signature on success, NULL on error */ struct GNUNET_CRYPTO_rsa_Signature * GNUNET_CRYPTO_rsa_unblind (struct GNUNET_CRYPTO_rsa_Signature *sig, struct GNUNET_CRYPTO_rsa_BlindingKey *bkey, struct GNUNET_CRYPTO_rsa_PublicKey *pkey) { gcry_mpi_t n; gcry_mpi_t s; gcry_mpi_t r_inv; gcry_mpi_t ubsig; int ret; struct GNUNET_CRYPTO_rsa_Signature *sret; ret = key_from_sexp (&n, pkey->sexp, "public-key", "n"); if (0 != ret) ret = key_from_sexp (&n, pkey->sexp, "rsa", "n"); if (0 != ret) { GNUNET_break_op (0); return NULL; } ret = key_from_sexp (&s, sig->sexp, "sig-val", "s"); if (0 != ret) ret = key_from_sexp (&s, sig->sexp, "rsa", "s"); if (0 != ret) { gcry_mpi_release (n); GNUNET_break_op (0); return NULL; } r_inv = gcry_mpi_new (0); if (1 != gcry_mpi_invm (r_inv, bkey->r, n)) { GNUNET_break_op (0); gcry_mpi_release (n); gcry_mpi_release (r_inv); gcry_mpi_release (s); return NULL; } ubsig = gcry_mpi_new (0); gcry_mpi_mulm (ubsig, s, r_inv, n); gcry_mpi_release (n); gcry_mpi_release (r_inv); gcry_mpi_release (s); sret = GNUNET_new (struct GNUNET_CRYPTO_rsa_Signature); GNUNET_assert (0 == gcry_sexp_build (&sret->sexp, NULL, "(sig-val (rsa (s %M)))", ubsig)); gcry_mpi_release (ubsig); return sret; }
const char* genGcryptRand(unsigned char* x){ size_t scanned; unsigned char *result; gcry_mpi_t a = gcry_mpi_new(0); gcry_mpi_t r = gcry_mpi_new(0); gcry_mpi_scan(&a, GCRYMPI_FMT_HEX, x, 0, &scanned); gen_rand(r, a); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &result, NULL, r); return result; }
unsigned char* inv(unsigned char* x, unsigned char* y){ size_t scanned; unsigned char *result; gcry_mpi_t a = gcry_mpi_new(0); gcry_mpi_t b = gcry_mpi_new(0); gcry_mpi_scan(&a, GCRYMPI_FMT_HEX, x, 0, &scanned); gcry_mpi_scan(&b, GCRYMPI_FMT_HEX, y, 0, &scanned); gcry_mpi_invm(a, a, b); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &result, NULL, a); return result; }
static void set_get_point (void) { gcry_mpi_point_t point; gcry_mpi_t x, y, z; wherestr = "set_get_point"; show ("checking point setting functions\n"); point = gcry_mpi_point_new (0); x = gcry_mpi_set_ui (NULL, 17); y = gcry_mpi_set_ui (NULL, 42); z = gcry_mpi_set_ui (NULL, 11371); gcry_mpi_point_get (x, y, z, point); if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) fail ("new point not initialized to (0,0,0)\n"); gcry_mpi_point_snatch_get (x, y, z, point); point = NULL; if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) fail ("snatch_get failed\n"); gcry_mpi_release (x); gcry_mpi_release (y); gcry_mpi_release (z); point = gcry_mpi_point_new (0); x = gcry_mpi_set_ui (NULL, 17); y = gcry_mpi_set_ui (NULL, 42); z = gcry_mpi_set_ui (NULL, 11371); gcry_mpi_point_set (point, x, y, z); gcry_mpi_set_ui (x, 23); gcry_mpi_set_ui (y, 24); gcry_mpi_set_ui (z, 25); gcry_mpi_point_get (x, y, z, point); if (gcry_mpi_cmp_ui (x, 17) || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) fail ("point_set/point_get failed\n"); gcry_mpi_point_snatch_set (point, x, y, z); x = gcry_mpi_new (0); y = gcry_mpi_new (0); z = gcry_mpi_new (0); gcry_mpi_point_get (x, y, z, point); if (gcry_mpi_cmp_ui (x, 17) || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) fail ("point_snatch_set/point_get failed\n"); gcry_mpi_point_release (point); gcry_mpi_release (x); gcry_mpi_release (y); gcry_mpi_release (z); }
static void test_keys( RSA_secret_key *sk, unsigned nbits ) { RSA_public_key pk; gcry_mpi_t test = gcry_mpi_new ( nbits ); gcry_mpi_t out1 = gcry_mpi_new ( nbits ); gcry_mpi_t out2 = gcry_mpi_new ( nbits ); pk.n = sk->n; pk.e = sk->e; gcry_mpi_randomize( test, nbits, GCRY_WEAK_RANDOM ); public( out1, test, &pk );
unsigned char* modPow(unsigned char* x, unsigned char* y, unsigned char* z){ size_t scanned; unsigned char *result; gcry_mpi_t a = gcry_mpi_new(0); gcry_mpi_t b = gcry_mpi_new(0); gcry_mpi_t c = gcry_mpi_new(0); gcry_mpi_scan(&a, GCRYMPI_FMT_HEX, x, 0, &scanned); gcry_mpi_scan(&b, GCRYMPI_FMT_HEX, y, 0, &scanned); gcry_mpi_scan(&c, GCRYMPI_FMT_HEX, z, 0, &scanned); gcry_mpi_powm(a, a, b, c); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &result, NULL, a); return result; }
/* Compose $(xp,xq) \in Z_p \times Z_q$ into $x \in Z_n$ using Chinese Remainder Theorem */ static void CRT_compose(gcry_mpi_t *x, const gcry_mpi_t xp, const gcry_mpi_t xq, const gcry_mpi_t p, const gcry_mpi_t q) { gcry_mpi_t a, u; a = gcry_mpi_new(0); u = gcry_mpi_new(0); *x = gcry_mpi_new(0); gcry_mpi_subm(a, xq, xp, q); gcry_mpi_invm(u, p, q); gcry_mpi_mulm(a, a, u, q); /* a = (xq - xp) / p (mod q) */ gcry_mpi_mul(*x, p, a); gcry_mpi_add(*x, *x, xp); /* x = p * ((xq - xp) / p mod q) + xp */ gcry_mpi_release(a); gcry_mpi_release(u); }
ZrtpDH::ZrtpDH(const char* type){ // Well - the algo type is only 4 char thus cast to int32 and compare if (*(int32_t*)type == *(int32_t*)dh2k) { pkType = DH2K; } else if (*(int32_t*)type == *(int32_t*)dh3k) { pkType = DH3K; } else { fprintf(stderr, "Unknown pubkey algo: %d\n", pkType); } ctx = static_cast<void*>(new gcryptCtx); gcryptCtx* tmpCtx = static_cast<gcryptCtx*>(ctx); tmpCtx->privKey = NULL; tmpCtx->pubKey = NULL; initializeGcrypt(); if (!dhinit) { gcry_mpi_scan(&bnP2048, GCRYMPI_FMT_USG, P2048, sizeof(P2048), NULL); gcry_mpi_scan(&bnP3072, GCRYMPI_FMT_USG, P3072, sizeof(P3072), NULL); // gcry_mpi_scan(&bnP4096, GCRYMPI_FMT_USG, P4096, sizeof(P4096), NULL); two = gcry_mpi_set_ui(NULL, 2); bnP2048MinusOne = gcry_mpi_new(sizeof(P2048)*8); gcry_mpi_sub_ui(bnP2048MinusOne, bnP2048, 1); bnP3072MinusOne = gcry_mpi_new(sizeof(P3072)*8); gcry_mpi_sub_ui(bnP3072MinusOne, bnP3072, 1); // bnP4096MinusOne = gcry_mpi_new(sizeof(P4096)*8); // gcry_mpi_sub_ui(bnP4096MinusOne, bnP4096, 1); dhinit = 1; } if (pkType == DH3K) { tmpCtx->privKey = gcry_mpi_new(256); gcry_mpi_randomize(tmpCtx->privKey, 256, GCRY_STRONG_RANDOM); } else if (pkType == DH2K) { tmpCtx->privKey = gcry_mpi_new(512); gcry_mpi_randomize(tmpCtx->privKey, 512, GCRY_STRONG_RANDOM); } // else { // tmpCtx->privKey = gcry_mpi_new(512); // gcry_mpi_randomize(tmpCtx->privKey, 512, GCRY_STRONG_RANDOM); // } }
const char* spakeNext(unsigned char* mIn, unsigned char* passHash){ size_t scanned; unsigned char *skString; unsigned char *mString; gcry_mpi_t a = gcry_mpi_new(0); gcry_mpi_t sk = gcry_mpi_new(0); gcry_mpi_t m = gcry_mpi_new(0); gcry_mpi_t X = gcry_mpi_new(0); gcry_mpi_scan(&m, GCRYMPI_FMT_HEX, mIn, 0, &scanned); gcry_mpi_scan(&a, GCRYMPI_FMT_HEX, passHash, 0, &scanned); spake_next_client(&sk, &X, m, a); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &skString, NULL, sk); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &mString, NULL, X); return concat(concat(skString, ","), mString); }
/** * Multiply the generator g of the elliptic curve by @a val * to obtain the point on the curve representing @a val. * Afterwards, point addition will correspond to integer * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to * convert a point back to an integer (as long as the * integer is smaller than the MAX of the @a edc context). * * @param edc calculation context for ECC operations * @param val value to encode into a point * @return representation of the value as an ECC point, * must be freed using #GNUNET_CRYPTO_ecc_free() */ gcry_mpi_point_t GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc, int val) { gcry_mpi_t fact; gcry_mpi_t n; gcry_mpi_point_t g; gcry_mpi_point_t r; g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); GNUNET_assert (NULL != g); fact = gcry_mpi_new (0); if (val < 0) { n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1); gcry_mpi_set_ui (fact, - val); gcry_mpi_sub (fact, n, fact); gcry_mpi_release (n); } else { gcry_mpi_set_ui (fact, val); } r = gcry_mpi_point_new (0); gcry_mpi_ec_mul (r, fact, g, edc->ctx); gcry_mpi_release (fact); gcry_mpi_point_release (g); return r; }
void gotr_ecbd_gen_flake_key(gcry_mpi_point_t *ret, gcry_mpi_point_t y0, gcry_mpi_t r1, gcry_mpi_point_t R1, gcry_mpi_point_t R0, gcry_mpi_point_t V1) { gcry_mpi_point_t tmp = gcry_mpi_point_new(0); gcry_mpi_t n = gcry_mpi_new(0); gcry_mpi_point_release(*ret); *ret = gcry_mpi_point_new(0); gcry_mpi_mul_ui(n, r1, 4); gcry_mpi_ec_mul(*ret, n, y0, edctx); gcry_mpi_set_ui(n, 3); gcry_mpi_ec_mul(tmp, n, R1, edctx); gcry_mpi_ec_add(*ret, *ret, tmp, edctx); gcry_mpi_ec_dup(tmp, R0, edctx); gcry_mpi_ec_add(*ret, *ret, tmp, edctx); gcry_mpi_ec_add(*ret, *ret, V1, edctx); gcry_mpi_point_release(tmp); gcry_mpi_release(n); }
static int test_add (void) { gcry_mpi_t one; gcry_mpi_t two; gcry_mpi_t ff; gcry_mpi_t result; unsigned char* pc; gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL); gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL); result = gcry_mpi_new(0); gcry_mpi_add(result, one, two); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); if (verbose) printf("Result of one plus two:\n%s\n", pc); gcry_free(pc); gcry_mpi_add(result, ff, one); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); if (verbose) printf("Result of ff plus one:\n%s\n", pc); gcry_free(pc); gcry_mpi_release(one); gcry_mpi_release(two); gcry_mpi_release(ff); gcry_mpi_release(result); return 1; }
int32_t ZrtpDH::computeSecretKey(uint8_t *pubKeyBytes, uint8_t *secret) { int32_t length = getDhSize(); gcryptCtx* tmpCtx = static_cast<gcryptCtx*>(ctx); gcry_mpi_t pubKeyOther; gcry_mpi_t sec = gcry_mpi_new(0); gcry_mpi_scan(&pubKeyOther, GCRYMPI_FMT_USG, pubKeyBytes, length, NULL); if (pkType == DH2K) { gcry_mpi_powm(sec, pubKeyOther, tmpCtx->privKey, bnP2048); } else if (pkType == DH3K) { gcry_mpi_powm(sec, pubKeyOther, tmpCtx->privKey, bnP3072); } else { // gcry_mpi_powm(sec, pubKeyOther, tmpCtx->privKey, bnP4096); return 0; } gcry_mpi_release(pubKeyOther); size_t result; gcry_mpi_print(GCRYMPI_FMT_USG, secret, length, &result, sec); gcry_mpi_release(sec); return result; }
/* Choose a random value x and calculate e = g^x mod p. Returns e and if ret_x is not NULL x. */ static gcry_mpi_t calc_dh_secret (gcry_mpi_t gex_g, gcry_mpi_t gex_p, gcry_mpi_t * ret_x) { gcry_mpi_t e, g, x, prime; size_t n = sizeof diffie_hellman_group1_prime; if (gex_p) prime = gcry_mpi_copy (gex_p); else if (gcry_mpi_scan (&prime, GCRYMPI_FMT_STD, diffie_hellman_group1_prime, n, NULL)) abort (); /*_gsti_dump_mpi( "prime=", prime );*/ if (gex_g) g = gcry_mpi_copy (gex_g); else g = gcry_mpi_set_ui (NULL, 2); /* FIXME: we n bits for the private exponent, where n is 2*derrived_key_material */ x = gcry_mpi_snew (200); gcry_mpi_randomize (x, 200, GCRY_STRONG_RANDOM); n = gcry_mpi_get_nbits (prime); e = gcry_mpi_new (n+1); gcry_mpi_powm (e, g, x, prime); if (ret_x) *ret_x = x; else gcry_mpi_release (x); gcry_mpi_release (g); gcry_mpi_release (prime); return e; }
/** * Generate a random value mod n. * * @param edc ECC context * @return random value mod n. */ gcry_mpi_t GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc) { gcry_mpi_t n; unsigned int highbit; gcry_mpi_t r; n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1); /* check public key for number of bits, bail out if key is all zeros */ highbit = 256; /* Curve25519 */ while ( (! gcry_mpi_test_bit (n, highbit)) && (0 != highbit) ) highbit--; GNUNET_assert (0 != highbit); /* generate fact < n (without bias) */ GNUNET_assert (NULL != (r = gcry_mpi_new (0))); do { gcry_mpi_randomize (r, highbit + 1, GCRY_STRONG_RANDOM); } while (gcry_mpi_cmp (r, n) >= 0); gcry_mpi_release (n); return r; }
static void do_powm ( const char *n_str, const char *e_str, const char *m_str) { gcry_mpi_t e, n, msg, cip; gcry_error_t err; int i; err = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, n_str, 0, 0); if (err) BUG (); err = gcry_mpi_scan (&e, GCRYMPI_FMT_HEX, e_str, 0, 0); if (err) BUG (); err = gcry_mpi_scan (&msg, GCRYMPI_FMT_HEX, m_str, 0, 0); if (err) BUG (); cip = gcry_mpi_new (0); start_timer (); for (i=0; i < 1000; i++) gcry_mpi_powm (cip, msg, e, n); stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); /* { */ /* char *buf; */ /* if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf, NULL, cip)) */ /* BUG (); */ /* printf ("result: %s\n", buf); */ /* gcry_free (buf); */ /* } */ gcry_mpi_release (cip); gcry_mpi_release (msg); gcry_mpi_release (n); gcry_mpi_release (e); }
/* This is to check a bug reported by bpgcrypt at itaparica.org on 2006-07-31 against libgcrypt 1.2.2. */ static void one_bit_only (int highbit) { gcry_mpi_t a; char *result; int i; wherestr = "one_bit_only"; show ("checking that set_%sbit does only set one bit\n", highbit?"high":""); a = gcry_mpi_new (0); gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM); gcry_mpi_set_ui (a, 0); if (highbit) gcry_mpi_set_highbit (a, 42); else gcry_mpi_set_bit (a, 42); if (!gcry_mpi_test_bit (a, 42)) fail ("failed to set a bit\n"); gcry_mpi_clear_bit (a, 42); if (gcry_mpi_test_bit (a, 42)) fail ("failed to clear a bit\n"); result = mpi2bitstr (a, 70); assert (strlen (result) == 70); for (i=0; result[i]; i++) if ( result[i] != '0' ) break; if (result[i]) fail ("spurious bits detected\n"); xfree (result); gcry_mpi_release (a); }
static void print_point (const char *text, gcry_mpi_point_t a) { gcry_mpi_t x, y, z; x = gcry_mpi_new (0); y = gcry_mpi_new (0); z = gcry_mpi_new (0); gcry_mpi_point_get (x, y, z, a); print_mpi_2 (text, ".x", x); print_mpi_2 (text, ".y", y); print_mpi_2 (text, ".z", z); gcry_mpi_release (x); gcry_mpi_release (y); gcry_mpi_release (z); }
int main (int argc, char *argv[]) { struct GNUNET_TIME_Absolute start; struct GNUNET_CRYPTO_PaillierPublicKey public_key; struct GNUNET_CRYPTO_PaillierPrivateKey private_key; struct GNUNET_CRYPTO_PaillierCiphertext c1; gcry_mpi_t m1; unsigned int i; start = GNUNET_TIME_absolute_get (); for (i=0;i<10;i++) GNUNET_CRYPTO_paillier_create (&public_key, &private_key); printf ("10x key generation took %s\n", GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES)); GAUGER ("UTIL", "Paillier key generation", 64 * 1024 / (1 + GNUNET_TIME_absolute_get_duration (start).rel_value_us / 1000LL), "keys/ms"); m1 = gcry_mpi_new (0); m1 = gcry_mpi_set_ui (m1, 1); /* m1 = m1 * 2 ^ (GCPB - 3) */ gcry_mpi_mul_2exp (m1, m1, GNUNET_CRYPTO_PAILLIER_BITS - 3); start = GNUNET_TIME_absolute_get (); for (i=0;i<10;i++) GNUNET_CRYPTO_paillier_encrypt (&public_key, m1, 2, &c1); printf ("10x encryption took %s\n", GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES)); GAUGER ("UTIL", "Paillier encryption", 64 * 1024 / (1 + GNUNET_TIME_absolute_get_duration (start).rel_value_us / 1000LL), "ops/ms"); start = GNUNET_TIME_absolute_get (); for (i=0;i<10;i++) GNUNET_CRYPTO_paillier_decrypt (&private_key, &public_key, &c1, m1); printf ("10x decryption took %s\n", GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES)); GAUGER ("UTIL", "Paillier decryption", 64 * 1024 / (1 + GNUNET_TIME_absolute_get_duration (start).rel_value_us / 1000LL), "ops/ms"); return 0; }
/** * Do pre-calculation for ECC discrete logarithm for small factors. * * @param max maximum value the factor can be * @param mem memory to use (should be smaller than @a max), must not be zero. * @return @a max if dlog failed, otherwise the factor */ struct GNUNET_CRYPTO_EccDlogContext * GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, unsigned int mem) { struct GNUNET_CRYPTO_EccDlogContext *edc; unsigned int K = ((max + (mem-1)) / mem); gcry_mpi_point_t g; struct GNUNET_PeerIdentity key; gcry_mpi_point_t gKi; gcry_mpi_t fact; gcry_mpi_t n; unsigned int i; GNUNET_assert (max < INT32_MAX); edc = GNUNET_new (struct GNUNET_CRYPTO_EccDlogContext); edc->max = max; edc->mem = mem; edc->map = GNUNET_CONTAINER_multipeermap_create (mem * 2, GNUNET_NO); GNUNET_assert (0 == gcry_mpi_ec_new (&edc->ctx, NULL, CURVE)); g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); GNUNET_assert (NULL != g); fact = gcry_mpi_new (0); gKi = gcry_mpi_point_new (0); for (i=0;i<=mem;i++) { gcry_mpi_set_ui (fact, i * K); gcry_mpi_ec_mul (gKi, fact, g, edc->ctx); extract_pk (gKi, edc->ctx, &key); GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (edc->map, &key, (void*) (long) i + max, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); } /* negative values */ n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1); for (i=1;i<mem;i++) { gcry_mpi_set_ui (fact, i * K); gcry_mpi_sub (fact, n, fact); gcry_mpi_ec_mul (gKi, fact, g, edc->ctx); extract_pk (gKi, edc->ctx, &key); GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (edc->map, &key, (void*) (long) max - i, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); } gcry_mpi_release (fact); gcry_mpi_release (n); gcry_mpi_point_release (gKi); gcry_mpi_point_release (g); return edc; }
nuts_mpi_t nuts_mpi_new_random(const unsigned int nbits) { gcry_check(); gcry_mpi_t mpi = gcry_mpi_new(nbits); gcry_mpi_randomize(mpi, nbits, GCRY_STRONG_RANDOM); gcry_mpi_set_bit(mpi, nbits - 1); gcry_mpi_set_bit(mpi, 0); return nuts_mpi_alloc(mpi); }
static void mpz_tdiv_q_2exp (gcry_mpi_t q, gcry_mpi_t n, unsigned int b) { gcry_mpi_t u, d; u = gcry_mpi_set_ui (NULL, 1); d = gcry_mpi_new (0); gcry_mpi_mul_2exp (d, u, b); gcry_mpi_div (q, NULL, n, d, 0); }
/* Check that a freshly generated key actually works. Returns 0 on success. */ static int test_keys (RSA_secret_key *sk, unsigned int nbits) { int result = -1; /* Default to failure. */ RSA_public_key pk; gcry_mpi_t plaintext = gcry_mpi_new (nbits); gcry_mpi_t ciphertext = gcry_mpi_new (nbits); gcry_mpi_t decr_plaintext = gcry_mpi_new (nbits); gcry_mpi_t signature = gcry_mpi_new (nbits); /* Put the relevant parameters into a public key structure. */ pk.n = sk->n; pk.e = sk->e; /* Create a random plaintext. */ gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM); /* Encrypt using the public key. */ public (ciphertext, plaintext, &pk);
int gotr_point_cmp(const gcry_mpi_point_t a, const gcry_mpi_point_t b) { gcry_mpi_t ax = gcry_mpi_new(0); gcry_mpi_t ay = gcry_mpi_new(0); gcry_mpi_t bx = gcry_mpi_new(0); gcry_mpi_t by = gcry_mpi_new(0); int ret = 1; gotr_assert(a && b); if (!gcry_mpi_ec_get_affine(ax, ay, a, edctx) && !gcry_mpi_ec_get_affine(bx, by, b, edctx)) ret = gcry_mpi_cmp(ax, bx) || gcry_mpi_cmp(ay, by); gcry_mpi_release(ax); gcry_mpi_release(ay); gcry_mpi_release(bx); gcry_mpi_release(by); return ret; }
/** * Do some DLOG operations for testing. * * @param edc context for ECC operations * @param do_dlog #GNUNET_YES if we want to actually do the bencharked operation */ static void test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, int do_dlog) { gcry_mpi_t fact; gcry_mpi_t n; gcry_ctx_t ctx; gcry_mpi_point_t q; gcry_mpi_point_t g; unsigned int i; int x; int iret; GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); g = gcry_mpi_ec_get_point ("g", ctx, 0); GNUNET_assert (NULL != g); n = gcry_mpi_ec_get_mpi ("n", ctx, 0); q = gcry_mpi_point_new (0); fact = gcry_mpi_new (0); for (i=0;i<TEST_ITER;i++) { fprintf (stderr, "."); x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, MAX_FACT); if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 2)) { gcry_mpi_set_ui (fact, x); gcry_mpi_sub (fact, n, fact); x = - x; } else { gcry_mpi_set_ui (fact, x); } gcry_mpi_ec_mul (q, fact, g, ctx); if ( (GNUNET_YES == do_dlog) && (x != (iret = GNUNET_CRYPTO_ecc_dlog (edc, q))) ) { fprintf (stderr, "DLOG failed for value %d (%d)\n", x, iret); GNUNET_assert (0); } } gcry_mpi_release (fact); gcry_mpi_release (n); gcry_mpi_point_release (g); gcry_mpi_point_release (q); gcry_ctx_release (ctx); fprintf (stderr, "\n"); }