示例#1
0
int RSAKey::Generate( int bits )
{
	Bignum pm1, qm1, phi_n;

	/*
	 * We don't generate e; we just use a standard one always.
	 */
	this->exponent = bignum_from_long(RSA_EXPONENT);

	/*
	 * Generate p and q: primes with combined length `bits', not
	 * congruent to 1 modulo e. (Strictly speaking, we wanted (p-1)
	 * and e to be coprime, and (q-1) and e to be coprime, but in
	 * general that's slightly more fiddly to arrange. By choosing
	 * a prime e, we can simplify the criterion.)
	 */
	this->p = primegen(bits / 2, RSA_EXPONENT, 1, NULL, 1);
	this->q = primegen(bits - bits / 2, RSA_EXPONENT, 1, NULL, 2);

	/*
	 * Ensure p > q, by swapping them if not.
	 */
	if (bignum_cmp(this->p, this->q) < 0)
		swap( p, q );

	/*
	 * Now we have p, q and e. All we need to do now is work out
	 * the other helpful quantities: n=pq, d=e^-1 mod (p-1)(q-1),
	 * and (q^-1 mod p).
	 */
	this->modulus = bigmul(this->p, this->q);
	pm1 = copybn(this->p);
	decbn(pm1);
	qm1 = copybn(this->q);
	decbn(qm1);
	phi_n = bigmul(pm1, qm1);
	freebn(pm1);
	freebn(qm1);
	this->private_exponent = modinv(this->exponent, phi_n);
	this->iqmp = modinv(this->q, this->p);

	/*
	 * Clean up temporary numbers.
	 */
	freebn(phi_n);

	return 1;
}
示例#2
0
/*
 * Verify that the public data in an RSA key matches the private
 * data. We also check the private data itself: we ensure that p >
 * q and that iqmp really is the inverse of q mod p.
 */
int rsa_verify(struct RSAKey *key)
{
    Bignum n, ed, pm1, qm1;
    int cmp;

    /* n must equal pq. */
    n = bigmul(key->p, key->q);
    cmp = bignum_cmp(n, key->modulus);
    freebn(n);
    if (cmp != 0)
	return 0;

    /* e * d must be congruent to 1, modulo (p-1) and modulo (q-1). */
    pm1 = copybn(key->p);
    decbn(pm1);
    ed = modmul(key->exponent, key->private_exponent, pm1);
    cmp = bignum_cmp(ed, One);
    sfree(ed);
    if (cmp != 0)
	return 0;

    qm1 = copybn(key->q);
    decbn(qm1);
    ed = modmul(key->exponent, key->private_exponent, qm1);
    cmp = bignum_cmp(ed, One);
    sfree(ed);
    if (cmp != 0)
	return 0;

    /*
     * Ensure p > q.
     */
    if (bignum_cmp(key->p, key->q) <= 0)
	return 0;

    /*
     * Ensure iqmp * q is congruent to 1, modulo p.
     */
    n = modmul(key->iqmp, key->q, key->p);
    cmp = bignum_cmp(n, One);
    sfree(n);
    if (cmp != 0)
	return 0;

    return 1;
}
示例#3
0
/*
 * Verify that the public data in an RSA key matches the private
 * data. We also check the private data itself: we ensure that p >
 * q and that iqmp really is the inverse of q mod p.
 */
bool RSAKey::Check() const
{
	Bignum n, ed, pm1, qm1;
	int cmp;

	/* n must equal pq. */
	n = bigmul(this->p, this->q);
	cmp = bignum_cmp(n, this->modulus);
	freebn(n);
	if (cmp != 0)
		return 0;

	/* e * d must be congruent to 1, modulo (p-1) and modulo (q-1). */
	pm1 = copybn(this->p);
	decbn(pm1);
	ed = modmul(this->exponent, this->private_exponent, pm1);
	cmp = bignum_cmp(ed, One);
	delete [] ed;
	if (cmp != 0)
		return 0;

	qm1 = copybn(this->q);
	decbn(qm1);
	ed = modmul(this->exponent, this->private_exponent, qm1);
	cmp = bignum_cmp(ed, One);
	delete [] ed;
	if (cmp != 0)
		return 0;

	/*
	 * Ensure p > q.
	 */
	if (bignum_cmp(this->p, this->q) <= 0)
		return 0;

	/*
	 * Ensure iqmp * q is congruent to 1, modulo p.
	 */
	n = modmul(this->iqmp, this->q, this->p);
	cmp = bignum_cmp(n, One);
	delete [] n;
	if (cmp != 0)
		return 0;

	return 1;
}
示例#4
0
int dsa_generate(struct dss_key *key, int bits, progfn_t pfn,
		 void *pfnparam)
{
    Bignum qm1, power, g, h, tmp;
    unsigned pfirst, qfirst;
    int progress;

    /*
     * Set up the phase limits for the progress report. We do this
     * by passing minus the phase number.
     *
     * For prime generation: our initial filter finds things
     * coprime to everything below 2^16. Computing the product of
     * (p-1)/p for all prime p below 2^16 gives about 20.33; so
     * among B-bit integers, one in every 20.33 will get through
     * the initial filter to be a candidate prime.
     *
     * Meanwhile, we are searching for primes in the region of 2^B;
     * since pi(x) ~ x/log(x), when x is in the region of 2^B, the
     * prime density will be d/dx pi(x) ~ 1/log(B), i.e. about
     * 1/0.6931B. So the chance of any given candidate being prime
     * is 20.33/0.6931B, which is roughly 29.34 divided by B.
     *
     * So now we have this probability P, we're looking at an
     * exponential distribution with parameter P: we will manage in
     * one attempt with probability P, in two with probability
     * P(1-P), in three with probability P(1-P)^2, etc. The
     * probability that we have still not managed to find a prime
     * after N attempts is (1-P)^N.
     * 
     * We therefore inform the progress indicator of the number B
     * (29.34/B), so that it knows how much to increment by each
     * time. We do this in 16-bit fixed point, so 29.34 becomes
     * 0x1D.57C4.
     */
    pfn(pfnparam, PROGFN_PHASE_EXTENT, 1, 0x2800);
    pfn(pfnparam, PROGFN_EXP_PHASE, 1, -0x1D57C4 / 160);
    pfn(pfnparam, PROGFN_PHASE_EXTENT, 2, 0x40 * bits);
    pfn(pfnparam, PROGFN_EXP_PHASE, 2, -0x1D57C4 / bits);

    /*
     * In phase three we are finding an order-q element of the
     * multiplicative group of p, by finding an element whose order
     * is _divisible_ by q and raising it to the power of (p-1)/q.
     * _Most_ elements will have order divisible by q, since for a
     * start phi(p) of them will be primitive roots. So
     * realistically we don't need to set this much below 1 (64K).
     * Still, we'll set it to 1/2 (32K) to be on the safe side.
     */
    pfn(pfnparam, PROGFN_PHASE_EXTENT, 3, 0x2000);
    pfn(pfnparam, PROGFN_EXP_PHASE, 3, -32768);

    /*
     * In phase four we are finding an element x between 1 and q-1
     * (exclusive), by inventing 160 random bits and hoping they
     * come out to a plausible number; so assuming q is uniformly
     * distributed between 2^159 and 2^160, the chance of any given
     * attempt succeeding is somewhere between 0.5 and 1. Lacking
     * the energy to arrange to be able to specify this probability
     * _after_ generating q, we'll just set it to 0.75.
     */
    pfn(pfnparam, PROGFN_PHASE_EXTENT, 4, 0x2000);
    pfn(pfnparam, PROGFN_EXP_PHASE, 4, -49152);

    pfn(pfnparam, PROGFN_READY, 0, 0);

    invent_firstbits(&pfirst, &qfirst);
    /*
     * Generate q: a prime of length 160.
     */
    key->q = primegen(160, 2, 2, NULL, 1, pfn, pfnparam, qfirst);
    /*
     * Now generate p: a prime of length `bits', such that p-1 is
     * divisible by q.
     */
    key->p = primegen(bits-160, 2, 2, key->q, 2, pfn, pfnparam, pfirst);

    /*
     * Next we need g. Raise 2 to the power (p-1)/q modulo p, and
     * if that comes out to one then try 3, then 4 and so on. As
     * soon as we hit a non-unit (and non-zero!) one, that'll do
     * for g.
     */
    power = bigdiv(key->p, key->q);    /* this is floor(p/q) == (p-1)/q */
    h = bignum_from_long(1);
    progress = 0;
    while (1) {
	pfn(pfnparam, PROGFN_PROGRESS, 3, ++progress);
	g = modpow(h, power, key->p);
	if (bignum_cmp(g, One) > 0)
	    break;		       /* got one */
	tmp = h;
	h = bignum_add_long(h, 1);
	freebn(tmp);
    }
    key->g = g;
    freebn(h);

    /*
     * Now we're nearly done. All we need now is our private key x,
     * which should be a number between 1 and q-1 exclusive, and
     * our public key y = g^x mod p.
     */
    qm1 = copybn(key->q);
    decbn(qm1);
    progress = 0;
    while (1) {
	int i, v, byte, bitsleft;
	Bignum x;

	pfn(pfnparam, PROGFN_PROGRESS, 4, ++progress);
	x = bn_power_2(159);
	byte = 0;
	bitsleft = 0;

	for (i = 0; i < 160; i++) {
	    if (bitsleft <= 0)
		bitsleft = 8, byte = random_byte();
	    v = byte & 1;
	    byte >>= 1;
	    bitsleft--;
	    bignum_set_bit(x, i, v);
	}

	if (bignum_cmp(x, One) <= 0 || bignum_cmp(x, qm1) >= 0) {
	    freebn(x);
	    continue;
	} else {
	    key->x = x;
	    break;
	}
    }
    freebn(qm1);

    key->y = modpow(key->g, key->x, key->p);

    return 1;
}
示例#5
0
文件: sshprime.c 项目: rdebath/sgt
/*
 * Generate a prime. We arrange to select a prime with the property
 * (prime % modulus) != residue (to speed up use in RSA).
 */
Bignum primegen(int bits, int modulus, int residue,
                int phase, progfn_t pfn, void *pfnparam) {
    int i, k, v, byte, bitsleft, check, checks;
    unsigned long delta, moduli[NPRIMES+1], residues[NPRIMES+1];
    Bignum p, pm1, q, wqp, wqp2;
    int progress = 0;

    byte = 0; bitsleft = 0;

    STARTOVER:

    pfn(pfnparam, phase, ++progress);

    /*
     * Generate a k-bit random number with top and bottom bits set.
     */
    p = newbn((bits+15)/16);
    for (i = 0; i < bits; i++) {
        if (i == 0 || i == bits-1)
            v = 1;
        else {
            if (bitsleft <= 0)
                bitsleft = 8; byte = random_byte();
            v = byte & 1;
            byte >>= 1;
            bitsleft--;
        }
        bignum_set_bit(p, i, v);
    }

    /*
     * Ensure this random number is coprime to the first few
     * primes, by repeatedly adding 2 to it until it is.
     */
    for (i = 0; i < NPRIMES; i++) {
        moduli[i] = primes[i];
        residues[i] = bignum_mod_short(p, primes[i]);
    }
    moduli[NPRIMES] = modulus;
    residues[NPRIMES] = (bignum_mod_short(p, (unsigned short)modulus)
                         + modulus - residue);
    delta = 0;
    while (1) {
        for (i = 0; i < (sizeof(moduli) / sizeof(*moduli)); i++)
            if (!((residues[i] + delta) % moduli[i]))
                break;
        if (i < (sizeof(moduli) / sizeof(*moduli))) {/* we broke */
            delta += 2;
            if (delta < 2) {
                freebn(p);
                goto STARTOVER;
            }
            continue;
        }
        break;
    }
    q = p;
    p = bignum_add_long(q, delta);
    freebn(q);

    /*
     * Now apply the Miller-Rabin primality test a few times. First
     * work out how many checks are needed.
     */
    checks = 27;
    if (bits >= 150) checks = 18;
    if (bits >= 200) checks = 15;
    if (bits >= 250) checks = 12;
    if (bits >= 300) checks = 9;
    if (bits >= 350) checks = 8;
    if (bits >= 400) checks = 7;
    if (bits >= 450) checks = 6;
    if (bits >= 550) checks = 5;
    if (bits >= 650) checks = 4;
    if (bits >= 850) checks = 3;
    if (bits >= 1300) checks = 2;

    /*
     * Next, write p-1 as q*2^k.
     */
    for (k = 0; bignum_bit(p, k) == !k; k++);   /* find first 1 bit in p-1 */
    q = bignum_rshift(p, k);
    /* And store p-1 itself, which we'll need. */
    pm1 = copybn(p);
    decbn(pm1);

    /*
     * Now, for each check ...
     */
    for (check = 0; check < checks; check++) {
        Bignum w;

        /*
         * Invent a random number between 1 and p-1 inclusive.
         */
        while (1) {
            w = newbn((bits+15)/16);
            for (i = 0; i < bits; i++) {
                if (bitsleft <= 0)
                    bitsleft = 8; byte = random_byte();
                v = byte & 1;
                byte >>= 1;
                bitsleft--;
                bignum_set_bit(w, i, v);
            }
            if (bignum_cmp(w, p) >= 0 || bignum_cmp(w, Zero) == 0) {
                freebn(w);
                continue;
            }
            break;
        }

        pfn(pfnparam, phase, ++progress);

        /*
         * Compute w^q mod p.
         */
        wqp = modpow(w, q, p);
        freebn(w);

        /*
         * See if this is 1, or if it is -1, or if it becomes -1
         * when squared at most k-1 times.
         */
        if (bignum_cmp(wqp, One) == 0 || bignum_cmp(wqp, pm1) == 0) {
            freebn(wqp);
            continue;
        }
        for (i = 0; i < k-1; i++) {
            wqp2 = modmul(wqp, wqp, p);
            freebn(wqp);
            wqp = wqp2;
            if (bignum_cmp(wqp, pm1) == 0)
                break;
        }
        if (i < k-1) {
            freebn(wqp);
            continue;
        }

        /*
         * It didn't. Therefore, w is a witness for the
         * compositeness of p.
         */
        freebn(p);
        freebn(pm1);
        freebn(q);
        goto STARTOVER;
    }

    /*
     * We have a prime!
     */
    freebn(q);
    freebn(pm1);
    return p;
}
示例#6
0
文件: sshrsag.c 项目: rdebath/sgt
int rsa_generate(struct RSAKey *key, struct RSAAux *aux, int bits,
                 progfn_t pfn, void *pfnparam) {
    Bignum pm1, qm1, phi_n;

    /*
     * Set up the phase limits for the progress report. We do this
     * by passing minus the phase number.
     *
     * For prime generation: our initial filter finds things
     * coprime to everything below 2^16. Computing the product of
     * (p-1)/p for all prime p below 2^16 gives about 20.33; so
     * among B-bit integers, one in every 20.33 will get through
     * the initial filter to be a candidate prime.
     *
     * Meanwhile, we are searching for primes in the region of 2^B;
     * since pi(x) ~ x/log(x), when x is in the region of 2^B, the
     * prime density will be d/dx pi(x) ~ 1/log(B), i.e. about
     * 1/0.6931B. So the chance of any given candidate being prime
     * is 20.33/0.6931B, which is roughly 29.34 divided by B.
     *
     * So now we have this probability P, we're looking at an
     * exponential distribution with parameter P: we will manage in
     * one attempt with probability P, in two with probability
     * P(1-P), in three with probability P(1-P)^2, etc. The
     * probability that we have still not managed to find a prime
     * after N attempts is (1-P)^N.
     * 
     * We therefore inform the progress indicator of the number B
     * (29.34/B), so that it knows how much to increment by each
     * time. We do this in 16-bit fixed point, so 29.34 becomes
     * 0x1D.57C4.
     */
    pfn(pfnparam, -1, -0x1D57C4/(bits/2));
    pfn(pfnparam, -2, -0x1D57C4/(bits-bits/2));
    pfn(pfnparam, -3, 5);

    /*
     * We don't generate e; we just use a standard one always.
     */
    key->exponent = bignum_from_short(RSA_EXPONENT);

    /*
     * Generate p and q: primes with combined length `bits', not
     * congruent to 1 modulo e. (Strictly speaking, we wanted (p-1)
     * and e to be coprime, and (q-1) and e to be coprime, but in
     * general that's slightly more fiddly to arrange. By choosing
     * a prime e, we can simplify the criterion.)
     */
    aux->p = primegen(bits/2, RSA_EXPONENT, 1, 1, pfn, pfnparam);
    aux->q = primegen(bits - bits/2, RSA_EXPONENT, 1, 2, pfn, pfnparam);

    /*
     * Ensure p > q, by swapping them if not.
     */
    if (bignum_cmp(aux->p, aux->q) < 0) {
        Bignum t = aux->p;
        aux->p = aux->q;
        aux->q = t;
    }

    /*
     * Now we have p, q and e. All we need to do now is work out
     * the other helpful quantities: n=pq, d=e^-1 mod (p-1)(q-1),
     * and (q^-1 mod p).
     */
    pfn(pfnparam, 3, 1);
    key->modulus = bigmul(aux->p, aux->q);
    pfn(pfnparam, 3, 2);
    pm1 = copybn(aux->p);
    decbn(pm1);
    qm1 = copybn(aux->q);
    decbn(qm1);
    phi_n = bigmul(pm1, qm1);
    pfn(pfnparam, 3, 3);
    freebn(pm1);
    freebn(qm1);
    key->private_exponent = modinv(key->exponent, phi_n);
    pfn(pfnparam, 3, 4);
    aux->iqmp = modinv(aux->q, aux->p);
    pfn(pfnparam, 3, 5);

    /*
     * Clean up temporary numbers.
     */
    freebn(phi_n);

    return 1;
}