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; }
void point_add(struct affine_point *p1, const struct affine_point *p2, const struct domain_params *dp) { if (! point_is_zero(p2)) { if (! point_is_zero(p1)) { if (! gcry_mpi_cmp(p1->x, p2->x)) { if (! gcry_mpi_cmp(p1->y, p2->y)) point_double(p1, dp); else point_load_zero(p1); } else { gcry_mpi_t t; t = gcry_mpi_snew(0); gcry_mpi_subm(t, p1->y, p2->y, dp->m); gcry_mpi_subm(p1->y, p1->x, p2->x, dp->m); gcry_mpi_invm(p1->y, p1->y, dp->m); gcry_mpi_mulm(p1->y, t, p1->y, dp->m); gcry_mpi_mulm(t, p1->y, p1->y, dp->m); gcry_mpi_addm(p1->x, p1->x, p2->x, dp->m); gcry_mpi_subm(p1->x, t, p1->x, dp->m); gcry_mpi_subm(t, p2->x, p1->x, dp->m); gcry_mpi_mulm(p1->y, p1->y, t, dp->m); gcry_mpi_subm(p1->y, p1->y, p2->y, dp->m); gcry_mpi_release(t); } } else point_set(p1, p2); } }
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; }
/* Algorithm 4.26 in the "Guide to Elliptic Curve Cryptography" */ int embedded_key_validation(const struct affine_point *p, const struct domain_params *dp) { if (gcry_mpi_cmp_ui(p->x, 0) < 0 || gcry_mpi_cmp(p->x, dp->m) >= 0 || gcry_mpi_cmp_ui(p->y, 0) < 0 || gcry_mpi_cmp(p->y, dp->m) >= 0) return 0; return ! point_is_zero(p) && point_on_curve(p, dp); }
int mixin_key_and_curve(struct affine_point *P, gcry_mpi_t pubkey, const struct curve_params *cp) { int yflag, res; if ((yflag = (gcry_mpi_cmp(pubkey, cp->dp.m) >= 0))) gcry_mpi_sub(pubkey, pubkey, cp->dp.m); res = gcry_mpi_cmp_ui(pubkey, 0) >= 0 && gcry_mpi_cmp(pubkey, cp->dp.m) < 0 && point_decompress(P, pubkey, yflag, &cp->dp); return res; }
/** * 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; }
/** * Compare the values of two blinding keys. * * @param b1 one key * @param b2 the other key * @return 0 if the two are equal */ int GNUNET_CRYPTO_rsa_blinding_key_cmp (struct GNUNET_CRYPTO_rsa_BlindingKey *b1, struct GNUNET_CRYPTO_rsa_BlindingKey *b2) { return gcry_mpi_cmp (b1->r, b2->r); }
/* 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; }
void jacobian_affine_point_add(struct jacobian_point *p1, const struct affine_point *p2, const struct domain_params *dp) { if (! point_is_zero(p2)) { if (gcry_mpi_cmp_ui(p1->z, 0)) { gcry_mpi_t t1, t2, t3; t1 = gcry_mpi_snew(0); t2 = gcry_mpi_snew(0); gcry_mpi_mulm(t1, p1->z, p1->z, dp->m); gcry_mpi_mulm(t2, t1, p2->x, dp->m); gcry_mpi_mulm(t1, t1, p1->z, dp->m); gcry_mpi_mulm(t1, t1, p2->y, dp->m); if (! gcry_mpi_cmp(p1->x, t2)) { if (! gcry_mpi_cmp(p1->y, t1)) jacobian_double(p1, dp); else jacobian_load_zero(p1); } else { t3 = gcry_mpi_snew(0); gcry_mpi_subm(p1->x, p1->x, t2, dp->m); gcry_mpi_subm(p1->y, p1->y, t1, dp->m); gcry_mpi_mulm(p1->z, p1->z, p1->x, dp->m); gcry_mpi_mulm(t3, p1->x, p1->x, dp->m); gcry_mpi_mulm(t2, t2, t3, dp->m); gcry_mpi_mulm(t3, t3, p1->x, dp->m); gcry_mpi_mulm(t1, t1, t3, dp->m); gcry_mpi_mulm(p1->x, p1->y, p1->y, dp->m); gcry_mpi_subm(p1->x, p1->x, t3, dp->m); gcry_mpi_subm(p1->x, p1->x, t2, dp->m); gcry_mpi_subm(p1->x, p1->x, t2, dp->m); gcry_mpi_subm(t2, t2, p1->x, dp->m); gcry_mpi_mulm(p1->y, p1->y, t2, dp->m); gcry_mpi_subm(p1->y, p1->y, t1, dp->m); gcry_mpi_release(t3); } gcry_mpi_release(t1); gcry_mpi_release(t2); } else jacobian_load_affine(p1, p2); } }
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; }
gcry_mpi_t get_random_exponent(const struct curve_params *cp) { int bits = gcry_mpi_get_nbits(cp->dp.order); gcry_mpi_t a; a = gcry_mpi_snew(0); do { gcry_mpi_randomize(a, bits, GCRY_STRONG_RANDOM); gcry_mpi_clear_highbit(a, bits); } while (! gcry_mpi_cmp_ui(a, 0) || gcry_mpi_cmp(a, cp->dp.order) >= 0); return a; }
/* Compare A to B, where B is given as a hex string. */ static int cmp_mpihex (gcry_mpi_t a, const char *b) { gcry_mpi_t bval; int res; bval = hex2mpi (b); res = gcry_mpi_cmp (a, bval); gcry_mpi_release (bval); return res; }
/* deterministically generate from seed/idx a quadratic residue (mod n) */ static gcry_mpi_t gensquare(const gcry_mpi_t n, const void *seed, size_t seedlen, uint32_t idx, unsigned secpar) { size_t buflen = secpar / 8; uint8_t buf[buflen]; gcry_mpi_t x; det_randomize(buf, buflen, seed, seedlen, idx); buf[0] &= 0x7f; /* clear upper bit, so that we have x < n */ x = mpi_import(buf, buflen); assert(gcry_mpi_cmp(x, n) < 0); gcry_mpi_mulm(x, x, x, n); return x; }
int nuts_mpi_cmp(const nuts_mpi_t mpi1, const nuts_mpi_t mpi2) { if (mpi1 == NULL && mpi2 == NULL) { return 0; } else if (mpi1 == NULL && mpi2 != NULL) { return -1 * gcry_mpi_cmp_ui(mpi2->mpi, 0); return 0; } else if (mpi1 != NULL && mpi2 == NULL) { return gcry_mpi_cmp_ui(mpi1->mpi, 0); } else /* mpi1 != NULL && mpi2 != NULL */ { return gcry_mpi_cmp(mpi1->mpi, mpi2->mpi); } }
int p2p_convert_private_key(RSA *key, gcry_sexp_t *r_key) { size_t err; char *buf; gcry_mpi_t n_mpi, e_mpi, d_mpi, p_mpi, q_mpi, u_mpi; buf = BN_bn2hex(key->n); gcry_mpi_scan(&n_mpi, GCRYMPI_FMT_HEX, buf, 0, &err); OPENSSL_free(buf); buf = BN_bn2hex(key->e); gcry_mpi_scan(&e_mpi, GCRYMPI_FMT_HEX, buf, 0, &err); OPENSSL_free(buf); buf = BN_bn2hex(key->d); gcry_mpi_scan(&d_mpi, GCRYMPI_FMT_HEX, buf, 0, &err); OPENSSL_free(buf); buf = BN_bn2hex(key->p); gcry_mpi_scan(&p_mpi, GCRYMPI_FMT_HEX, buf, 0, &err); OPENSSL_free(buf); buf = BN_bn2hex(key->q); gcry_mpi_scan(&q_mpi, GCRYMPI_FMT_HEX, buf, 0, &err); OPENSSL_free(buf); buf = BN_bn2hex(key->iqmp); gcry_mpi_scan(&u_mpi, GCRYMPI_FMT_HEX, buf, 0, &err); OPENSSL_free(buf); if(gcry_mpi_cmp(p_mpi, q_mpi) > 0) { gcry_mpi_swap(p_mpi, q_mpi); gcry_mpi_invm(u_mpi, p_mpi, q_mpi); } gcry_sexp_build(r_key, &err, "(private-key (rsa (n %m) (e %m) (d %m) (p %m) (q %m) (u %m)))", n_mpi, e_mpi, d_mpi, p_mpi, q_mpi, u_mpi); gcry_mpi_release(n_mpi); gcry_mpi_release(e_mpi); gcry_mpi_release(d_mpi); gcry_mpi_release(p_mpi); gcry_mpi_release(q_mpi); gcry_mpi_release(u_mpi); gcry_error_t sane = gcry_pk_testkey(*r_key); if(sane) { return -1; } return 0; }
/* Compare A to B, where B is given as a hex string. */ static int cmp_mpihex (gcry_mpi_t a, const char *b) { gcry_mpi_t bval; int res; if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) bval = hex2mpiopa (b); else bval = hex2mpi (b); res = gcry_mpi_cmp (a, bval); gcry_mpi_release (bval); return res; }
int32_t ZrtpDH::checkPubKey(uint8_t *pubKeyBytes) const { gcry_mpi_t pubKeyOther = NULL; gcry_mpi_scan(&pubKeyOther, GCRYMPI_FMT_USG, pubKeyBytes, getDhSize(), NULL); if (pkType == DH2K) { if (gcry_mpi_cmp(bnP2048MinusOne, pubKeyOther) == 0) return 0; } else if (pkType == DH3K) { if (gcry_mpi_cmp(bnP3072MinusOne, pubKeyOther) == 0) return 0; } else { // if (gcry_mpi_cmp(bnP4096MinusOne, pubKeyOther) == 0) return 0; } if (gcry_mpi_cmp_ui(pubKeyOther, 1) == 0) { return 0; } gcry_mpi_release(pubKeyOther); return 1; }
static void extract_cmp_mpi (gcry_sexp_t sexp, const char *name, const char *expected) { gcry_sexp_t l1; gcry_mpi_t a, b; l1 = gcry_sexp_find_token (sexp, name, 0); a = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); b = mpi_from_string (expected); if (!a) fail ("parameter \"%s\" missing in key\n", name); else if ( gcry_mpi_cmp (a, b) ) fail ("parameter \"%s\" does not match expected value\n", name); gcry_mpi_release (b); gcry_mpi_release (a); gcry_sexp_release (l1); }
int point_on_curve(const struct affine_point *p, const struct domain_params *dp) { int res; if (! (res = point_is_zero(p))) { gcry_mpi_t h1, h2; h1 = gcry_mpi_snew(0); h2 = gcry_mpi_snew(0); gcry_mpi_mulm(h1, p->x, p->x, dp->m); gcry_mpi_addm(h1, h1, dp->a, dp->m); gcry_mpi_mulm(h1, h1, p->x, dp->m); gcry_mpi_addm(h1, h1, dp->b, dp->m); gcry_mpi_mulm(h2, p->y, p->y, dp->m); res = ! gcry_mpi_cmp(h1, h2); gcry_mpi_release(h1); gcry_mpi_release(h2); } return res; }
gboolean egg_dh_gen_pair (gcry_mpi_t prime, gcry_mpi_t base, guint bits, gcry_mpi_t *pub, gcry_mpi_t *priv) { guint pbits; g_return_val_if_fail (prime, FALSE); g_return_val_if_fail (base, FALSE); g_return_val_if_fail (pub, FALSE); g_return_val_if_fail (priv, FALSE); pbits = gcry_mpi_get_nbits (prime); g_return_val_if_fail (pbits > 1, FALSE); if (bits == 0) { bits = pbits; } else if (bits > pbits) { g_return_val_if_reached (FALSE); } /* * Generate a strong random number of bits, and not zero. * gcry_mpi_randomize bumps up to the next byte. Since we * need to have a value less than half of prime, we make sure * we bump down. */ *priv = gcry_mpi_snew (bits); g_return_val_if_fail (*priv, FALSE); while (gcry_mpi_cmp_ui (*priv, 0) == 0) gcry_mpi_randomize (*priv, bits, GCRY_STRONG_RANDOM); /* Secret key value must be less than half of p */ if (gcry_mpi_get_nbits (*priv) > bits) gcry_mpi_clear_highbit (*priv, bits); if (gcry_mpi_get_nbits (*priv) > pbits - 1) gcry_mpi_clear_highbit (*priv, pbits - 1); g_assert (gcry_mpi_cmp (prime, *priv) > 0); *pub = gcry_mpi_new (gcry_mpi_get_nbits (*priv)); g_return_val_if_fail (*pub, FALSE); gcry_mpi_powm (*pub, base, *priv, prime); return TRUE; }
static gsti_error_t check_dh_mpi_range (gcry_mpi_t gex_p, gcry_mpi_t chk) { gsti_error_t err = 0; gcry_mpi_t p; /* A value which is not in the range [1, p-1] is considered as a protocol violation. */ if (gex_p) p = gcry_mpi_copy (gex_p); else if (gcry_mpi_scan (&p, GCRYMPI_FMT_STD, diffie_hellman_group1_prime, sizeof diffie_hellman_group1_prime, NULL)) #warning why abort? abort (); if (gcry_mpi_cmp (chk, p) > 0 || gcry_mpi_get_nbits (chk) < 2) err = gsti_error (GPG_ERR_PROTOCOL_VIOLATION); gcry_mpi_release (p); return err; }
static void test_asn1_integers (Test *test, gconstpointer unused) { GNode *asn; gcry_mpi_t mpi, mpt; GBytes *data; gboolean ret; asn = egg_asn1x_create (test_asn1_tab, "TestIntegers"); g_assert ("asn test structure is null" && asn != NULL); /* Make a random number */ mpi = gcry_mpi_new (512); g_return_if_fail (mpi); gcry_mpi_randomize (mpi, 512, GCRY_WEAK_RANDOM); /* Write the mpi out */ ret = gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "mpi", NULL), mpi); g_assert ("couldn't write mpi to asn1" && ret); /* Now encode the whole caboodle */ data = egg_asn1x_encode (asn, NULL); g_assert ("encoding asn1 didn't work" && data != NULL); egg_asn1x_destroy (asn); /* Now decode it all nicely */ asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestIntegers", data); g_assert (asn != NULL); ret = gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "mpi", NULL), &mpt); egg_asn1x_destroy (asn); g_assert ("couldn't read mpi from asn1" && ret); g_assert ("mpi returned is null" && mpt != NULL); g_assert ("mpi is wrong number" && gcry_mpi_cmp (mpi, mpt) == 0); g_bytes_unref (data); gcry_mpi_release (mpi); gcry_mpi_release (mpt); }
static char *test_flake() { struct gotr_user u[2]; gotr_gen_BD_keypair(&u[0].r[0], &u[0].z[0]); gotr_gen_BD_keypair(&u[0].r[1], &u[0].z[1]); u[1].y[0] = u[0].z[0]; u[1].y[1] = u[0].z[1]; gotr_gen_BD_keypair(&u[1].r[0], &u[1].z[0]); gotr_gen_BD_keypair(&u[1].r[1], &u[1].z[1]); u[0].y[0] = u[1].z[0]; u[0].y[1] = u[1].z[1]; mu_assert("ERROR: flake X0 failed", gotr_gen_BD_X_value(&u[0].R[0], u[0].y[1], u[0].z[1], u[0].r[0])); mu_assert("ERROR: flake X1 failed", gotr_gen_BD_X_value(&u[0].R[1], u[0].z[0], u[0].y[0], u[0].r[1])); mu_assert("ERROR: flake X2 failed", gotr_gen_BD_X_value(&u[1].R[0], u[1].y[1], u[1].z[1], u[1].r[0])); mu_assert("ERROR: flake X3 failed", gotr_gen_BD_X_value(&u[1].R[1], u[1].z[0], u[1].y[0], u[1].r[1])); u[1].V[0] = u[0].R[0]; u[1].V[1] = u[0].R[1]; u[0].V[0] = u[1].R[0]; u[0].V[1] = u[1].R[1]; mu_assert("ERROR: flake f0 failed", gotr_gen_BD_flake_key(&u[0].flake_key, u[0].y[0], u[0].r[1], u[0].R[0], u[0].R[1], u[0].V[1])); mu_assert("ERROR: flake f1 failed", gotr_gen_BD_flake_key(&u[1].flake_key, u[1].y[0], u[1].r[1], u[1].R[0], u[1].R[1], u[1].V[1])); /* u[0].next = u[1].next = NULL; if (!gotr_gen_BD_circle_key(u[0].flake_key, &u[0])) gotr_eprintf("c0 failed"); if (gcry_mpi_cmp(u[0].flake_key, u[1].flake_key)) gotr_eprintf("flake != c0"); gcry_mpi_dump(u[0].flake_key); gotr_eprintf(""); if (!gotr_gen_BD_circle_key(u[1].flake_key, &u[1])) gotr_eprintf("c1 failed"); if (gcry_mpi_cmp(u[1].flake_key, u[0].flake_key)) gotr_eprintf("flake != c1"); gcry_mpi_dump(u[1].flake_key); gotr_eprintf(""); gotr_eprintf("circle keys match");*/ mu_assert("ERROR: flake keys do not match", 0 == gcry_mpi_cmp(u[0].flake_key, u[1].flake_key)); return 0; }
cdk_error_t _cdk_pubkey_compare (cdk_pkt_pubkey_t a, cdk_pkt_pubkey_t b) { int na, nb, i; if (a->timestamp != b->timestamp || a->pubkey_algo != b->pubkey_algo) return -1; if (a->version < 4 && a->expiredate != b->expiredate) return -1; na = cdk_pk_get_npkey (a->pubkey_algo); nb = cdk_pk_get_npkey (b->pubkey_algo); if (na != nb) return -1; for (i = 0; i < na; i++) { if (gcry_mpi_cmp (a->mpi[i], b->mpi[i])) return -1; } return 0; }
/** * Generate a key pair with a key of size NBITS. * @param sk where to store the key * @param nbits the number of bits to use * @param hc the HC to use for PRNG (modified!) */ static void generate_kblock_key (KBlock_secret_key *sk, unsigned int nbits, struct GNUNET_HashCode * hc) { gcry_mpi_t t1, t2; gcry_mpi_t phi; /* helper: (p-1)(q-1) */ gcry_mpi_t g; gcry_mpi_t f; /* make sure that nbits is even so that we generate p, q of equal size */ if ((nbits & 1)) nbits++; sk->e = gcry_mpi_set_ui (NULL, 257); sk->n = gcry_mpi_new (0); sk->p = gcry_mpi_new (0); sk->q = gcry_mpi_new (0); sk->d = gcry_mpi_new (0); sk->u = gcry_mpi_new (0); t1 = gcry_mpi_new (0); t2 = gcry_mpi_new (0); phi = gcry_mpi_new (0); g = gcry_mpi_new (0); f = gcry_mpi_new (0); do { do { gcry_mpi_release (sk->p); gcry_mpi_release (sk->q); gen_prime (&sk->p, nbits / 2, hc); gen_prime (&sk->q, nbits / 2, hc); if (gcry_mpi_cmp (sk->p, sk->q) > 0) /* p shall be smaller than q (for calc of u) */ gcry_mpi_swap (sk->p, sk->q); /* calculate the modulus */ gcry_mpi_mul (sk->n, sk->p, sk->q); } while (gcry_mpi_get_nbits (sk->n) != nbits); /* calculate Euler totient: phi = (p-1)(q-1) */ gcry_mpi_sub_ui (t1, sk->p, 1); gcry_mpi_sub_ui (t2, sk->q, 1); gcry_mpi_mul (phi, t1, t2); gcry_mpi_gcd (g, t1, t2); gcry_mpi_div (f, NULL, phi, g, 0); while (0 == gcry_mpi_gcd (t1, sk->e, phi)) { /* (while gcd is not 1) */ gcry_mpi_add_ui (sk->e, sk->e, 2); } /* calculate the secret key d = e^1 mod phi */ } while ((0 == gcry_mpi_invm (sk->d, sk->e, f)) || (0 == gcry_mpi_invm (sk->u, sk->p, sk->q))); gcry_mpi_release (t1); gcry_mpi_release (t2); gcry_mpi_release (phi); gcry_mpi_release (f); gcry_mpi_release (g); }
/** * Return true if n is probably a prime */ static int is_prime (gcry_mpi_t n, int steps, struct GNUNET_HashCode * hc) { gcry_mpi_t x; gcry_mpi_t y; gcry_mpi_t z; gcry_mpi_t nminus1; gcry_mpi_t a2; gcry_mpi_t q; unsigned int i, j, k; int rc = 0; unsigned int nbits; x = gcry_mpi_new (0); y = gcry_mpi_new (0); z = gcry_mpi_new (0); nminus1 = gcry_mpi_new (0); a2 = gcry_mpi_set_ui (NULL, 2); nbits = gcry_mpi_get_nbits (n); gcry_mpi_sub_ui (nminus1, n, 1); /* Find q and k, so that n = 1 + 2^k * q . */ q = gcry_mpi_set (NULL, nminus1); k = mpz_trailing_zeroes (q); mpz_tdiv_q_2exp (q, q, k); for (i = 0; i < steps; i++) { if (!i) { gcry_mpi_set_ui (x, 2); } else { mpz_randomize (x, nbits - 1, hc); GNUNET_assert (gcry_mpi_cmp (x, nminus1) < 0); GNUNET_assert (gcry_mpi_cmp_ui (x, 1) > 0); } gcry_mpi_powm (y, x, q, n); if (gcry_mpi_cmp_ui (y, 1) && gcry_mpi_cmp (y, nminus1)) { for (j = 1; j < k && gcry_mpi_cmp (y, nminus1); j++) { gcry_mpi_powm (y, y, a2, n); if (!gcry_mpi_cmp_ui (y, 1)) goto leave; /* Not a prime. */ } if (gcry_mpi_cmp (y, nminus1)) goto leave; /* Not a prime. */ } } rc = 1; /* May be a prime. */ leave: gcry_mpi_release (x); gcry_mpi_release (y); gcry_mpi_release (z); gcry_mpi_release (nminus1); gcry_mpi_release (q); gcry_mpi_release (a2); return rc; }
/* * Generate a random number less than p * FIXME: takes ages ... */ void gen_rand(gcry_mpi_t r, gcry_mpi_t p) { do { gcry_mpi_randomize(r, gcry_mpi_get_nbits(p), GCRY_STRONG_RANDOM); gcry_mpi_clear_highbit(r, gcry_mpi_get_nbits(p) + 1); } while (gcry_mpi_cmp(p, r) < 0); }
/* Compute and print missing RSA parameters. */ static void compute_missing (gcry_mpi_t rsa_p, gcry_mpi_t rsa_q, gcry_mpi_t rsa_e) { gcry_mpi_t rsa_n, rsa_d, rsa_pm1, rsa_qm1, rsa_u; gcry_mpi_t phi, tmp_g, tmp_f; rsa_n = gcry_mpi_new (0); rsa_d = gcry_mpi_new (0); rsa_pm1 = gcry_mpi_new (0); rsa_qm1 = gcry_mpi_new (0); rsa_u = gcry_mpi_new (0); phi = gcry_mpi_new (0); tmp_f = gcry_mpi_new (0); tmp_g = gcry_mpi_new (0); /* Check that p < q; if not swap p and q. */ if (openpgp_mode && gcry_mpi_cmp (rsa_p, rsa_q) > 0) { fprintf (stderr, PGM ": swapping p and q\n"); gcry_mpi_swap (rsa_p, rsa_q); } gcry_mpi_mul (rsa_n, rsa_p, rsa_q); /* Compute the Euler totient: phi = (p-1)(q-1) */ gcry_mpi_sub_ui (rsa_pm1, rsa_p, 1); gcry_mpi_sub_ui (rsa_qm1, rsa_q, 1); gcry_mpi_mul (phi, rsa_pm1, rsa_qm1); if (!gcry_mpi_gcd (tmp_g, rsa_e, phi)) die ("parameter 'e' does match 'p' and 'q'\n"); /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */ gcry_mpi_gcd (tmp_g, rsa_pm1, rsa_qm1); gcry_mpi_div (tmp_f, NULL, phi, tmp_g, -1); /* Compute the secret key: d = e^{-1} mod lcm(p-1,q-1) */ gcry_mpi_invm (rsa_d, rsa_e, tmp_f); /* Compute the CRT helpers: d mod (p-1), d mod (q-1) */ gcry_mpi_mod (rsa_pm1, rsa_d, rsa_pm1); gcry_mpi_mod (rsa_qm1, rsa_d, rsa_qm1); /* Compute the CRT value: OpenPGP: u = p^{-1} mod q Standard: iqmp = q^{-1} mod p */ if (openpgp_mode) gcry_mpi_invm (rsa_u, rsa_p, rsa_q); else gcry_mpi_invm (rsa_u, rsa_q, rsa_p); gcry_mpi_release (phi); gcry_mpi_release (tmp_f); gcry_mpi_release (tmp_g); /* Print everything. */ print_mpi_line ("n", rsa_n); print_mpi_line ("e", rsa_e); if (openpgp_mode) print_mpi_line ("d", rsa_d); print_mpi_line ("p", rsa_p); print_mpi_line ("q", rsa_q); if (openpgp_mode) print_mpi_line ("u", rsa_u); else { print_mpi_line ("dmp1", rsa_pm1); print_mpi_line ("dmq1", rsa_qm1); print_mpi_line ("iqmp", rsa_u); } gcry_mpi_release (rsa_n); gcry_mpi_release (rsa_d); gcry_mpi_release (rsa_pm1); gcry_mpi_release (rsa_qm1); gcry_mpi_release (rsa_u); }
/* Check the math used with Twisted Edwards curves. */ static void twistededwards_math (void) { gpg_error_t err; gcry_ctx_t ctx; gcry_mpi_point_t G, Q; gcry_mpi_t k; gcry_mpi_t w, a, x, y, z, p, n, b, I; wherestr = "twistededwards_math"; show ("checking basic Twisted Edwards math\n"); err = gcry_mpi_ec_new (&ctx, NULL, "Ed25519"); if (err) die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err)); k = hex2mpi ("2D3501E723239632802454EE5DDC406EFB0BDF18486A5BDE9C0390A9C2984004" "F47252B628C953625B8DEB5DBCB8DA97AA43A1892D11FA83596F42E0D89CB1B6"); G = gcry_mpi_ec_get_point ("g", ctx, 1); if (!G) die ("gcry_mpi_ec_get_point(G) failed\n"); Q = gcry_mpi_point_new (0); w = gcry_mpi_new (0); a = gcry_mpi_new (0); x = gcry_mpi_new (0); y = gcry_mpi_new (0); z = gcry_mpi_new (0); I = gcry_mpi_new (0); p = gcry_mpi_ec_get_mpi ("p", ctx, 1); n = gcry_mpi_ec_get_mpi ("n", ctx, 1); b = gcry_mpi_ec_get_mpi ("b", ctx, 1); /* Check: 2^{p-1} mod p == 1 */ gcry_mpi_sub_ui (a, p, 1); gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, p); if (gcry_mpi_cmp_ui (w, 1)) fail ("failed assertion: 2^{p-1} mod p == 1\n"); /* Check: p % 4 == 1 */ gcry_mpi_mod (w, p, GCRYMPI_CONST_FOUR); if (gcry_mpi_cmp_ui (w, 1)) fail ("failed assertion: p % 4 == 1\n"); /* Check: 2^{n-1} mod n == 1 */ gcry_mpi_sub_ui (a, n, 1); gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, n); if (gcry_mpi_cmp_ui (w, 1)) fail ("failed assertion: 2^{n-1} mod n == 1\n"); /* Check: b^{(p-1)/2} mod p == p-1 */ gcry_mpi_sub_ui (a, p, 1); gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_TWO, -1); gcry_mpi_powm (w, b, x, p); gcry_mpi_abs (w); if (gcry_mpi_cmp (w, a)) fail ("failed assertion: b^{(p-1)/2} mod p == p-1\n"); /* I := 2^{(p-1)/4} mod p */ gcry_mpi_sub_ui (a, p, 1); gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_FOUR, -1); gcry_mpi_powm (I, GCRYMPI_CONST_TWO, x, p); /* Check: I^2 mod p == p-1 */ gcry_mpi_powm (w, I, GCRYMPI_CONST_TWO, p); if (gcry_mpi_cmp (w, a)) fail ("failed assertion: I^2 mod p == p-1\n"); /* Check: G is on the curve */ if (!gcry_mpi_ec_curve_point (G, ctx)) fail ("failed assertion: G is on the curve\n"); /* Check: nG == (0,1) */ gcry_mpi_ec_mul (Q, n, G, ctx); if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) fail ("failed to get affine coordinates\n"); if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 1)) fail ("failed assertion: nG == (0,1)\n"); /* Now two arbitrary point operations taken from the ed25519.py sample data. */ gcry_mpi_release (a); a = hex2mpi ("4f71d012df3c371af3ea4dc38385ca5bb7272f90cb1b008b3ed601c76de1d496" "e30cbf625f0a756a678d8f256d5325595cccc83466f36db18f0178eb9925edd3"); gcry_mpi_ec_mul (Q, a, G, ctx); if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) fail ("failed to get affine coordinates\n"); if (cmp_mpihex (x, ("157f7361c577aad36f67ed33e38dc7be" "00014fecc2165ca5cee9eee19fe4d2c1")) || cmp_mpihex (y, ("5a69dbeb232276b38f3f5016547bb2a2" "4025645f0b820e72b8cad4f0a909a092"))) { fail ("sample point multiply failed:\n"); print_mpi ("r", a); print_mpi ("Rx", x); print_mpi ("Ry", y); } gcry_mpi_release (a); a = hex2mpi ("2d3501e723239632802454ee5ddc406efb0bdf18486a5bde9c0390a9c2984004" "f47252b628c953625b8deb5dbcb8da97aa43a1892d11fa83596f42e0d89cb1b6"); gcry_mpi_ec_mul (Q, a, G, ctx); if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) fail ("failed to get affine coordinates\n"); if (cmp_mpihex (x, ("6218e309d40065fcc338b3127f468371" "82324bd01ce6f3cf81ab44e62959c82a")) || cmp_mpihex (y, ("5501492265e073d874d9e5b81e7f8784" "8a826e80cce2869072ac60c3004356e5"))) { fail ("sample point multiply failed:\n"); print_mpi ("r", a); print_mpi ("Rx", x); print_mpi ("Ry", y); } gcry_mpi_release (I); gcry_mpi_release (b); gcry_mpi_release (n); gcry_mpi_release (p); gcry_mpi_release (w); gcry_mpi_release (a); gcry_mpi_release (x); gcry_mpi_release (y); gcry_mpi_release (z); gcry_mpi_point_release (Q); gcry_mpi_point_release (G); gcry_mpi_release (k); gcry_ctx_release (ctx); }
/* What we test here is that we don't overwrite our args and that using thne same mpi for several args works. */ static int test_powm (void) { int b_int = 17; int e_int = 3; int m_int = 19; gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int); gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int); gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int); gcry_mpi_t res = gcry_mpi_new (0); gcry_mpi_powm (res, base, exp, mod); if (gcry_mpi_cmp_ui (base, b_int)) die ("test_powm failed for base at %d\n", __LINE__); if (gcry_mpi_cmp_ui (exp, e_int)) die ("test_powm_ui failed for exp at %d\n", __LINE__); if (gcry_mpi_cmp_ui (mod, m_int)) die ("test_powm failed for mod at %d\n", __LINE__); /* Check using base for the result. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_set_ui (exp, e_int); gcry_mpi_set_ui(mod, m_int); gcry_mpi_powm (base, base, exp, mod); if (gcry_mpi_cmp (res, base)) die ("test_powm failed at %d\n", __LINE__); if (gcry_mpi_cmp_ui (exp, e_int)) die ("test_powm_ui failed for exp at %d\n", __LINE__); if (gcry_mpi_cmp_ui (mod, m_int)) die ("test_powm failed for mod at %d\n", __LINE__); /* Check using exp for the result. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_set_ui (exp, e_int); gcry_mpi_set_ui(mod, m_int); gcry_mpi_powm (exp, base, exp, mod); if (gcry_mpi_cmp (res, exp)) die ("test_powm failed at %d\n", __LINE__); if (gcry_mpi_cmp_ui (base, b_int)) die ("test_powm failed for base at %d\n", __LINE__); if (gcry_mpi_cmp_ui (mod, m_int)) die ("test_powm failed for mod at %d\n", __LINE__); /* Check using mod for the result. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_set_ui (exp, e_int); gcry_mpi_set_ui(mod, m_int); gcry_mpi_powm (mod, base, exp, mod); if (gcry_mpi_cmp (res, mod)) die ("test_powm failed at %d\n", __LINE__); if (gcry_mpi_cmp_ui (base, b_int)) die ("test_powm failed for base at %d\n", __LINE__); if (gcry_mpi_cmp_ui (exp, e_int)) die ("test_powm_ui failed for exp at %d\n", __LINE__); /* Now check base ^ base mod mod. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_set_ui(mod, m_int); gcry_mpi_powm (res, base, base, mod); if (gcry_mpi_cmp_ui (base, b_int)) die ("test_powm failed for base at %d\n", __LINE__); if (gcry_mpi_cmp_ui (mod, m_int)) die ("test_powm failed for mod at %d\n", __LINE__); /* Check base ^ base mod mod with base as result. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_set_ui(mod, m_int); gcry_mpi_powm (base, base, base, mod); if (gcry_mpi_cmp (res, base)) die ("test_powm failed at %d\n", __LINE__); if (gcry_mpi_cmp_ui (mod, m_int)) die ("test_powm failed for mod at %d\n", __LINE__); /* Check base ^ base mod mod with mod as result. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_set_ui(mod, m_int); gcry_mpi_powm (mod, base, base, mod); if (gcry_mpi_cmp (res, mod)) die ("test_powm failed at %d\n", __LINE__); if (gcry_mpi_cmp_ui (base, b_int)) die ("test_powm failed for base at %d\n", __LINE__); /* Now check base ^ base mod base. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_powm (res, base, base, base); if (gcry_mpi_cmp_ui (base, b_int)) die ("test_powm failed for base at %d\n", __LINE__); /* Check base ^ base mod base with base as result. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_powm (base, base, base, base); if (gcry_mpi_cmp (res, base)) die ("test_powm failed at %d\n", __LINE__); /* Fixme: We should add the rest of the cases of course. */ return 1; }