void fips186_gen::gen_q (bigint *q) { bigint u1, u2; char digest[HASHSIZE]; do { sha1_hash (digest, seed, seedsize << 3); // seedsize * 8 mpz_set_rawmag_le (&u1, digest, HASHSIZE); seed[3]++; sha1_hash (digest, seed, seedsize << 3); // seedsize * 8 mpz_set_rawmag_le (&u2, digest, HASHSIZE); mpz_xor (q, &u1, &u2); mpz_setbit (q, (HASHSIZE << 3) - 1); // set high bit mpz_setbit (q, 0); // set low bit } while (!q->probab_prime (5)); }
int pre_encrypt (MP_INT *out, const char *msg, size_t nbits) { size_t msglen = strlen (msg); char msbmask; size_t msgzlen, padsize, reslen; char *res; char *mp, *hp, *h; size_t i; if (msglen + enc_minz + enc_pad > nbits / 8) { mpz_set_ui (out, 0); return -1; } msbmask = 0xff >> (-nbits & 7); padsize = enc_pad + !!(nbits & 7); msgzlen = (nbits / 8) - enc_pad; reslen = padsize + msgzlen; res = malloc (reslen); h = malloc (padsize); if (!res || !h) { free (res); free (h); mpz_set_ui (out, 0); return -1; } mp = res; hp = mp + msgzlen; prng_getbytes (hp, padsize); hp[padsize-1] &= msbmask; sha1oracle_lookup (enc_gidx, mp, msgzlen, hp, padsize); for (i = 0; i < msglen; i++) mp[i] ^= msg[i]; sha1oracle_lookup (enc_hidx, h, padsize, mp, msgzlen); for (i = 0; i < padsize; i++) hp[i] ^= h[i]; hp[padsize-1] &= msbmask; mpz_set_rawmag_le (out, res, reslen); bzero (res, reslen); free (res); bzero (h, padsize); free (h); return 0; }
bool fips186_gen::gen_p (bigint *p, const bigint &q, u_int iter) { bigint X, c; for (u_int i = 0; i < num_p_candidates; i++) { for (u_int off = 0; off < raw_psize; off += HASHSIZE) { seed[0]++; sha1_hash (raw_p + off, seed, seedsize << 3); // seedsize * 8 } mpz_set_rawmag_le (&X, raw_p, pbytes); mpz_setbit (&X, pbits - 1); c = X; c = mod (c, q * 2); *p = (X - c + 1); if (p->probab_prime (iter)) return true; } return false; }
int pre_sign (MP_INT *out, sha1_ctx *sc, size_t nbits) { const size_t mlen = (nbits + 7) / 8; const size_t padsize = mlen - sha1_hashsize; char r[sig_rndbytes]; char *mp, *hp; int i; mp = malloc (mlen); if (!mp || nbits/8 < sig_minpad + sig_rndbytes + sha1_hashsize) { u_char garbage[sha1_hashsize]; free (mp); sha1_final (sc, garbage); mpz_set_ui (out, 0); return -1; } prng_getbytes (r, sig_rndbytes); sha1_update (sc, r, sig_rndbytes); sha1_final (sc, (u_char *) mp); hp = mp + sha1_hashsize; sha1oracle_lookup (sig_gidx, hp, padsize, mp, sha1_hashsize); hp[padsize-1] &= 0xff >> (-nbits & 7); for (i = 0; i < sig_rndbytes; i++) hp[i] ^= r[i]; mpz_set_rawmag_le (out, mp, mlen); bzero (mp, mlen); free (mp); return 0; }