int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz) { int ret = 0; mp_int x; mp_int y; mp_int z; if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY) return MP_INIT_E; if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY) ret = MP_READ_E; if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY) ret = MP_READ_E; if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY) ret = MP_EXPTMOD_E; if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY) ret = MP_TO_E; if (ret == 0) *agreeSz = mp_unsigned_bin_size(&z); mp_clear(&z); mp_clear(&y); mp_clear(&x); return ret; }
int main(int argc, char *argv[]) { mp_int a, b, m; mp_err res; char *str; int len, rval = 0; if(argc < 3) { fprintf(stderr, "Usage: %s <a> <b> <m>\n", argv[0]); return 1; } mp_init(&a); mp_init(&b); mp_init(&m); mp_read_radix(&a, argv[1], 10); mp_read_radix(&b, argv[2], 10); mp_read_radix(&m, argv[3], 10); if((res = mp_exptmod(&a, &b, &m, &a)) != MP_OKAY) { fprintf(stderr, "%s: error: %s\n", argv[0], mp_strerror(res)); rval = 1; } else { len = mp_radix_size(&a, 10); str = calloc(len, sizeof(char)); mp_toradix(&a, str, 10); printf("%s\n", str); free(str); } mp_clear(&a); mp_clear(&b); mp_clear(&m); return rval; }
static void gety(dropbear_dss_key *key) { if (mp_exptmod(key->g, key->x, key->p, key->y) != MP_OKAY) { fprintf(stderr, "DSS key generation failed\n"); exit(1); } }
/* ** An attack against RSA CRT was described by Boneh, DeMillo, and Lipton in: ** "On the Importance of Eliminating Errors in Cryptographic Computations", ** http://theory.stanford.edu/~dabo/papers/faults.ps.gz ** ** As a defense against the attack, carry out the private key operation, ** followed up with a public key operation to invert the result. ** Verify that result against the input. */ static SECStatus rsa_PrivateKeyOpCRTCheckedPubKey(RSAPrivateKey *key, mp_int *m, mp_int *c) { mp_int n, e, v; mp_err err = MP_OKAY; SECStatus rv = SECSuccess; MP_DIGITS(&n) = 0; MP_DIGITS(&e) = 0; MP_DIGITS(&v) = 0; CHECK_MPI_OK( mp_init(&n) ); CHECK_MPI_OK( mp_init(&e) ); CHECK_MPI_OK( mp_init(&v) ); CHECK_SEC_OK( rsa_PrivateKeyOpCRTNoCheck(key, m, c) ); SECITEM_TO_MPINT(key->modulus, &n); SECITEM_TO_MPINT(key->publicExponent, &e); /* Perform a public key operation v = m ** e mod n */ CHECK_MPI_OK( mp_exptmod(m, &e, &n, &v) ); if (mp_cmp(&v, c) != 0) { rv = SECFailure; } cleanup: mp_clear(&n); mp_clear(&e); mp_clear(&v); if (err) { MP_TO_SEC_ERROR(err); rv = SECFailure; } return rv; }
int wc_SrpGetVerifier(Srp* srp, byte* verifier, word32* size) { mp_int v; int r; if (!srp || !verifier || !size || srp->side != SRP_CLIENT_SIDE) return BAD_FUNC_ARG; if (mp_iszero(&srp->auth)) return SRP_CALL_ORDER_E; r = mp_init(&v); if (r != MP_OKAY) return MP_INIT_E; /* v = g ^ x % N */ if (!r) r = mp_exptmod(&srp->g, &srp->auth, &srp->N, &v); if (!r) r = *size < (word32)mp_unsigned_bin_size(&v) ? BUFFER_E : MP_OKAY; if (!r) r = mp_to_unsigned_bin(&v, verifier); if (!r) *size = mp_unsigned_bin_size(&v); mp_clear(&v); return r; }
/* performs one Fermat test. * * If "a" were prime then b**a == b (mod a) since the order of * the multiplicative sub-group would be phi(a) = a-1. That means * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). * * Sets result to 1 if the congruence holds, or zero otherwise. */ int mp_prime_fermat (mp_int * a, mp_int * b, int *result) { mp_int t; int err; /* default to composite */ *result = MP_NO; /* ensure b > 1 */ if (mp_cmp_d(b, 1) != MP_GT) { return MP_VAL; } /* init t */ if ((err = mp_init (&t)) != MP_OKAY) { return err; } /* compute t = b**a mod a */ if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { goto LBL_T; } /* is it equal to b? */ if (mp_cmp (&t, b) == MP_EQ) { *result = MP_YES; } err = MP_OKAY; LBL_T:mp_clear (&t); return err; }
static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz, byte* pub, word32* pubSz) { int ret = 0; mp_int x; mp_int y; if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY) return MP_INIT_E; if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY) ret = MP_READ_E; if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY) ret = MP_EXPTMOD_E; if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY) ret = MP_TO_E; if (ret == 0) *pubSz = mp_unsigned_bin_size(&y); mp_clear(&y); mp_clear(&x); return ret; }
int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa) { unsigned char *buf; int qsize, err; if (rng == NULL || dsa == NULL) return BAD_FUNC_ARG; qsize = mp_unsigned_bin_size(&dsa->q); if (qsize == 0) return BAD_FUNC_ARG; /* allocate ram */ buf = (unsigned char *)XMALLOC(qsize, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (buf == NULL) return MEMORY_E; if (mp_init(&dsa->x) != MP_OKAY) { XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MP_INIT_E; } do { /* make a random exponent mod q */ err = wc_RNG_GenerateBlock(rng, buf, qsize); if (err != MP_OKAY) { mp_clear(&dsa->x); XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); return err; } err = mp_read_unsigned_bin(&dsa->x, buf, qsize); if (err != MP_OKAY) { mp_clear(&dsa->x); XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); return err; } } while (mp_cmp_d(&dsa->x, 1) != MP_GT); XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (mp_init(&dsa->y) != MP_OKAY) { mp_clear(&dsa->x); return MP_INIT_E; } /* public key : y = g^x mod p */ err = mp_exptmod(&dsa->g, &dsa->x, &dsa->p, &dsa->y); if (err != MP_OKAY) { mp_clear(&dsa->x); mp_clear(&dsa->y); return err; } dsa->type = DSA_PRIVATE; return MP_OKAY; }
/* this is a shell function that calls either the normal or Montgomery * exptmod functions. Originally the call to the montgomery code was * embedded in the normal function but that wasted alot of stack space * for nothing (since 99% of the time the Montgomery code would be called) */ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) { int dr; /* modulus P must be positive */ if (P->sign == MP_NEG) { return MP_VAL; } /* if exponent X is negative we have to recurse */ if (X->sign == MP_NEG) { mp_int tmpG, tmpX; int err; /* first compute 1/G mod P */ if ((err = mp_init(&tmpG)) != MP_OKAY) { return err; } if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) { mp_clear(&tmpG); return err; } /* now get |X| */ if ((err = mp_init(&tmpX)) != MP_OKAY) { mp_clear(&tmpG); return err; } if ((err = mp_abs(X, &tmpX)) != MP_OKAY) { mp_clear_multi(&tmpG, &tmpX, NULL); return err; } /* and now compute (1/G)**|X| instead of G**X [X < 0] */ err = mp_exptmod(&tmpG, &tmpX, P, Y); mp_clear_multi(&tmpG, &tmpX, NULL); return err; } /* is it a DR modulus? */ dr = mp_dr_is_modulus(P); /* if not, is it a uDR modulus? */ if (dr == 0) { dr = mp_reduce_is_2k(P) << 1; } /* if the modulus is odd or dr != 0 use the fast method */ #ifndef NO_FAST_EXPTMOD if (mp_isodd (P) == 1 || dr != 0) { return mp_exptmod_fast (G, X, P, Y, dr); } else #endif { /* otherwise use the generic Barrett reduction technique */ return s_mp_exptmod (G, X, P, Y); } }
static int exptmod(void *a, void *b, void *c, void *d) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); LTC_ARGCHK(d != NULL); return mpi_to_ltc_error(mp_exptmod(a,b,c,d)); }
/** * bignum_exptmod - Modular exponentiation: d = a^b (mod c) * @a: Bignum from bignum_init(); base * @b: Bignum from bignum_init(); exponent * @c: Bignum from bignum_init(); modulus * @d: Bignum from bignum_init(); used to store the result of a^b (mod c) * Returns: 0 on success, -1 on failure */ int bignum_exptmod(const struct bignum *a, const struct bignum *b, const struct bignum *c, struct bignum *d) { if (mp_exptmod((mp_int *) a, (mp_int *) b, (mp_int *) c, (mp_int *) d) != MP_OKAY) { wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); return -1; } return 0; }
void EncryptDecrypt(mp_int *result, const mp_int *source, const mp_int *e, const mp_int *n) { //mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, // mp_int c); /* c = a^b (mod m) */ int res=mp_exptmod(source, e, n,result); }
static void blind(mp_int *in, mp_int *b, mp_int *e, mp_int *n) { mp_int t1; mp_init(&t1); /* in' = (in * b^e) mod n */ mp_exptmod(b, e, n, &t1); mp_mul(&t1, in, in); mp_mod(in, n, in); mp_clear(&t1); }
int main(int argc, char *argv[]) { instant_t start, finish; mp_int prime, gen, expt, res; unsigned int ix, diff; int num; srand(time(NULL)); if(argc < 2) { fprintf(stderr, "Usage: %s <num-tests>\n", argv[0]); return 1; } if((num = atoi(argv[1])) < 0) num = -num; if(num == 0) ++num; mp_init(&prime); mp_init(&gen); mp_init(&res); mp_read_radix(&prime, g_prime, 16); mp_read_radix(&gen, g_gen, 16); mp_init_size(&expt, USED(&prime) - 1); s_mp_pad(&expt, USED(&prime) - 1); printf("Testing %d modular exponentations ... \n", num); start = now(); for(ix = 0; ix < num; ix++) { mpp_random(&expt); mp_exptmod(&gen, &expt, &prime, &res); } finish = now(); diff = (finish.sec - start.sec) * 1000000; diff += finish.usec; diff -= start.usec; printf("%d operations took %u usec (%.3f sec)\n", num, diff, (double)diff / 1000000.0); printf("That is %.3f sec per operation.\n", ((double)diff / 1000000.0) / num); mp_clear(&expt); mp_clear(&res); mp_clear(&gen); mp_clear(&prime); return 0; }
mp_err mp_rsavp(mp_int *sig, mp_int *e, mp_int *modulus, mp_int *msg) { ARGCHK(sig != NULL && e != NULL && modulus != NULL && msg != NULL, MP_BADARG); if((mp_cmp_z(sig) < 0) || (mp_cmp(sig, modulus) >= 0)) { return MP_RANGE; } return mp_exptmod(sig, e, modulus, msg); } /* end mp_rsavp() */
mp_err mp_rsasp(mp_int *msg, mp_int *d, mp_int *modulus, mp_int *sig) { ARGCHK(msg != NULL && d != NULL && modulus != NULL && sig != NULL, MP_BADARG); if((mp_cmp_z(msg) < 0) || (mp_cmp(msg, modulus) >= 0)) { return MP_RANGE; } return mp_exptmod(msg, d, modulus, sig); } /* end mp_rsasp() */
mp_err mp_rsadp(mp_int *cipher, mp_int *d, mp_int *modulus, mp_int *msg) { ARGCHK(cipher != NULL && d != NULL && modulus != NULL && msg != NULL, MP_BADARG); /* Insure that ciphertext representative is in range of modulus */ if((mp_cmp_z(cipher) < 0) || (mp_cmp(cipher, modulus) >= 0)) { return MP_RANGE; } return mp_exptmod(cipher, d, modulus, msg); } /* end mp_rsadp() */
mp_err mp_rsaep(mp_int *msg, mp_int *e, mp_int *modulus, mp_int *cipher) { ARGCHK(msg != NULL && e != NULL && modulus != NULL && cipher != NULL, MP_BADARG); /* Insure that message representative is in range of modulus */ if((mp_cmp_z(msg) < 0) || (mp_cmp(msg, modulus) >= 0)) { return MP_RANGE; } return mp_exptmod(msg, e, modulus, cipher); } /* end mp_rsaep() */
int _dsa_verify_hash (mp_int *r, mp_int *s, mp_int *hash, mp_int *keyG, mp_int *keyP, mp_int *keyQ, mp_int *keyY) { mp_int w, v, u1, u2; int ret; MP_OP(mp_init_multi(&w, &v, &u1, &u2, NULL)); // neither r or s can be 0 or >q if (mp_iszero(r) == MP_YES || mp_iszero(s) == MP_YES || mp_cmp(r, keyQ) != MP_LT || mp_cmp(s, keyQ) != MP_LT) { ret = -1; goto error; } // w = 1/s mod q MP_OP(mp_invmod(s, keyQ, &w)); // u1 = m * w mod q MP_OP(mp_mulmod(hash, &w, keyQ, &u1)); // u2 = r*w mod q MP_OP(mp_mulmod(r, &w, keyQ, &u2)); // v = g^u1 * y^u2 mod p mod q MP_OP(mp_exptmod(keyG, &u1, keyP, &u1)); MP_OP(mp_exptmod(keyY, &u2, keyP, &u2)); MP_OP(mp_mulmod(&u1, &u2, keyP, &v)); MP_OP(mp_mod(&v, keyQ, &v)); // if r = v then we're set ret = 0; if (mp_cmp(r, &v) == MP_EQ) ret = 1; error: mp_clear_multi(&w, &v, &u1, &u2, NULL); return ret; }
/** Non-complex part (no primality testing) of the validation of DSA params (p, q, g) @param key The key to validate @param stat [out] Result of test, 1==valid, 0==invalid @return CRYPT_OK if successful */ int dsa_int_validate_pqg(dsa_key *key, int *stat) { void *tmp1, *tmp2; int err; LTC_ARGCHK(key != NULL); LTC_ARGCHK(stat != NULL); *stat = 0; /* check q-order */ if ( key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 || (unsigned long)key->qord >= mp_unsigned_bin_size(key->p) || (mp_unsigned_bin_size(key->p) - key->qord) >= LTC_MDSA_DELTA ) { return CRYPT_OK; } /* FIPS 186-4 chapter 4.1: 1 < g < p */ if (mp_cmp_d(key->g, 1) != LTC_MP_GT || mp_cmp(key->g, key->p) != LTC_MP_LT) { return CRYPT_OK; } if ((err = mp_init_multi(&tmp1, &tmp2, NULL)) != CRYPT_OK) { return err; } /* FIPS 186-4 chapter 4.1: q is a divisor of (p - 1) */ if ((err = mp_sub_d(key->p, 1, tmp1)) != CRYPT_OK) { goto error; } if ((err = mp_div(tmp1, key->q, tmp1, tmp2)) != CRYPT_OK) { goto error; } if (mp_iszero(tmp2) != LTC_MP_YES) { err = CRYPT_OK; goto error; } /* FIPS 186-4 chapter 4.1: g is a generator of a subgroup of order q in * the multiplicative group of GF(p) - so we make sure that g^q mod p = 1 */ if ((err = mp_exptmod(key->g, key->q, key->p, tmp1)) != CRYPT_OK) { goto error; } if (mp_cmp_d(tmp1, 1) != LTC_MP_EQ) { err = CRYPT_OK; goto error; } err = CRYPT_OK; *stat = 1; error: mp_clear_multi(tmp2, tmp1, NULL); return err; }
/** Create a DSA key (with given params) @param prng An active PRNG state @param wprng The index of the PRNG desired @param group_size Size of the multiplicative group (octets) @param modulus_size Size of the modulus (octets) @param key [out] Where to store the created key @param p_hex Hexadecimal string 'p' @param q_hex Hexadecimal string 'q' @param g_hex Hexadecimal string 'g' @return CRYPT_OK if successful, upon error this function will free all allocated memory */ static int dsa_make_key_ex(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key, char* p_hex, char* q_hex, char* g_hex) { int err, qbits; LTC_ARGCHK(key != NULL); /* init mp_ints */ if ((err = mp_init_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) { return err; } if (p_hex == NULL || q_hex == NULL || g_hex == NULL) { /* generate params */ err = dsa_make_params(prng, wprng, group_size, modulus_size, key->p, key->q, key->g); if (err != CRYPT_OK) { goto cleanup; } } else { /* read params */ if ((err = mp_read_radix(key->p, p_hex, 16)) != CRYPT_OK) { goto cleanup; } if ((err = mp_read_radix(key->q, q_hex, 16)) != CRYPT_OK) { goto cleanup; } if ((err = mp_read_radix(key->g, g_hex, 16)) != CRYPT_OK) { goto cleanup; } /* XXX-TODO maybe do some validity check for p, q, g */ } /* so now we have our DH structure, generator g, order q, modulus p Now we need a random exponent [mod q] and it's power g^x mod p */ qbits = mp_count_bits(key->q); do { if ((err = rand_bn_bits(key->x, qbits, prng, wprng)) != CRYPT_OK) { goto cleanup; } /* private key x should be from range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2) */ } while (mp_cmp_d(key->x, 0) != LTC_MP_GT || mp_cmp(key->x, key->q) != LTC_MP_LT); if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { goto cleanup; } key->type = PK_PRIVATE; key->qord = group_size; return CRYPT_OK; cleanup: mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL); return err; }
/* ** RSA Private key operation (no CRT). */ static SECStatus rsa_PrivateKeyOpNoCRT(RSAPrivateKey *key, mp_int *m, mp_int *c, mp_int *n, unsigned int modLen) { mp_int d; mp_err err = MP_OKAY; SECStatus rv = SECSuccess; MP_DIGITS(&d) = 0; CHECK_MPI_OK( mp_init(&d) ); SECITEM_TO_MPINT(key->privateExponent, &d); /* 1. m = c**d mod n */ CHECK_MPI_OK( mp_exptmod(c, &d, n, m) ); cleanup: mp_clear(&d); if (err) { MP_TO_SEC_ERROR(err); rv = SECFailure; } return rv; }
unsigned char *cli_decodesig(const char *sig, unsigned int plen, mp_int e, mp_int n) { int i, slen = strlen(sig), dec; unsigned char *plain; mp_int r, p, c; mp_init(&r); mp_init(&c); for(i = 0; i < slen; i++) { if((dec = cli_ndecode(sig[i])) < 0) { mp_clear(&r); mp_clear(&c); return NULL; } mp_set_int(&r, dec); mp_mul_2d(&r, 6 * i, &r); mp_add(&r, &c, &c); } plain = (unsigned char *) cli_calloc(plen + 1, sizeof(unsigned char)); if(!plain) { cli_errmsg("cli_decodesig: Can't allocate memory for 'plain'\n"); mp_clear(&r); mp_clear(&c); return NULL; } mp_init(&p); mp_exptmod(&c, &e, &n, &p); /* plain = cipher^e mod n */ mp_clear(&c); mp_set_int(&c, 256); for(i = plen - 1; i >= 0; i--) { /* reverse */ mp_div(&p, &c, &p, &r); plain[i] = mp_get_int(&r); } mp_clear(&c); mp_clear(&p); mp_clear(&r); return plain; }
static int _prime_test(void) { void *p, *g, *tmp; int x, err, primality; if ((err = mp_init_multi(&p, &g, &tmp, NULL)) != CRYPT_OK) { goto error; } for (x = 0; ltc_dh_sets[x].size != 0; x++) { if ((err = mp_read_radix(g, ltc_dh_sets[x].base, 16)) != CRYPT_OK) { goto error; } if ((err = mp_read_radix(p, ltc_dh_sets[x].prime, 16)) != CRYPT_OK) { goto error; } /* ensure p is prime */ if ((err = mp_prime_is_prime(p, 8, &primality)) != CRYPT_OK) { goto done; } if (primality != LTC_MP_YES ) { err = CRYPT_FAIL_TESTVECTOR; goto done; } if ((err = mp_sub_d(p, 1, tmp)) != CRYPT_OK) { goto error; } if ((err = mp_div_2(tmp, tmp)) != CRYPT_OK) { goto error; } /* ensure (p-1)/2 is prime */ if ((err = mp_prime_is_prime(tmp, 8, &primality)) != CRYPT_OK) { goto done; } if (primality == 0) { err = CRYPT_FAIL_TESTVECTOR; goto done; } /* now see if g^((p-1)/2) mod p is in fact 1 */ if ((err = mp_exptmod(g, tmp, p, tmp)) != CRYPT_OK) { goto error; } if (mp_cmp_d(tmp, 1)) { err = CRYPT_FAIL_TESTVECTOR; goto done; } } err = CRYPT_OK; error: done: mp_clear_multi(tmp, g, p, NULL); return err; }
static SECStatus generate_blinding_params(struct RSABlindingParamsStr *rsabp, RSAPrivateKey *key, mp_int *n, unsigned int modLen) { SECStatus rv = SECSuccess; mp_int e, k; mp_err err = MP_OKAY; unsigned char *kb = NULL; MP_DIGITS(&e) = 0; MP_DIGITS(&k) = 0; CHECK_MPI_OK( mp_init(&e) ); CHECK_MPI_OK( mp_init(&k) ); SECITEM_TO_MPINT(key->publicExponent, &e); /* generate random k < n */ kb = PORT_Alloc(modLen); if (!kb) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto cleanup; } CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(kb, modLen) ); CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, modLen) ); /* k < n */ CHECK_MPI_OK( mp_mod(&k, n, &k) ); /* f = k**e mod n */ CHECK_MPI_OK( mp_exptmod(&k, &e, n, &rsabp->f) ); /* g = k**-1 mod n */ CHECK_MPI_OK( mp_invmod(&k, n, &rsabp->g) ); /* Initialize the counter for this (f, g) */ rsabp->counter = RSA_BLINDING_PARAMS_MAX_REUSE; cleanup: if (kb) PORT_ZFree(kb, modLen); mp_clear(&k); mp_clear(&e); if (err) { MP_TO_SEC_ERROR(err); rv = SECFailure; } return rv; }
static int ltm_dh_compute_key(unsigned char *shared, const BIGNUM * pub, DH *dh) { mp_int s, priv_key, p, peer_pub; int ret; if (dh->pub_key == NULL || dh->g == NULL || dh->priv_key == NULL) return -1; mp_init_multi(&s, &priv_key, &p, &peer_pub, NULL); BN2mpz(&p, dh->p); BN2mpz(&peer_pub, pub); /* check if peers pubkey is reasonable */ if (mp_isneg(&peer_pub) || mp_cmp(&peer_pub, &p) >= 0 || mp_cmp_d(&peer_pub, 1) <= 0) { ret = -1; goto out; } BN2mpz(&priv_key, dh->priv_key); ret = mp_exptmod(&peer_pub, &priv_key, &p, &s); if (ret != 0) { ret = -1; goto out; } ret = mp_unsigned_bin_size(&s); mp_to_unsigned_bin(&s, shared); out: mp_clear_multi(&s, &priv_key, &p, &peer_pub, NULL); return ret; }
static SECStatus generate_blinding_params(RSAPrivateKey *key, mp_int* f, mp_int* g, mp_int *n, unsigned int modLen) { SECStatus rv = SECSuccess; mp_int e, k; mp_err err = MP_OKAY; unsigned char *kb = NULL; MP_DIGITS(&e) = 0; MP_DIGITS(&k) = 0; CHECK_MPI_OK( mp_init(&e) ); CHECK_MPI_OK( mp_init(&k) ); SECITEM_TO_MPINT(key->publicExponent, &e); /* generate random k < n */ kb = PORT_Alloc(modLen); if (!kb) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto cleanup; } CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(kb, modLen) ); CHECK_MPI_OK( mp_read_unsigned_octets(&k, kb, modLen) ); /* k < n */ CHECK_MPI_OK( mp_mod(&k, n, &k) ); /* f = k**e mod n */ CHECK_MPI_OK( mp_exptmod(&k, &e, n, f) ); /* g = k**-1 mod n */ CHECK_MPI_OK( mp_invmod(&k, n, g) ); cleanup: if (kb) PORT_ZFree(kb, modLen); mp_clear(&k); mp_clear(&e); if (err) { MP_TO_SEC_ERROR(err); rv = SECFailure; } return rv; }
/** Create a DSA shared secret between two keys @param private_key The private DSA key (the exponent) @param base The base of the exponentiation (allows this to be used for both encrypt and decrypt) @param public_key The public key @param out [out] Destination of the shared secret @param outlen [in/out] The max size and resulting size of the shared secret @return CRYPT_OK if successful */ int dsa_shared_secret(void *private_key, void *base, dsa_key *public_key, unsigned char *out, unsigned long *outlen) { unsigned long x; void *res; int err; LTC_ARGCHK(private_key != NULL); LTC_ARGCHK(public_key != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* make new point */ if ((err = mp_init(&res)) != CRYPT_OK) { return err; } if ((err = mp_exptmod(base, private_key, public_key->p, res)) != CRYPT_OK) { mp_clear(res); return err; } x = (unsigned long)mp_unsigned_bin_size(res); if (*outlen < x) { *outlen = x; err = CRYPT_BUFFER_OVERFLOW; goto done; } zeromem(out, x); if ((err = mp_to_unsigned_bin(res, out + (x - mp_unsigned_bin_size(res)))) != CRYPT_OK) { goto done; } err = CRYPT_OK; *outlen = x; done: mp_clear(res); return err; }
static void getg(dss_key * key) { DEF_MP_INT(div); DEF_MP_INT(h); DEF_MP_INT(val); m_mp_init_multi(&div, &h, &val, NULL); /* get div=(p-1)/q */ if (mp_sub_d(key->p, 1, &val) != MP_OKAY) { fprintf(stderr, "dss key generation failed\n"); exit(1); } if (mp_div(&val, key->q, &div, NULL) != MP_OKAY) { fprintf(stderr, "dss key generation failed\n"); exit(1); } /* initialise h=1 */ mp_set(&h, 1); do { /* now keep going with g=h^div mod p, until g > 1 */ if (mp_exptmod(&h, &div, key->p, key->g) != MP_OKAY) { fprintf(stderr, "dss key generation failed\n"); exit(1); } if (mp_add_d(&h, 1, &h) != MP_OKAY) { fprintf(stderr, "dss key generation failed\n"); exit(1); } } while (mp_cmp_d(key->g, 1) != MP_GT); mp_clear_multi(&div, &h, &val, NULL); }
PRBool KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime) { mp_int p, q, y, r; mp_err err; int cmp = 1; /* default is false */ if (!Y || !prime || !subPrime) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } MP_DIGITS(&p) = 0; MP_DIGITS(&q) = 0; MP_DIGITS(&y) = 0; MP_DIGITS(&r) = 0; CHECK_MPI_OK( mp_init(&p) ); CHECK_MPI_OK( mp_init(&q) ); CHECK_MPI_OK( mp_init(&y) ); CHECK_MPI_OK( mp_init(&r) ); SECITEM_TO_MPINT(*prime, &p); SECITEM_TO_MPINT(*subPrime, &q); SECITEM_TO_MPINT(*Y, &y); /* compute r = y**q mod p */ CHECK_MPI_OK( mp_exptmod(&y, &q, &p, &r) ); /* compare to 1 */ cmp = mp_cmp_d(&r, 1); cleanup: mp_clear(&p); mp_clear(&q); mp_clear(&y); mp_clear(&r); if (err) { MP_TO_SEC_ERROR(err); return PR_FALSE; } return (cmp == 0) ? PR_TRUE : PR_FALSE; }