Example #1
0
/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in
 * Montgomery projective coordinates. Uses algorithm Madd in appendix of
 * Lopex, J. and Dahab, R.  "Fast multiplication on elliptic curves over
 * GF(2^m) without precomputation". */
static mp_err
gf2m_Madd(const mp_int *x, mp_int *x1, mp_int *z1, mp_int *x2, mp_int *z2,
                  const ECGroup *group, int kmflag)
{
        mp_err res = MP_OKAY;
        mp_int t1, t2;

        MP_DIGITS(&t1) = 0;
        MP_DIGITS(&t2) = 0;
        MP_CHECKOK(mp_init(&t1, kmflag));
        MP_CHECKOK(mp_init(&t2, kmflag));

        MP_CHECKOK(mp_copy(x, &t1));
        MP_CHECKOK(group->meth->field_mul(x1, z2, x1, group->meth));
        MP_CHECKOK(group->meth->field_mul(z1, x2, z1, group->meth));
        MP_CHECKOK(group->meth->field_mul(x1, z1, &t2, group->meth));
        MP_CHECKOK(group->meth->field_add(z1, x1, z1, group->meth));
        MP_CHECKOK(group->meth->field_sqr(z1, z1, group->meth));
        MP_CHECKOK(group->meth->field_mul(z1, &t1, x1, group->meth));
        MP_CHECKOK(group->meth->field_add(x1, &t2, x1, group->meth));

  CLEANUP:
        mp_clear(&t1);
        mp_clear(&t2);
        return res;
}
Example #2
0
/*
** 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;
}
Example #3
0
static SECStatus
init_blinding_params(RSABlindingParams *rsabp, RSAPrivateKey *key,
                     mp_int *n, unsigned int modLen)
{
    blindingParams * bp = rsabp->array;
    int i = 0;

    /* Initialize the list pointer for the element */
    PR_INIT_CLIST(&rsabp->link);
    for (i = 0; i < RSA_BLINDING_PARAMS_MAX_CACHE_SIZE; ++i, ++bp) {
    	bp->next = bp + 1;
	MP_DIGITS(&bp->f) = 0;
	MP_DIGITS(&bp->g) = 0;
	bp->counter = 0;
    }
    /* The last bp->next value was initialized with out
     * of rsabp->array pointer and must be set to NULL 
     */ 
    rsabp->array[RSA_BLINDING_PARAMS_MAX_CACHE_SIZE - 1].next = NULL;
    
    bp          = rsabp->array;
    rsabp->bp   = NULL;
    rsabp->free = bp;

    /* List elements are keyed using the modulus */
    SECITEM_CopyItem(NULL, &rsabp->modulus, &key->modulus);

    return SECSuccess;
}
Example #4
0
/* Allocate memory for a new ECGroup object. */
ECGroup *
ECGroup_new()
{
    mp_err res = MP_OKAY;
    ECGroup *group;
    group = (ECGroup *) malloc(sizeof(ECGroup));
    if (group == NULL)
        return NULL;
    group->constructed = MP_YES;
    group->meth = NULL;
    group->text = NULL;
    MP_DIGITS(&group->curvea) = 0;
    MP_DIGITS(&group->curveb) = 0;
    MP_DIGITS(&group->genx) = 0;
    MP_DIGITS(&group->geny) = 0;
    MP_DIGITS(&group->order) = 0;
    group->base_point_mul = NULL;
    group->points_mul = NULL;
    group->validate_point = NULL;
    group->extra1 = NULL;
    group->extra2 = NULL;
    group->extra_free = NULL;
    MP_CHECKOK(mp_init(&group->curvea));
    MP_CHECKOK(mp_init(&group->curveb));
    MP_CHECKOK(mp_init(&group->genx));
    MP_CHECKOK(mp_init(&group->geny));
    MP_CHECKOK(mp_init(&group->order));

CLEANUP:
    if (res != MP_OKAY) {
        ECGroup_free(group);
        return NULL;
    }
    return group;
}
Example #5
0
/* Tests pre computation of Chudnovsky Jacobian points used in wNAF form */
mp_err
testPreCompute(ECGroup *ecgroup)
{
	ecfp_chud_pt precomp[16];
	ecfp_aff_pt p;
	EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;
	int i;
	mp_err res;

	mp_int x, y, ny, x2, y2;

	MP_DIGITS(&x) = 0;
	MP_DIGITS(&y) = 0;
	MP_DIGITS(&ny) = 0;
	MP_DIGITS(&x2) = 0;
	MP_DIGITS(&y2) = 0;

	MP_CHECKOK(mp_init(&x));
	MP_CHECKOK(mp_init(&y));
	MP_CHECKOK(mp_init(&ny));
	MP_CHECKOK(mp_init(&x2));
	MP_CHECKOK(mp_init(&y2));

	ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
	ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
	ecfp_i2fp(group->curvea, &(ecgroup->curvea), ecgroup);

	/* Perform precomputation */
	group->precompute_chud(precomp, &p, group);

	M_TimeOperation(group->precompute_chud(precomp, &p, group), 10000);

	/* Calculate addition to compare against */
	MP_CHECKOK(mp_copy(&ecgroup->genx, &x));
	MP_CHECKOK(mp_copy(&ecgroup->geny, &y));
	MP_CHECKOK(ecgroup->meth->field_neg(&y, &ny, ecgroup->meth));

	ec_GFp_pt_dbl_aff(&x, &y, &x2, &y2, ecgroup);

	for (i = 0; i < 8; i++) {
		MP_CHECKOK(testChudPoint(&precomp[8 + i], &x, &y, ecgroup));
		MP_CHECKOK(testChudPoint(&precomp[7 - i], &x, &ny, ecgroup));
		ec_GFp_pt_add_aff(&x, &y, &x2, &y2, &x, &y, ecgroup);
		MP_CHECKOK(ecgroup->meth->field_neg(&y, &ny, ecgroup->meth));
	}

  CLEANUP:
	if (res == MP_OKAY)
		printf("  Test Passed - Precomputation\n");
	else
		printf("TEST FAILED - Precomputation\n");

	mp_clear(&x);
	mp_clear(&y);
	mp_clear(&ny);
	mp_clear(&x2);
	mp_clear(&y2);
	return res;
}
Example #6
0
/*
**  RSA Private key operation using CRT.
*/
static SECStatus 
rsa_PrivateKeyOpCRTNoCheck(RSAPrivateKey *key, mp_int *m, mp_int *c)
{
    mp_int p, q, d_p, d_q, qInv;
    mp_int m1, m2, h, ctmp;
    mp_err   err = MP_OKAY;
    SECStatus rv = SECSuccess;
    MP_DIGITS(&p)    = 0;
    MP_DIGITS(&q)    = 0;
    MP_DIGITS(&d_p)  = 0;
    MP_DIGITS(&d_q)  = 0;
    MP_DIGITS(&qInv) = 0;
    MP_DIGITS(&m1)   = 0;
    MP_DIGITS(&m2)   = 0;
    MP_DIGITS(&h)    = 0;
    MP_DIGITS(&ctmp) = 0;
    CHECK_MPI_OK( mp_init(&p)    );
    CHECK_MPI_OK( mp_init(&q)    );
    CHECK_MPI_OK( mp_init(&d_p)  );
    CHECK_MPI_OK( mp_init(&d_q)  );
    CHECK_MPI_OK( mp_init(&qInv) );
    CHECK_MPI_OK( mp_init(&m1)   );
    CHECK_MPI_OK( mp_init(&m2)   );
    CHECK_MPI_OK( mp_init(&h)    );
    CHECK_MPI_OK( mp_init(&ctmp) );
    /* copy private key parameters into mp integers */
    SECITEM_TO_MPINT(key->prime1,      &p);    /* p */
    SECITEM_TO_MPINT(key->prime2,      &q);    /* q */
    SECITEM_TO_MPINT(key->exponent1,   &d_p);  /* d_p  = d mod (p-1) */
    SECITEM_TO_MPINT(key->exponent2,   &d_q);  /* d_q  = d mod (q-1) */
    SECITEM_TO_MPINT(key->coefficient, &qInv); /* qInv = q**-1 mod p */
    /* 1. m1 = c**d_p mod p */
    CHECK_MPI_OK( mp_mod(c, &p, &ctmp) );
    CHECK_MPI_OK( mp_exptmod(&ctmp, &d_p, &p, &m1) );
    /* 2. m2 = c**d_q mod q */
    CHECK_MPI_OK( mp_mod(c, &q, &ctmp) );
    CHECK_MPI_OK( mp_exptmod(&ctmp, &d_q, &q, &m2) );
    /* 3.  h = (m1 - m2) * qInv mod p */
    CHECK_MPI_OK( mp_submod(&m1, &m2, &p, &h) );
    CHECK_MPI_OK( mp_mulmod(&h, &qInv, &p, &h)  );
    /* 4.  m = m2 + h * q */
    CHECK_MPI_OK( mp_mul(&h, &q, m) );
    CHECK_MPI_OK( mp_add(m, &m2, m) );
cleanup:
    mp_clear(&p);
    mp_clear(&q);
    mp_clear(&d_p);
    mp_clear(&d_q);
    mp_clear(&qInv);
    mp_clear(&m1);
    mp_clear(&m2);
    mp_clear(&h);
    mp_clear(&ctmp);
    if (err) {
	MP_TO_SEC_ERROR(err);
	rv = SECFailure;
    }
    return rv;
}
Example #7
0
/* Tests point addition of Jacobian + Affine -> Jacobian */
mp_err
testPointAddJacAff(ECGroup *ecgroup)
{
	mp_err res;
	mp_int pz, rx2, ry2, rz2;
	ecfp_jac_pt p, r;
	ecfp_aff_pt q;
	EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;

	/* Init */
	MP_DIGITS(&pz) = 0;
	MP_DIGITS(&rx2) = 0;
	MP_DIGITS(&ry2) = 0;
	MP_DIGITS(&rz2) = 0;
	MP_CHECKOK(mp_init(&pz));
	MP_CHECKOK(mp_init(&rx2));
	MP_CHECKOK(mp_init(&ry2));
	MP_CHECKOK(mp_init(&rz2));

	MP_CHECKOK(mp_set_int(&pz, 5));

	/* Set p */
	ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
	ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
	ecfp_i2fp(p.z, &pz, ecgroup);
	/* Set q */
	ecfp_i2fp(q.x, &ecgroup->geny, ecgroup);
	ecfp_i2fp(q.y, &ecgroup->genx, ecgroup);

	/* Do calculations */
	group->pt_add_jac_aff(&p, &q, &r, group);

	/* Do calculation in integer to compare against */
	MP_CHECKOK(ec_GFp_pt_add_jac_aff
			   (&ecgroup->genx, &ecgroup->geny, &pz, &ecgroup->geny,
				&ecgroup->genx, &rx2, &ry2, &rz2, ecgroup));
	/* convert result R to affine coordinates */
	ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);

	MP_CHECKOK(testJacPoint(&r, &rx2, &ry2, ecgroup));

  CLEANUP:
	if (res == MP_OKAY)
		printf("  Test Passed - Point Addition - Jacobian & Affine\n");
	else
		printf("TEST FAILED - Point Addition - Jacobian & Affine\n");

	mp_clear(&pz);
	mp_clear(&rx2);
	mp_clear(&ry2);
	mp_clear(&rz2);

	return res;
}
Example #8
0
File: ec.c Project: txazo/hotspot
/* Generate a random private key using the algorithm A.4.1 of ANSI X9.62,
 * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the
 * random number generator.
 *
 * Parameters
 * - order: a buffer that holds the curve's group order
 * - len: the length in octets of the order buffer
 * - random: a buffer of 2 * len random bytes
 * - randomlen: the length in octets of the random buffer
 *
 * Return Value
 * Returns a buffer of len octets that holds the private key. The caller
 * is responsible for freeing the buffer with PORT_ZFree.
 */
static unsigned char *
ec_GenerateRandomPrivateKey(const unsigned char *order, int len,
    const unsigned char *random, int randomlen, int kmflag)
{
    SECStatus rv = SECSuccess;
    mp_err err;
    unsigned char *privKeyBytes = NULL;
    mp_int privKeyVal, order_1, one;

    MP_DIGITS(&privKeyVal) = 0;
    MP_DIGITS(&order_1) = 0;
    MP_DIGITS(&one) = 0;
    CHECK_MPI_OK( mp_init(&privKeyVal, kmflag) );
    CHECK_MPI_OK( mp_init(&order_1, kmflag) );
    CHECK_MPI_OK( mp_init(&one, kmflag) );

    /*
     * Reduces the 2*len buffer of random bytes modulo the group order.
     */
    if ((privKeyBytes = PORT_Alloc(2*len, kmflag)) == NULL) goto cleanup;
    if (randomlen != 2 * len) {
        randomlen = 2 * len;
    }
    /* No need to generate - random bytes are now supplied */
    /* CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) );*/
    memcpy(privKeyBytes, random, randomlen);

    CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) );
    CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) );
    CHECK_MPI_OK( mp_set_int(&one, 1) );
    CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) );
    CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) );
    CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) );
    CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) );
    memset(privKeyBytes+len, 0, len);
cleanup:
    mp_clear(&privKeyVal);
    mp_clear(&order_1);
    mp_clear(&one);
    if (err < MP_OKAY) {
        MP_TO_SEC_ERROR(err);
        rv = SECFailure;
    }
    if (rv != SECSuccess && privKeyBytes) {
#ifdef _KERNEL
        kmem_free(privKeyBytes, 2*len);
#else
        free(privKeyBytes);
#endif
        privKeyBytes = NULL;
    }
    return privKeyBytes;
}
Example #9
0
/* Tests the time required for a point multiplication */
mp_err
testPointMulTime(ECGroup *ecgroup)
{
	mp_err res = MP_OKAY;
	mp_int rx, ry, n;
	int size;

	MP_DIGITS(&rx) = 0;
	MP_DIGITS(&ry) = 0;
	MP_DIGITS(&n) = 0;

	MP_CHECKOK(mp_init(&rx));
	MP_CHECKOK(mp_init(&ry));
	MP_CHECKOK(mp_init(&n));

	/* compute random scalar */
	size = mpl_significant_bits(&ecgroup->meth->irr);
	if (size < MP_OKAY) {
		res = MP_NO;
		goto CLEANUP;
	}

	MP_CHECKOK(mpp_random_size(&n, (size + ECL_BITS - 1) / ECL_BITS));
	MP_CHECKOK(ecgroup->meth->field_mod(&n, &n, ecgroup->meth));

	M_TimeOperation(ec_GFp_pt_mul_jac_fp
					(&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
					 ecgroup), 1000);

	M_TimeOperation(ec_GFp_point_mul_jac_4w_fp
					(&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
					 ecgroup), 1000);

	M_TimeOperation(ec_GFp_point_mul_wNAF_fp
					(&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
					 ecgroup), 1000);

	M_TimeOperation(ec_GFp_pt_mul_jac
					(&n, &ecgroup->genx, &ecgroup->geny, &rx, &ry,
					 ecgroup), 100);

  CLEANUP:
	if (res == MP_OKAY)
		printf("  Test Passed - Point Multiplication Timing\n");
	else
		printf("TEST FAILED - Point Multiplication Timing\n");
	mp_clear(&rx);
	mp_clear(&ry);
	mp_clear(&n);

	return res;
}
Example #10
0
/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k * P(x,
 * y).  If x, y = NULL, then P is assumed to be the generator (base point)
 * of the group of points on the elliptic curve. Input and output values
 * are assumed to be NOT field-encoded. */
mp_err
ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px,
                        const mp_int *py, mp_int *rx, mp_int *ry)
{
        mp_err res = MP_OKAY;
        mp_int kt;

        ARGCHK((k != NULL) && (group != NULL), MP_BADARG);
        MP_DIGITS(&kt) = 0;

        /* want scalar to be less than or equal to group order */
        if (mp_cmp(k, &group->order) > 0) {
                MP_CHECKOK(mp_init(&kt, FLAG(k)));
                MP_CHECKOK(mp_mod(k, &group->order, &kt));
        } else {
                MP_SIGN(&kt) = MP_ZPOS;
                MP_USED(&kt) = MP_USED(k);
                MP_ALLOC(&kt) = MP_ALLOC(k);
                MP_DIGITS(&kt) = MP_DIGITS(k);
        }

        if ((px == NULL) || (py == NULL)) {
                if (group->base_point_mul) {
                        MP_CHECKOK(group->base_point_mul(&kt, rx, ry, group));
                } else {
                        MP_CHECKOK(group->
                                           point_mul(&kt, &group->genx, &group->geny, rx, ry,
                                                                 group));
                }
        } else {
                if (group->meth->field_enc) {
                        MP_CHECKOK(group->meth->field_enc(px, rx, group->meth));
                        MP_CHECKOK(group->meth->field_enc(py, ry, group->meth));
                        MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group));
                } else {
                        MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group));
                }
        }
        if (group->meth->field_dec) {
                MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
                MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
        }

  CLEANUP:
        if (MP_DIGITS(&kt) != MP_DIGITS(k)) {
                mp_clear(&kt);
        }
        return res;
}
Example #11
0
/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
 * k2 * P(x, y), where G is the generator (base point) of the group of
 * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
 * Input and output values are assumed to be NOT field-encoded. */
mp_err
ECPoints_mul(const ECGroup *group, const mp_int *k1, const mp_int *k2,
                         const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry)
{
        mp_err res = MP_OKAY;
        mp_int k1t, k2t;
        const mp_int *k1p, *k2p;

        MP_DIGITS(&k1t) = 0;
        MP_DIGITS(&k2t) = 0;

        ARGCHK(group != NULL, MP_BADARG);

        /* want scalar to be less than or equal to group order */
        if (k1 != NULL) {
                if (mp_cmp(k1, &group->order) >= 0) {
                        MP_CHECKOK(mp_init(&k1t, FLAG(k1)));
                        MP_CHECKOK(mp_mod(k1, &group->order, &k1t));
                        k1p = &k1t;
                } else {
                        k1p = k1;
                }
        } else {
                k1p = k1;
        }
        if (k2 != NULL) {
                if (mp_cmp(k2, &group->order) >= 0) {
                        MP_CHECKOK(mp_init(&k2t, FLAG(k2)));
                        MP_CHECKOK(mp_mod(k2, &group->order, &k2t));
                        k2p = &k2t;
                } else {
                        k2p = k2;
                }
        } else {
                k2p = k2;
        }

        /* if points_mul is defined, then use it */
        if (group->points_mul) {
                res = group->points_mul(k1p, k2p, px, py, rx, ry, group);
        } else {
                res = ec_pts_mul_simul_w2(k1p, k2p, px, py, rx, ry, group);
        }

  CLEANUP:
        mp_clear(&k1t);
        mp_clear(&k2t);
        return res;
}
Example #12
0
/* Field multiplication using Montgomery reduction. */
mp_err
ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
				const GFMethod *meth)
{
	mp_err res = MP_OKAY;

#ifdef MP_MONT_USE_MP_MUL
	/* if MP_MONT_USE_MP_MUL is defined, then the function s_mp_mul_mont
	 * is not implemented and we have to use mp_mul and s_mp_redc directly 
	 */
	MP_CHECKOK(mp_mul(a, b, r));
	MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
#else
	mp_int s;

	MP_DIGITS(&s) = 0;
	/* s_mp_mul_mont doesn't allow source and destination to be the same */
	if ((a == r) || (b == r)) {
		MP_CHECKOK(mp_init(&s));
		MP_CHECKOK(s_mp_mul_mont
				   (a, b, &s, (mp_mont_modulus *) meth->extra1));
		MP_CHECKOK(mp_copy(&s, r));
		mp_clear(&s);
	} else {
		return s_mp_mul_mont(a, b, r, (mp_mont_modulus *) meth->extra1);
	}
#endif
  CLEANUP:
	return res;
}
Example #13
0
/*
 * mpi_to_weave takes an array of bignums, a matrix in which each bignum 
 * occupies all the columns of a row, and transposes it into a matrix in 
 * which each bignum occupies a column of every row.  The first row of the
 * input matrix becomes the first column of the output matrix.  The n'th
 * row of input becomes the n'th column of output.  The input data is said
 * to be "interleaved" or "woven" into the output matrix.
 *
 * The array of bignums is left in this woven form.  Each time a single
 * bignum value is needed, it is recreated by fetching the n'th column, 
 * forming a single row which is the new bignum.
 *
 * The purpose of this interleaving is make it impossible to determine which
 * of the bignums is being used in any one operation by examining the pattern
 * of cache misses.
 *
 * The weaving function does not transpose the entire input matrix in one call.
 * It transposes 4 rows of mp_ints into their respective columns of output.
 *
 * There are two different implementations of the weaving and unweaving code
 * in this file.  One uses byte loads and stores.  The second uses loads and
 * stores of mp_weave_word size values.  The weaved forms of these two 
 * implementations differ.  Consequently, each one has its own explanation.
 *
 * Here is the explanation for the byte-at-a-time implementation.
 *
 * This implementation treats each mp_int bignum as an array of bytes, 
 * rather than as an array of mp_digits.  It stores those bytes as a 
 * column of bytes in the output matrix.  It doesn't care if the machine
 * uses big-endian or little-endian byte ordering within mp_digits.
 * The first byte of the mp_digit array becomes the first byte in the output
 * column, regardless of whether that byte is the MSB or LSB of the mp_digit.
 *
 * "bignums" is an array of mp_ints.
 * It points to four rows, four mp_ints, a subset of a larger array of mp_ints.
 *
 * "weaved" is the weaved output matrix. 
 * The first byte of bignums[0] is stored in weaved[0].
 * 
 * "nBignums" is the total number of bignums in the array of which "bignums" 
 * is a part.  
 *
 * "nDigits" is the size in mp_digits of each mp_int in the "bignums" array. 
 * mp_ints that use less than nDigits digits are logically padded with zeros 
 * while being stored in the weaved array.
 */
mp_err mpi_to_weave(const mp_int  *bignums, 
                    unsigned char *weaved, 
		    mp_size nDigits,  /* in each mp_int of input */
		    mp_size nBignums) /* in the entire source array */
{
  mp_size i;
  unsigned char * endDest = weaved + (nDigits * nBignums * sizeof(mp_digit));

  for (i=0; i < WEAVE_WORD_SIZE; i++) {
    mp_size used = MP_USED(&bignums[i]);
    unsigned char *pSrc   = (unsigned char *)MP_DIGITS(&bignums[i]);
    unsigned char *endSrc = pSrc + (used * sizeof(mp_digit));
    unsigned char *pDest  = weaved + i;

    ARGCHK(MP_SIGN(&bignums[i]) == MP_ZPOS, MP_BADARG);
    ARGCHK(used <= nDigits, MP_BADARG);

    for (; pSrc < endSrc; pSrc++) {
      *pDest = *pSrc;
      pDest += nBignums;
    }
    while (pDest < endDest) {
      *pDest = 0;
      pDest += nBignums;
    }
  }

  return MP_OKAY;
}
Example #14
0
/* Reverse the operation above for one mp_int.
 * Reconstruct one mp_int from its column in the weaved array.
 * Every read accesses every element of the weaved array, in order to
 * avoid timing attacks based on patterns of memory accesses.
 */
mp_err weave_to_mpi(mp_int *a,              /* out, result */
                    const mp_digit *weaved, /* in, byte matrix */
                    mp_size index,          /* which column to read */
                    mp_size nDigits,        /* number of mp_digits in each bignum */
                    mp_size nBignums)       /* width of the matrix */
{
    /* these are indices, but need to be the same size as mp_digit
     * because of the CONST_TIME operations */
    mp_digit i, j;
    mp_digit d;
    mp_digit *pDest = MP_DIGITS(a);

    MP_SIGN(a) = MP_ZPOS;
    MP_USED(a) = nDigits;

    assert(weaved != NULL);

    /* Fetch the proper column in constant time, indexing over the whole array */
    for (i = 0; i < nDigits; ++i) {
        d = 0;
        for (j = 0; j < nBignums; ++j) {
            d |= weaved[i * nBignums + j] & CONST_TIME_EQ(j, index);
        }
        pDest[i] = d;
    }

    s_mp_clamp(a);
    return MP_OKAY;
}
Example #15
0
/* Generate a random private key using the algorithm A.4.1 of ANSI X9.62,
 * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the
 * random number generator.
 *
 * Parameters
 * - order: a buffer that holds the curve's group order
 * - len: the length in octets of the order buffer
 *
 * Return Value
 * Returns a buffer of len octets that holds the private key. The caller
 * is responsible for freeing the buffer with PORT_ZFree.
 */
static unsigned char *
ec_GenerateRandomPrivateKey(const unsigned char *order, int len, int kmflag)
{
    SECStatus rv = SECSuccess;
    mp_err err;
    unsigned char *privKeyBytes = NULL;
    mp_int privKeyVal, order_1, one;

    MP_DIGITS(&privKeyVal) = 0;
    MP_DIGITS(&order_1) = 0;
    MP_DIGITS(&one) = 0;
    CHECK_MPI_OK( mp_init(&privKeyVal) );
    CHECK_MPI_OK( mp_init(&order_1) );
    CHECK_MPI_OK( mp_init(&one) );

    /* Generates 2*len random bytes using the global random bit generator
     * (which implements Algorithm 1 of FIPS 186-2 Change Notice 1) then
     * reduces modulo the group order.
     */
    if ((privKeyBytes = PORT_Alloc(2*len, kmflag)) == NULL) goto cleanup;
    CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) );
    CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) );
    CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) );
    CHECK_MPI_OK( mp_set_int(&one, 1) );
    CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) );
    CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) );
    CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) );
    CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) );
    memset(privKeyBytes+len, 0, len);
cleanup:
    mp_clear(&privKeyVal);
    mp_clear(&order_1);
    mp_clear(&one);
    if (err < MP_OKAY) {
	MP_TO_SEC_ERROR(err);
	rv = SECFailure;
    }
    if (rv != SECSuccess && privKeyBytes) {
#ifdef _KERNEL
	kmem_free(privKeyBytes, 2*len);
#else
	free(privKeyBytes);
#endif
	privKeyBytes = NULL;
    }
    return privKeyBytes;
}
Example #16
0
/* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G +
 * k2 * P(x, y), where G is the generator (base point) of the group of
 * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL.
 * Input and output values are assumed to be NOT field-encoded. */
mp_err
ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px,
                                 const mp_int *py, mp_int *rx, mp_int *ry,
                                 const ECGroup *group)
{
        mp_err res = MP_OKAY;
        mp_int sx, sy;

        ARGCHK(group != NULL, MP_BADARG);
        ARGCHK(!((k1 == NULL)
                         && ((k2 == NULL) || (px == NULL)
                                 || (py == NULL))), MP_BADARG);

        /* if some arguments are not defined used ECPoint_mul */
        if (k1 == NULL) {
                return ECPoint_mul(group, k2, px, py, rx, ry);
        } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
                return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
        }

        MP_DIGITS(&sx) = 0;
        MP_DIGITS(&sy) = 0;
        MP_CHECKOK(mp_init(&sx, FLAG(k1)));
        MP_CHECKOK(mp_init(&sy, FLAG(k1)));

        MP_CHECKOK(ECPoint_mul(group, k1, NULL, NULL, &sx, &sy));
        MP_CHECKOK(ECPoint_mul(group, k2, px, py, rx, ry));

        if (group->meth->field_enc) {
                MP_CHECKOK(group->meth->field_enc(&sx, &sx, group->meth));
                MP_CHECKOK(group->meth->field_enc(&sy, &sy, group->meth));
                MP_CHECKOK(group->meth->field_enc(rx, rx, group->meth));
                MP_CHECKOK(group->meth->field_enc(ry, ry, group->meth));
        }

        MP_CHECKOK(group->point_add(&sx, &sy, rx, ry, rx, ry, group));

        if (group->meth->field_dec) {
                MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
                MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
        }

  CLEANUP:
        mp_clear(&sx);
        mp_clear(&sy);
        return res;
}
Example #17
0
/* reverse the operation above for one entry.
 * b points to the offset into the weave array of the power we are
 * calculating */
mp_err weave_to_mpi(mp_int *a, const unsigned char *b, 
					mp_size b_size, mp_size count)
{
  mp_digit *pb = MP_DIGITS(a);
  mp_digit *end = &pb[b_size];

  MP_SIGN(a) = MP_ZPOS;
  MP_USED(a) = b_size;

  for (; pb < end; pb++) {
    register mp_digit digit;

    digit = *b << 8; b += count;
#define MPI_UNWEAVE_ONE_STEP  digit |= *b; b += count; digit = digit << 8;
    switch (sizeof(mp_digit)) {
    case 32:
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
    case 16:
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
    case 8:
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
    case 4:
	MPI_UNWEAVE_ONE_STEP 
	MPI_UNWEAVE_ONE_STEP 
    case 2:
	break;
    }
    digit |= *b; b += count; 

    *pb = digit;
  }
  s_mp_clamp(a);
  return MP_OKAY;
}
Example #18
0
/* Test point doubling in Jacobian coordinates */
mp_err
testPointDoubleJac(ECGroup *ecgroup)
{
	mp_err res;
	mp_int pz, rx, ry, rz, rx2, ry2, rz2;
	ecfp_jac_pt p, p2;
	EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;

	MP_DIGITS(&pz) = 0;
	MP_DIGITS(&rx) = 0;
	MP_DIGITS(&ry) = 0;
	MP_DIGITS(&rz) = 0;
	MP_DIGITS(&rx2) = 0;
	MP_DIGITS(&ry2) = 0;
	MP_DIGITS(&rz2) = 0;

	MP_CHECKOK(mp_init(&pz));
	MP_CHECKOK(mp_init(&rx));
	MP_CHECKOK(mp_init(&ry));
	MP_CHECKOK(mp_init(&rz));
	MP_CHECKOK(mp_init(&rx2));
	MP_CHECKOK(mp_init(&ry2));
	MP_CHECKOK(mp_init(&rz2));

	MP_CHECKOK(mp_set_int(&pz, 5));

	/* Set p2 = 2P */
	ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
	ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
	ecfp_i2fp(p.z, &pz, ecgroup);
	ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);

	group->pt_dbl_jac(&p, &p2, group);
	M_TimeOperation(group->pt_dbl_jac(&p, &p2, group), 100000);

	/* Calculate doubling to compare against */
	ec_GFp_pt_dbl_jac(&ecgroup->genx, &ecgroup->geny, &pz, &rx2, &ry2,
					  &rz2, ecgroup);
	ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);

	/* Do comparison */
	MP_CHECKOK(testJacPoint(&p2, &rx2, &ry2, ecgroup));

  CLEANUP:
	if (res == MP_OKAY)
		printf("  Test Passed - Point Doubling - Jacobian\n");
	else
		printf("TEST FAILED - Point Doubling - Jacobian\n");

	mp_clear(&pz);
	mp_clear(&rx);
	mp_clear(&ry);
	mp_clear(&rz);
	mp_clear(&rx2);
	mp_clear(&ry2);
	mp_clear(&rz2);

	return res;
}
Example #19
0
/* Tests a point p in Jacobian coordinates, comparing against the
 * expected affine result (x, y). */
mp_err
testJacPoint(ecfp_jac_pt * p, mp_int *x, mp_int *y, ECGroup *ecgroup)
{
	char s[1000];
	mp_int rx, ry, rz;
	mp_err res = MP_OKAY;

	MP_DIGITS(&rx) = 0;
	MP_DIGITS(&ry) = 0;
	MP_DIGITS(&rz) = 0;

	MP_CHECKOK(mp_init(&rx));
	MP_CHECKOK(mp_init(&ry));
	MP_CHECKOK(mp_init(&rz));

	ecfp_fp2i(&rx, p->x, ecgroup);
	ecfp_fp2i(&ry, p->y, ecgroup);
	ecfp_fp2i(&rz, p->z, ecgroup);

	/* convert result R to affine coordinates */
	ec_GFp_pt_jac2aff(&rx, &ry, &rz, &rx, &ry, ecgroup);

	/* Compare to expected result */
	if ((mp_cmp(&rx, x) != 0) || (mp_cmp(&ry, y) != 0)) {
		printf("  Error: Jacobian Floating Point Incorrect.\n");
		MP_CHECKOK(mp_toradix(&rx, s, 16));
		printf("floating point result\nrx    %s\n", s);
		MP_CHECKOK(mp_toradix(&ry, s, 16));
		printf("ry    %s\n", s);
		MP_CHECKOK(mp_toradix(x, s, 16));
		printf("integer result\nx   %s\n", s);
		MP_CHECKOK(mp_toradix(y, s, 16));
		printf("y   %s\n", s);
		res = MP_NO;
		goto CLEANUP;
	}

  CLEANUP:
	mp_clear(&rx);
	mp_clear(&ry);
	mp_clear(&rz);

	return res;
}
Example #20
0
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;
}
Example #21
0
/* Allocate memory for a new ECGroup object. */
ECGroup *
ECGroup_new(int kmflag)
{
	mp_err res = MP_OKAY;
	ECGroup *group;
#ifdef _KERNEL
	group = (ECGroup *) kmem_alloc(sizeof(ECGroup), kmflag);
#else
	group = (ECGroup *) malloc(sizeof(ECGroup));
#endif
	if (group == NULL)
		return NULL;
	group->constructed = MP_YES;
        group->meth = NULL;
	group->text = NULL;
	MP_DIGITS(&group->curvea) = 0;
	MP_DIGITS(&group->curveb) = 0;
	MP_DIGITS(&group->genx) = 0;
	MP_DIGITS(&group->geny) = 0;
	MP_DIGITS(&group->order) = 0;
	group->base_point_mul = NULL;
	group->points_mul = NULL;
	group->validate_point = NULL;
	group->extra1 = NULL;
	group->extra2 = NULL;
	group->extra_free = NULL;
	MP_CHECKOK(mp_init(&group->curvea, kmflag));
	MP_CHECKOK(mp_init(&group->curveb, kmflag));
	MP_CHECKOK(mp_init(&group->genx, kmflag));
	MP_CHECKOK(mp_init(&group->geny, kmflag));
	MP_CHECKOK(mp_init(&group->order, kmflag));

  CLEANUP:
	if (res != MP_OKAY) {
		ECGroup_free(group);
		return NULL;
	}
	return group;
}
Example #22
0
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;
}
/*
 * FIPS 186-2 requires result from random output to be reduced mod q when 
 * generating random numbers for DSA. 
 *
 * Input: w, 2*qLen bytes
 *        q, qLen bytes
 * Output: xj, qLen bytes
 */
static SECStatus
fips186Change_ReduceModQForDSA(const PRUint8 *w, const PRUint8 *q,
                               unsigned int qLen, PRUint8 * xj)
{
    mp_int W, Q, Xj;
    mp_err err;
    SECStatus rv = SECSuccess;

    /* Initialize MPI integers. */
    MP_DIGITS(&W) = 0;
    MP_DIGITS(&Q) = 0;
    MP_DIGITS(&Xj) = 0;
    CHECK_MPI_OK( mp_init(&W) );
    CHECK_MPI_OK( mp_init(&Q) );
    CHECK_MPI_OK( mp_init(&Xj) );
    /*
     * Convert input arguments into MPI integers.
     */
    CHECK_MPI_OK( mp_read_unsigned_octets(&W, w, 2*qLen) );
    CHECK_MPI_OK( mp_read_unsigned_octets(&Q, q, qLen) );

    /*
     * Algorithm 1 of FIPS 186-2 Change Notice 1, Step 3.3
     *
     * xj = (w0 || w1) mod q
     */
    CHECK_MPI_OK( mp_mod(&W, &Q, &Xj) );
    CHECK_MPI_OK( mp_to_fixlen_octets(&Xj, xj, qLen) );
cleanup:
    mp_clear(&W);
    mp_clear(&Q);
    mp_clear(&Xj);
    if (err) {
	MP_TO_SEC_ERROR(err);
	rv = SECFailure;
    }
    return rv;
}
Example #24
0
/*! c <- REDC( a * b ) mod N
    \param a < N  i.e. "reduced"
    \param b < N  i.e. "reduced"
    \param mmm modulus N and n0' of N
*/
mp_err
s_mp_mul_mont(const mp_int *a, const mp_int *b, mp_int *c,
              mp_mont_modulus *mmm)
{
    mp_digit *pb;
    mp_digit m_i;
    mp_err res;
    mp_size ib; /* "index b": index of current digit of B */
    mp_size useda, usedb;

    ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);

    if (MP_USED(a) < MP_USED(b)) {
        const mp_int *xch = b; /* switch a and b, to do fewer outer loops */
        b = a;
        a = xch;
    }

    MP_USED(c) = 1;
    MP_DIGIT(c, 0) = 0;
    ib = (MP_USED(&mmm->N) << 1) + 1;
    if ((res = s_mp_pad(c, ib)) != MP_OKAY)
        goto CLEANUP;

    useda = MP_USED(a);
    pb = MP_DIGITS(b);
    s_mpv_mul_d(MP_DIGITS(a), useda, *pb++, MP_DIGITS(c));
    s_mp_setz(MP_DIGITS(c) + useda + 1, ib - (useda + 1));
    m_i = MP_DIGIT(c, 0) * mmm->n0prime;
    s_mp_mul_d_add_offset(&mmm->N, m_i, c, 0);

    /* Outer loop:  Digits of b */
    usedb = MP_USED(b);
    for (ib = 1; ib < usedb; ib++) {
        mp_digit b_i = *pb++;

        /* Inner product:  Digits of a */
        if (b_i)
            s_mpv_mul_d_add_prop(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
        m_i = MP_DIGIT(c, ib) * mmm->n0prime;
        s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib);
    }
    if (usedb < MP_USED(&mmm->N)) {
        for (usedb = MP_USED(&mmm->N); ib < usedb; ++ib) {
            m_i = MP_DIGIT(c, ib) * mmm->n0prime;
            s_mp_mul_d_add_offset(&mmm->N, m_i, c, ib);
        }
    }
    s_mp_clamp(c);
    s_mp_rshd(c, MP_USED(&mmm->N)); /* c /= R */
    if (s_mp_cmp(c, &mmm->N) >= 0) {
        MP_CHECKOK(s_mp_sub(c, &mmm->N));
    }
    res = MP_OKAY;

CLEANUP:
    return res;
}
Example #25
0
/* Converts a point P(px, py, pz) from Jacobian projective coordinates to
 * affine coordinates R(rx, ry).  P and R can share x and y coordinates.
 * Assumes input is already field-encoded using field_enc, and returns
 * output that is still field-encoded. */
mp_err
ec_GFp_pt_jac2aff(const mp_int *px, const mp_int *py, const mp_int *pz,
				  mp_int *rx, mp_int *ry, const ECGroup *group)
{
	mp_err res = MP_OKAY;
	mp_int z1, z2, z3;

	MP_DIGITS(&z1) = 0;
	MP_DIGITS(&z2) = 0;
	MP_DIGITS(&z3) = 0;
	MP_CHECKOK(mp_init(&z1));
	MP_CHECKOK(mp_init(&z2));
	MP_CHECKOK(mp_init(&z3));

	/* if point at infinity, then set point at infinity and exit */
	if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
		MP_CHECKOK(ec_GFp_pt_set_inf_aff(rx, ry));
		goto CLEANUP;
	}

	/* transform (px, py, pz) into (px / pz^2, py / pz^3) */
	if (mp_cmp_d(pz, 1) == 0) {
		MP_CHECKOK(mp_copy(px, rx));
		MP_CHECKOK(mp_copy(py, ry));
	} else {
		MP_CHECKOK(group->meth->field_div(NULL, pz, &z1, group->meth));
		MP_CHECKOK(group->meth->field_sqr(&z1, &z2, group->meth));
		MP_CHECKOK(group->meth->field_mul(&z1, &z2, &z3, group->meth));
		MP_CHECKOK(group->meth->field_mul(px, &z2, rx, group->meth));
		MP_CHECKOK(group->meth->field_mul(py, &z3, ry, group->meth));
	}

  CLEANUP:
	mp_clear(&z1);
	mp_clear(&z2);
	mp_clear(&z3);
	return res;
}
Example #26
0
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;
}
Example #27
0
static SECStatus
init_blinding_params(struct RSABlindingParamsStr *rsabp, RSAPrivateKey *key,
                     mp_int *n, unsigned int modLen)
{
    SECStatus rv = SECSuccess;
    mp_err err = MP_OKAY;
    MP_DIGITS(&rsabp->f) = 0;
    MP_DIGITS(&rsabp->g) = 0;
    /* initialize blinding parameters */
    CHECK_MPI_OK( mp_init(&rsabp->f) );
    CHECK_MPI_OK( mp_init(&rsabp->g) );
    /* List elements are keyed using the modulus */
    SECITEM_CopyItem(NULL, &rsabp->modulus, &key->modulus);
    CHECK_SEC_OK( generate_blinding_params(rsabp, key, n, modLen) );
    return SECSuccess;
cleanup:
    mp_clear(&rsabp->f);
    mp_clear(&rsabp->g);
    if (err) {
	MP_TO_SEC_ERROR(err);
	rv = SECFailure;
    }
    return rv;
}
Example #28
0
/* Tests point doubling in Chudnovsky Jacobian coordinates */
mp_err
testPointDoubleChud(ECGroup *ecgroup)
{
	mp_err res;
	mp_int px, py, pz, rx2, ry2, rz2;
	ecfp_aff_pt p;
	ecfp_chud_pt p2;
	EC_group_fp *group = (EC_group_fp *) ecgroup->extra1;

	MP_DIGITS(&rx2) = 0;
	MP_DIGITS(&ry2) = 0;
	MP_DIGITS(&rz2) = 0;
	MP_DIGITS(&px) = 0;
	MP_DIGITS(&py) = 0;
	MP_DIGITS(&pz) = 0;

	MP_CHECKOK(mp_init(&rx2));
	MP_CHECKOK(mp_init(&ry2));
	MP_CHECKOK(mp_init(&rz2));
	MP_CHECKOK(mp_init(&px));
	MP_CHECKOK(mp_init(&py));
	MP_CHECKOK(mp_init(&pz));

	/* Set p2 = 2P */
	ecfp_i2fp(p.x, &ecgroup->genx, ecgroup);
	ecfp_i2fp(p.y, &ecgroup->geny, ecgroup);
	ecfp_i2fp(group->curvea, &ecgroup->curvea, ecgroup);

	group->pt_dbl_aff2chud(&p, &p2, group);

	/* Calculate doubling to compare against */
	MP_CHECKOK(mp_set_int(&pz, 1));
	ec_GFp_pt_dbl_jac(&ecgroup->genx, &ecgroup->geny, &pz, &rx2, &ry2,
					  &rz2, ecgroup);
	ec_GFp_pt_jac2aff(&rx2, &ry2, &rz2, &rx2, &ry2, ecgroup);

	/* Do comparison and check az^4 */
	MP_CHECKOK(testChudPoint(&p2, &rx2, &ry2, ecgroup));

  CLEANUP:
	if (res == MP_OKAY)
		printf("  Test Passed - Point Doubling - Chudnovsky Jacobian\n");
	else
		printf("TEST FAILED - Point Doubling - Chudnovsky Jacobian\n");

	mp_clear(&rx2);
	mp_clear(&ry2);
	mp_clear(&rz2);
	mp_clear(&px);
	mp_clear(&py);
	mp_clear(&pz);

	return res;
}
Example #29
0
/* Reverse the operation above for one mp_int.
 * Reconstruct one mp_int from its column in the weaved array.
 * "pSrc" points to the offset into the weave array of the bignum we 
 * are going to reconstruct.
 */
mp_err weave_to_mpi(mp_int *a,                /* output, result */
                    const unsigned char *pSrc, /* input, byte matrix */
		    mp_size nDigits,          /* per mp_int output */
		    mp_size nBignums)         /* bignums in weaved matrix */
{
  unsigned char *pDest   = (unsigned char *)MP_DIGITS(a);
  unsigned char *endDest = pDest + (nDigits * sizeof(mp_digit));

  MP_SIGN(a) = MP_ZPOS;
  MP_USED(a) = nDigits;

  for (; pDest < endDest; pSrc += nBignums, pDest++) {
    *pDest = *pSrc;
  }
  s_mp_clamp(a);
  return MP_OKAY;
}
Example #30
0
/* Computes R = P - Q. Elliptic curve points P, Q, and R can all be
 * identical. Uses affine coordinates. Assumes input is already
 * field-encoded using field_enc, and returns output that is still
 * field-encoded. */
mp_err
ec_GFp_pt_sub_aff(const mp_int *px, const mp_int *py, const mp_int *qx,
                  const mp_int *qy, mp_int *rx, mp_int *ry,
                  const ECGroup *group)
{
    mp_err res = MP_OKAY;
    mp_int nqy;

    MP_DIGITS(&nqy) = 0;
    MP_CHECKOK(mp_init(&nqy));
    /* nqy = -qy */
    MP_CHECKOK(group->meth->field_neg(qy, &nqy, group->meth));
    res = group->point_add(px, py, qx, &nqy, rx, ry, group);
CLEANUP:
    mp_clear(&nqy);
    return res;
}