Crypt-Bear
view release on metacpan or search on metacpan
src/rsa/rsa_i31_keygen_inner.c view on Meta::CPAN
* the size of p.
*/
static uint32_t
invert_pubexp(uint32_t *d, const uint32_t *m, uint32_t e, uint32_t *t)
{
uint32_t *f;
uint32_t r;
f = t;
t += 1 + ((m[0] + 31) >> 5);
/*
* Compute d = 1/e mod m. Since p = 3 mod 4, m is odd.
*/
br_i31_zero(d, m[0]);
d[1] = 1;
br_i31_zero(f, m[0]);
f[1] = e & 0x7FFFFFFF;
f[2] = e >> 31;
r = br_i31_moddiv(d, f, m, br_i31_ninv31(m[1]), t);
/*
* We really want d = 1/e mod p-1, with p = 2m. By the CRT,
* the result is either the d we got, or d + m.
*
* Let's write e*d = 1 + k*m, for some integer k. Integers e
* and m are odd. If d is odd, then e*d is odd, which implies
* that k must be even; in that case, e*d = 1 + (k/2)*2m, and
* thus d is already fine. Conversely, if d is even, then k
* is odd, and we must add m to d in order to get the correct
* result.
*/
br_i31_add(d, m, (uint32_t)(1 - (d[1] & 1)));
return r;
}
/*
* Swap two buffers in RAM. They must be disjoint.
*/
static void
bufswap(void *b1, void *b2, size_t len)
{
size_t u;
unsigned char *buf1, *buf2;
buf1 = b1;
buf2 = b2;
for (u = 0; u < len; u ++) {
unsigned w;
w = buf1[u];
buf1[u] = buf2[u];
buf2[u] = w;
}
}
/* see inner.h */
uint32_t
br_rsa_i31_keygen_inner(const br_prng_class **rng,
br_rsa_private_key *sk, void *kbuf_priv,
br_rsa_public_key *pk, void *kbuf_pub,
unsigned size, uint32_t pubexp, br_i31_modpow_opt_type mp31)
{
uint32_t esize_p, esize_q;
size_t plen, qlen, tlen;
uint32_t *p, *q, *t;
union {
uint32_t t32[TEMPS];
uint64_t t64[TEMPS >> 1]; /* for 64-bit alignment */
} tmp;
uint32_t r;
if (size < BR_MIN_RSA_SIZE || size > BR_MAX_RSA_SIZE) {
return 0;
}
if (pubexp == 0) {
pubexp = 3;
} else if (pubexp == 1 || (pubexp & 1) == 0) {
return 0;
}
esize_p = (size + 1) >> 1;
esize_q = size - esize_p;
sk->n_bitlen = size;
sk->p = kbuf_priv;
sk->plen = (esize_p + 7) >> 3;
sk->q = sk->p + sk->plen;
sk->qlen = (esize_q + 7) >> 3;
sk->dp = sk->q + sk->qlen;
sk->dplen = sk->plen;
sk->dq = sk->dp + sk->dplen;
sk->dqlen = sk->qlen;
sk->iq = sk->dq + sk->dqlen;
sk->iqlen = sk->plen;
if (pk != NULL) {
pk->n = kbuf_pub;
pk->nlen = (size + 7) >> 3;
pk->e = pk->n + pk->nlen;
pk->elen = 4;
br_enc32be(pk->e, pubexp);
while (*pk->e == 0) {
pk->e ++;
pk->elen --;
}
}
/*
* We now switch to encoded sizes.
*
* floor((x * 16913) / (2^19)) is equal to floor(x/31) for all
* integers x from 0 to 34966; the intermediate product fits on
* 30 bits, thus we can use MUL31().
*/
esize_p += MUL31(esize_p, 16913) >> 19;
esize_q += MUL31(esize_q, 16913) >> 19;
plen = (esize_p + 31) >> 5;
qlen = (esize_q + 31) >> 5;
p = tmp.t32;
q = p + 1 + plen;
( run in 0.592 second using v1.01-cache-2.11-cpan-5a3173703d6 )