Beispiel #1
0
/*
	In-memory version of matrixX509ReadPubKey.
	This function was written strictly for clarity in the PeerSec crypto API
	subset.  It extracts only the public key from a certificate file for use
	in the lower level encrypt/decrypt RSA routines.
*/
int32 matrixX509ParsePubKey(psPool_t *pool, unsigned char *certBuf,
							int32 certLen, sslRsaKey_t **key)
{
	sslRsaKey_t		*lkey;
	sslRsaCert_t	*certStruct;
	int32			err;

	if (matrixX509ParseCert(pool, certBuf, certLen, &certStruct) < 0) {
		matrixX509FreeCert(certStruct);
		return -1;
	}
	lkey = *key = psMalloc(pool, sizeof(sslRsaKey_t));
	memset(lkey, 0x0, sizeof(sslRsaKey_t));

	if ((err = _mp_init_multi(pool, &lkey->e, &lkey->N, NULL,
			NULL, NULL,	NULL, NULL,	NULL)) != MP_OKAY) {
		matrixX509FreeCert(certStruct);
		psFree(lkey);
		return err;
	}
	mp_copy(&certStruct->publicKey.e, &lkey->e);
	mp_copy(&certStruct->publicKey.N, &lkey->N);

	mp_shrink(&lkey->e);
	mp_shrink(&lkey->N);

	lkey->size = certStruct->publicKey.size;

	matrixX509FreeCert(certStruct);

	return 0;
}
Beispiel #2
0
/* calc a value mod 2^b */
int
mp_mod_2d (mp_int * a, int b, mp_int * c)
{
    int     x, res;


    /* if b is <= 0 then zero the int */
    if (b <= 0) {
        mp_zero (c);
        return MP_OKAY;
    }

    /* if the modulus is larger than the value than return */
    if (b > (int) (a->used * DIGIT_BIT)) {
        res = mp_copy (a, c);
        return res;
    }

    /* copy */
    if ((res = mp_copy (a, c)) != MP_OKAY) {
        return res;
    }

    /* zero digits above the last digit of the modulus */
    for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
        c->dp[x] = 0;
    }
    /* clear the digit that is not completely outside/inside the modulus */
    c->dp[b / DIGIT_BIT] &=
        (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
    mp_clamp (c);
    return MP_OKAY;
}
Beispiel #3
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;
}
Beispiel #4
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 rsa_verify(RSAKey *key)
{
    mp_int *n, *ed, *pm1, *qm1;
    unsigned ok = 1;

    /* Preliminary checks: p,q must actually be nonzero. */
    if (mp_eq_integer(key->p, 0) | mp_eq_integer(key->q, 0))
        return false;

    /* n must equal pq. */
    n = mp_mul(key->p, key->q);
    ok &= mp_cmp_eq(n, key->modulus);
    mp_free(n);

    /* e * d must be congruent to 1, modulo (p-1) and modulo (q-1). */
    pm1 = mp_copy(key->p);
    mp_sub_integer_into(pm1, pm1, 1);
    ed = mp_modmul(key->exponent, key->private_exponent, pm1);
    mp_free(pm1);
    ok &= mp_eq_integer(ed, 1);
    mp_free(ed);

    qm1 = mp_copy(key->q);
    mp_sub_integer_into(qm1, qm1, 1);
    ed = mp_modmul(key->exponent, key->private_exponent, qm1);
    mp_free(qm1);
    ok &= mp_eq_integer(ed, 1);
    mp_free(ed);

    /*
     * Ensure p > q.
     *
     * I have seen key blobs in the wild which were generated with
     * p < q, so instead of rejecting the key in this case we
     * should instead flip them round into the canonical order of
     * p > q. This also involves regenerating iqmp.
     */
    mp_int *p_new = mp_max(key->p, key->q);
    mp_int *q_new = mp_min(key->p, key->q);
    mp_free(key->p);
    mp_free(key->q);
    mp_free(key->iqmp);
    key->p = p_new;
    key->q = q_new;
    key->iqmp = mp_invert(key->q, key->p);

    return ok;
}
Beispiel #5
0
static void two_complement_bitop(mp_int *a, mp_int *b, mp_int *c,
        int (*mp_bitop)(mp_int *, mp_int *, mp_int *)) {
    mp_int d;
    if (SIGN(a) ^ SIGN(b)) {
        /* exactly one of them is negative, so need to perform
         * some magic. tommath stores a sign bit, but Perl 6 expects
         * 2's complement */
        mp_init(&d);
        if (MP_NEG == SIGN(a)) {
            grow_and_negate(a, USED(b), &d);
            mp_bitop(&d, b, c);
        } else {
            grow_and_negate(b, USED(a), &d);
            mp_bitop(a, &d, c);
        }
        if (DIGIT(c, USED(c) - 1) & ((mp_digit)1<<(mp_digit)(DIGIT_BIT - 1))) {
            grow_and_negate(c, c->used, &d);
            mp_copy(&d, c);
            mp_neg(c, c);
        }
        mp_clear(&d);
    } else {
        mp_bitop(a, b, c);
    }

}
Beispiel #6
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;
}
Beispiel #7
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;
}
Beispiel #8
0
void
mpi_rshift(const mpi *p, unsigned bits, mpi *q)
{
    if (!bits)
        return;

    const unsigned digits = bits / MP_DIGIT_BITS;
    bits %= MP_DIGIT_BITS;

    const unsigned pbits = mpi_significant_bits(p);
    if (pbits <= bits) {
        mpi_zero(q);
        return;
    }

    if (p == q) {
        if (digits) {
            q->size -= digits;
            mp_copy(q->digits + digits, q->size, q->digits);
        }
        mp_rshifti(q->digits, q->size, bits);
    } else {
        const mp_size qsize = p->size - digits;
        MPI_SIZE(q, qsize);
        mp_rshift(p->digits + digits, qsize, bits, q->digits);
    }
    q->size -= (q->digits[q->size - 1] == 0);
    ASSERT(q->size != 0);
}
Beispiel #9
0
void
mpi_mul(const mpi *a, const mpi *b, mpi *c)
{
    if (a->size == 0 || b->size == 0) {
        mpi_zero(c);
        return;
    }

    if (a == b) {
        mpi_sqr(a, c);
        return;
    }

    mp_size csize = a->size + b->size;
    if (a == c || b == c) {
        mp_digit *prod = MP_TMP_ALLOC(csize);
        mp_mul(a->digits, a->size, b->digits, b->size, prod);
        csize -= (prod[csize - 1] == 0);
        MPI_SIZE(c, csize);
        mp_copy(prod, csize, c->digits);
        MP_TMP_FREE(prod);
    } else {
        ASSERT(a->digits[a->size - 1] != 0);
        ASSERT(b->digits[b->size - 1] != 0);
        MPI_MIN_ALLOC(c, csize);
        mp_mul(a->digits, a->size, b->digits, b->size, c->digits);
        c->size = csize - (c->digits[csize - 1] == 0);
    }
    c->sign = a->sign ^ b->sign;
}
Beispiel #10
0
void
mpi_div(const mpi *a, const mpi *b, mpi *q)
{
    mp_size qsize;

    ASSERT(b->size != 0);

    if (a->size == 0 ||
            a->size < b->size) {
        mpi_zero(q);
        return;
    }
    if (a == b) {
        mpi_set_u32(q, 1);
        return;
    }

    qsize = a->size - b->size + 1;
    if (a == q || b == q) {
        mp_digit *quot = MP_TMP_ALLOC(qsize);
        mp_div(a->digits, a->size,
               b->digits, b->size, quot);
        qsize -= (quot[qsize - 1] == 0);
        MPI_SIZE(q, qsize);
        mp_copy(quot, qsize, q->digits);
        MP_TMP_FREE(quot);
    } else {
        MPI_MIN_ALLOC(q, qsize);
        mp_div(a->digits, a->size,
               b->digits, b->size, q->digits);
        MP_NORMALIZE(q->digits, q->size);
    }
    q->sign = a->sign ^ b->sign;
}
Beispiel #11
0
/* sets given mp_int p,q as the numerator,denominator in mp_rat a */
int mpq_set(mp_rat * a, mp_int * p, mp_int * q)
{
    int e;

    if ((e = mp_copy(p, &a->numerator)) != MP_OKAY) {
	return e;
    }
    if ((e = mp_copy(q, &a->denominator)) != MP_OKAY) {
	return e;
    }
    mpq_normalize_sign(a);
    if ((e = mpq_reduce(a)) != MP_OKAY) {
	return e;
    }
    return MP_OKAY;
}
Beispiel #12
0
void
mpi_divexact(const mpi *a, const mpi *b, mpi *q)
{
    ASSERT(b->size != 0);

    if (a->size == 0 ||
            a->size < b->size) {
        /* FIXME: raise an error here? */
        mpi_zero(q);
        return;
    }
    if (a == b) {
        mpi_set_u32(q, 1);
        return;
    }

    mp_size qsize = a->size - b->size + 1;
    if (a == q || b == q) {
        mp_digit *quot = MP_TMP_ALLOC(qsize);
        mp_divexact(a->digits, a->size,
                    b->digits, b->size, quot);
        MP_NORMALIZE(quot, qsize);
        MPI_SIZE(q, qsize);
        mp_copy(quot, qsize, q->digits);
        MP_TMP_FREE(quot);
    } else {
        MPI_MIN_ALLOC(q, qsize);
        mp_divexact(a->digits, a->size,
                    b->digits, b->size, q->digits);
        MP_NORMALIZE(q->digits, qsize);
    }
    q->size = qsize;
    q->sign = a->sign ^ b->sign;
}
int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
{
   mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
   int err;

   if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
      return err;
   }

   /* initialize, (u1,u2,u3) = (1,0,a) */
   mp_set(&u1, 1);
   if ((err = mp_copy(a, &u3)) != MP_OKAY)                                        { goto _ERR; }

   /* initialize, (v1,v2,v3) = (0,1,b) */
   mp_set(&v2, 1);
   if ((err = mp_copy(b, &v3)) != MP_OKAY)                                        { goto _ERR; }

   /* loop while v3 != 0 */
   while (mp_iszero(&v3) == MP_NO) {
       /* q = u3/v3 */
       if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY)                         { goto _ERR; }

       /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
       if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY)                              { goto _ERR; }
       if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY)                             { goto _ERR; }
       if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY)                              { goto _ERR; }
       if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY)                             { goto _ERR; }
       if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY)                              { goto _ERR; }
       if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY)                             { goto _ERR; }

       /* (u1,u2,u3) = (v1,v2,v3) */
       if ((err = mp_copy(&v1, &u1)) != MP_OKAY)                                  { goto _ERR; }
       if ((err = mp_copy(&v2, &u2)) != MP_OKAY)                                  { goto _ERR; }
       if ((err = mp_copy(&v3, &u3)) != MP_OKAY)                                  { goto _ERR; }

       /* (v1,v2,v3) = (t1,t2,t3) */
       if ((err = mp_copy(&t1, &v1)) != MP_OKAY)                                  { goto _ERR; }
       if ((err = mp_copy(&t2, &v2)) != MP_OKAY)                                  { goto _ERR; }
       if ((err = mp_copy(&t3, &v3)) != MP_OKAY)                                  { goto _ERR; }
   }

   /* make sure U3 >= 0 */
   if (u3.sign == MP_NEG) {
      mp_neg(&u1, &u1);
      mp_neg(&u2, &u2);
      mp_neg(&u3, &u3);
   }

   /* copy result out */
   if (U1 != NULL) { mp_exch(U1, &u1); }
   if (U2 != NULL) { mp_exch(U2, &u2); }
   if (U3 != NULL) { mp_exch(U3, &u3); }

   err = MP_OKAY;
_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
   return err;
}
Beispiel #14
0
static void initialise_common(
    struct ec_curve *curve, EllipticCurveType type, mp_int *p)
{
    curve->type = type;
    curve->p = mp_copy(p);
    curve->fieldBits = mp_get_nbits(p);
    curve->fieldBytes = (curve->fieldBits + 7) / 8;
}
Beispiel #15
0
void
mpi_mul_u64(const mpi *a, uint64_t b, mpi *p)
{
    if (mpi_is_zero(a) || b == 0) {
        mpi_zero(p);
        return;
    } else if (b == 1) {
        if (a != p)
            mpi_set_mpi(p, a);
        return;
    } else if ((b & (b-1)) == 0) {	/* B is a power of 2 */
        mpi_lshift(a, __builtin_ctzll(b), p);
        return;
    } else if (b == (mp_digit)b) {	/* B fits in an mp_digit */
        if (a == p) {
            mp_digit cy = mp_dmuli(p->digits, p->size, (mp_digit)b);
            if (cy) {
                MPI_MIN_ALLOC(p, p->size + 1);
                p->digits[p->size++] = cy;
            }
        } else {
            MPI_MIN_ALLOC(p, a->size);
            mp_digit cy = mp_dmul(a->digits, a->size, (mp_digit)b, p->digits);
            if (cy) {
                MPI_MIN_ALLOC(p, a->size + 1);
                p->digits[a->size] = cy;
                p->size = a->size + 1;
            } else {
                p->size = a->size;
            }
        }
    } else {
        unsigned bits = CHAR_BIT * sizeof(uint64_t) - __builtin_clzll(b);
        mp_size size = (bits + MP_DIGIT_BITS - 1) / MP_DIGIT_BITS;
        mp_digit *bp = MP_TMP_ALLOC(size);
#if MP_DIGIT_BITS >= 64
        bp[0] = b;
#else
        for (mp_size j=0; j<size; j++) {
            bp[j] = (mp_digit)b;
            b >>= MP_DIGIT_BITS;
        }
#endif
        if (a == p) {
            mp_digit *tmp = MP_TMP_ALLOC(p->size + size);
            mp_mul(p->digits, p->size, bp, size, tmp);
            MPI_MIN_ALLOC(p, p->size + size);
            mp_copy(tmp, p->size + size, p->digits);
            p->size = mp_rsize(p->digits, p->size + size);
            MP_TMP_FREE(tmp);
        } else {
            MPI_MIN_ALLOC(p, a->size + size);
            mp_mul(a->digits, a->size, bp, size, p->digits);
            p->size = mp_rsize(p->digits, a->size + size);
        }
        MP_TMP_FREE(bp);
    }
}
Beispiel #16
0
/* Negates a field element. Note that for binary polynomial fields, the
 * negation of a field element is the field element itself. */
mp_err
ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth)
{
    if (a == r) {
        return MP_OKAY;
    } else {
        return mp_copy(a, r);
    }
}
/* creates "a" then copies b into it */
int mp_init_copy (mp_int * a, mp_int * b)
{
  int     res;

  if ((res = mp_init_size (a, b->used)) != MP_OKAY) {
    return res;
  }
  return mp_copy (b, a);
}
Beispiel #18
0
/* creates "a" then copies b into it */
int mp_init_copy (mp_int * a, mp_int * b)
{
    int     res;

    if ((res = mp_init (a)) != MP_OKAY) {
        return res;
    }
    return mp_copy (b, a);
}
Beispiel #19
0
/*-------------------------------------------------------------------*/
static void convert_to_integer(gmp_poly_t *alg_sqrt, mp_t *n,
				mp_t *c, signed_mp_t *m1, 
				signed_mp_t *m0, mp_t *res) {

	/* given the completed square root, apply the homomorphism
	   to convert the polynomial to an integer. We do this
	   by evaluating alg_sqrt at c*m0/m1, with all calculations
	   performed mod n */

	uint32 i;
	mpz_t gmp_n;
	mp_t m1_pow;
	mp_t m1_tmp;
	mp_t m0_tmp;
	mp_t next_coeff;

	mpz_init(gmp_n); 
	mp2gmp(n, gmp_n);
	gmp_poly_mod_q(alg_sqrt, gmp_n, alg_sqrt);
	mpz_clear(gmp_n);

	mp_copy(&m1->num, &m1_tmp);
	if (m1->sign == NEGATIVE)
		mp_sub(n, &m1_tmp, &m1_tmp);
	mp_copy(&m1_tmp, &m1_pow);

	mp_modmul(&m0->num, c, n, &m0_tmp);
	if (m0->sign == POSITIVE)
		mp_sub(n, &m0_tmp, &m0_tmp);

	i = alg_sqrt->degree;
	gmp2mp(alg_sqrt->coeff[i], res);

	for (i--; (int32)i >= 0; i--) {
		mp_modmul(res, &m0_tmp, n, res);
		gmp2mp(alg_sqrt->coeff[i], &next_coeff);
		mp_modmul(&next_coeff, &m1_pow, n, &next_coeff);
		mp_add(res, &next_coeff, res);
		if (i > 0)
			mp_modmul(&m1_pow, &m1_tmp, n, &m1_pow);
	}
	if (mp_cmp(res, n) > 0)
		mp_sub(res, n, res);
}
Beispiel #20
0
/* Converts a point P(px, py) from affine coordinates to Jacobian
 * projective coordinates R(rx, ry, rz). Assumes input is already
 * field-encoded using field_enc, and returns output that is still
 * field-encoded. */
mp_err
ec_GFp_pt_aff2jac(const mp_int *px, const mp_int *py, mp_int *rx,
				  mp_int *ry, mp_int *rz, const ECGroup *group)
{
	mp_err res = MP_OKAY;

	if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
		MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
	} else {
		MP_CHECKOK(mp_copy(px, rx));
		MP_CHECKOK(mp_copy(py, ry));
		MP_CHECKOK(mp_set_int(rz, 1));
		if (group->meth->field_enc) {
			MP_CHECKOK(group->meth->field_enc(rz, rz, group->meth));
		}
	}
  CLEANUP:
	return res;
}
Beispiel #21
0
/* Construct a generic GFMethod for arithmetic over prime fields with
 * irreducible irr. */
GFMethod *
GFMethod_consGFp(const mp_int *irr)
{
    mp_err res = MP_OKAY;
    GFMethod *meth = NULL;

    meth = GFMethod_new();
    if (meth == NULL)
        return NULL;

    MP_CHECKOK(mp_copy(irr, &meth->irr));
    meth->irr_arr[0] = mpl_significant_bits(irr);
    meth->irr_arr[1] = meth->irr_arr[2] = meth->irr_arr[3] =
        meth->irr_arr[4] = 0;
    switch (MP_USED(&meth->irr)) {
        /* maybe we need 1 and 2 words here as well?*/
        case 3:
            meth->field_add = &ec_GFp_add_3;
            meth->field_sub = &ec_GFp_sub_3;
            break;
        case 4:
            meth->field_add = &ec_GFp_add_4;
            meth->field_sub = &ec_GFp_sub_4;
            break;
        case 5:
            meth->field_add = &ec_GFp_add_5;
            meth->field_sub = &ec_GFp_sub_5;
            break;
        case 6:
            meth->field_add = &ec_GFp_add_6;
            meth->field_sub = &ec_GFp_sub_6;
            break;
        default:
            meth->field_add = &ec_GFp_add;
            meth->field_sub = &ec_GFp_sub;
    }
    meth->field_neg = &ec_GFp_neg;
    meth->field_mod = &ec_GFp_mod;
    meth->field_mul = &ec_GFp_mul;
    meth->field_sqr = &ec_GFp_sqr;
    meth->field_div = &ec_GFp_div;
    meth->field_enc = NULL;
    meth->field_dec = NULL;
    meth->extra1 = NULL;
    meth->extra2 = NULL;
    meth->extra_free = NULL;

CLEANUP:
    if (res != MP_OKAY) {
        GFMethod_free(meth);
        return NULL;
    }
    return meth;
}
Beispiel #22
0
static void initialise_wcurve(
    struct ec_curve *curve, mp_int *p, mp_int *a, mp_int *b,
    mp_int *nonsquare, mp_int *G_x, mp_int *G_y, mp_int *G_order)
{
    initialise_common(curve, EC_WEIERSTRASS, p);

    curve->w.wc = ecc_weierstrass_curve(p, a, b, nonsquare);

    curve->w.G = ecc_weierstrass_point_new(curve->w.wc, G_x, G_y);
    curve->w.G_order = mp_copy(G_order);
}
Beispiel #23
0
static void initialise_ecurve(
    struct ec_curve *curve, mp_int *p, mp_int *d, mp_int *a,
    mp_int *nonsquare, mp_int *G_x, mp_int *G_y, mp_int *G_order)
{
    initialise_common(curve, EC_EDWARDS, p);

    curve->e.ec = ecc_edwards_curve(p, d, a, nonsquare);

    curve->e.G = ecc_edwards_point_new(curve->e.ec, G_x, G_y);
    curve->e.G_order = mp_copy(G_order);
}
Beispiel #24
0
STATIC
mp_err s_mp_to_mont(const mp_int *x, mp_mont_modulus *mmm, mp_int *xMont)
{
  mp_err res;

  /* xMont = x * R mod N   where  N is modulus */
  MP_CHECKOK( mp_copy( x, xMont ) );
  MP_CHECKOK( s_mp_lshd( xMont, MP_USED(&mmm->N) ) );	/* xMont = x << b */
  MP_CHECKOK( mp_div(xMont, &mmm->N, 0, xMont) );	/*         mod N */
CLEANUP:
  return res;
}
Beispiel #25
0
/* Decode a field element from Montgomery form. */
mp_err
ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth)
{
	mp_err res = MP_OKAY;

	if (a != r) {
		MP_CHECKOK(mp_copy(a, r));
	}
	MP_CHECKOK(s_mp_redc(r, (mp_mont_modulus *) meth->extra1));
  CLEANUP:
	return res;
}
Beispiel #26
0
/* sets given mp_int b as the numerator in mp_rat a */
int mpq_set_num(mp_rat * a, mp_int * b)
{
    int e;

    if ((e = mp_copy(b, &a->numerator)) != MP_OKAY) {
	return e;
    }
    mpq_normalize_sign(a);
    if ((e = mpq_reduce(a)) != MP_OKAY) {
	return e;
    }
    return MP_OKAY;
}
Beispiel #27
0
/* Construct a generic ECGroup for elliptic curves over binary polynomial
 * fields. */
ECGroup *
ECGroup_consGF2m(const mp_int *irr, const unsigned int irr_arr[5],
                 const mp_int *curvea, const mp_int *curveb,
                 const mp_int *genx, const mp_int *geny,
                 const mp_int *order, int cofactor)
{
    mp_err res = MP_OKAY;
    ECGroup *group = NULL;

    group = ECGroup_new();
    if (group == NULL)
        return NULL;

    group->meth = GFMethod_consGF2m(irr, irr_arr);
    if (group->meth == NULL) {
        res = MP_MEM;
        goto CLEANUP;
    }
    MP_CHECKOK(mp_copy(curvea, &group->curvea));
    MP_CHECKOK(mp_copy(curveb, &group->curveb));
    MP_CHECKOK(mp_copy(genx, &group->genx));
    MP_CHECKOK(mp_copy(geny, &group->geny));
    MP_CHECKOK(mp_copy(order, &group->order));
    group->cofactor = cofactor;
    group->point_add = &ec_GF2m_pt_add_aff;
    group->point_sub = &ec_GF2m_pt_sub_aff;
    group->point_dbl = &ec_GF2m_pt_dbl_aff;
    group->point_mul = &ec_GF2m_pt_mul_mont;
    group->base_point_mul = NULL;
    group->points_mul = &ec_pts_mul_basic;
    group->validate_point = &ec_GF2m_validate_point;

CLEANUP:
    if (res != MP_OKAY) {
        ECGroup_free(group);
        return NULL;
    }
    return group;
}
Beispiel #28
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;
}
Beispiel #29
0
/* b = |a| 
 *
 * Simple function copies the input and fixes the sign to positive
 */
int mp_abs(mp_int * a, mp_int * b)
{
	int res;

	/* copy a to b */
	if (a != b) {
		if ((res = mp_copy(a, b)) != MP_OKAY) {
			return res;
		}
	}

	/* force the sign of b to positive */
	b->sign = MP_ZPOS;

	return MP_OKAY;
}
Beispiel #30
0
void
mpi_set_mpi(mpi *p, const mpi *q)
{
    ASSERT(p != NULL);
    ASSERT(q != NULL);

    if (p != q) {
        if (q->size == 0) {
            mpi_zero(p);
        } else {
            MPI_SIZE(p, q->size);
            mp_copy(q->digits, q->size, p->digits);
            p->sign = q->sign;
        }
    }
}