Merge branch 'keycomp'

This commit is contained in:
toddouska
2014-08-29 14:34:44 -07:00
13 changed files with 602 additions and 109 deletions

View File

@@ -65,6 +65,7 @@ const ecc_set_type ecc_sets[] = {
14,
"SECP112R1",
"DB7C2ABF62E35E668076BEAD208B",
"DB7C2ABF62E35E668076BEAD2088",
"659EF8BA043916EEDE8911702B22",
"DB7C2ABF62E35E7628DFAC6561C5",
"09487239995A5EE76B55F9C2F098",
@@ -76,6 +77,7 @@ const ecc_set_type ecc_sets[] = {
16,
"SECP128R1",
"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
"FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
"E87579C11079F43DD824993C2CEE5ED3",
"FFFFFFFE0000000075A30D1B9038A115",
"161FF7528B899B2D0C28607CA52C5B86",
@@ -87,6 +89,7 @@ const ecc_set_type ecc_sets[] = {
20,
"SECP160R1",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
"1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
"0100000000000000000001F4C8F927AED3CA752257",
"4A96B5688EF573284664698968C38BB913CBFC82",
@@ -98,6 +101,7 @@ const ecc_set_type ecc_sets[] = {
24,
"ECC-192",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
"64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
"FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
"188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
@@ -109,6 +113,7 @@ const ecc_set_type ecc_sets[] = {
28,
"ECC-224",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
"B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
"B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
@@ -120,6 +125,7 @@ const ecc_set_type ecc_sets[] = {
32,
"ECC-256",
"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
"6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
@@ -131,6 +137,7 @@ const ecc_set_type ecc_sets[] = {
48,
"ECC-384",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
"B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
"AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
@@ -142,6 +149,7 @@ const ecc_set_type ecc_sets[] = {
66,
"ECC-521",
"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
"51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
"C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
@@ -150,7 +158,7 @@ const ecc_set_type ecc_sets[] = {
#endif
{
0,
NULL, NULL, NULL, NULL, NULL, NULL
NULL, NULL, NULL, NULL, NULL, NULL, NULL
}
};
@@ -169,6 +177,13 @@ static int ecc_mul2add(ecc_point* A, mp_int* kA, ecc_point* B, mp_int* kB,
ecc_point* C, mp_int* modulus);
#endif
int mp_jacobi(mp_int* a, mp_int* p, int* c);
int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret);
int mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d);
#ifdef HAVE_COMP_KEY
static int ecc_export_x963_compressed(ecc_key*, byte* out, word32* outLen);
#endif
/* helper for either lib */
static int get_digit_count(mp_int* a)
@@ -2197,10 +2212,26 @@ int ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
}
/* export public ECC key in ANSI X9.63 format, extended with
* compression option */
int ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, int compressed)
{
if (compressed == 0)
return ecc_export_x963(key, out, outLen);
#ifdef HAVE_COMP_KEY
else
return ecc_export_x963_compressed(key, out, outLen);
#endif
return NOT_COMPILED_IN;
}
/* import public ECC key in ANSI X9.63 format */
int ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
{
int x, err;
int compressed = 0;
if (in == NULL || key == NULL)
return ECC_BAD_ARG_E;
@@ -2217,24 +2248,25 @@ int ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
}
err = MP_OKAY;
/* check for 4, 6 or 7 */
if (in[0] != 4 && in[0] != 6 && in[0] != 7) {
/* check for 4, 2, or 3 */
if (in[0] != 0x04 && in[0] != 0x02 && in[0] != 0x03) {
err = ASN_PARSE_E;
}
/* read data */
if (err == MP_OKAY)
err = mp_read_unsigned_bin(&key->pubkey.x, (byte*)in+1, (inLen-1)>>1);
if (err == MP_OKAY)
err = mp_read_unsigned_bin(&key->pubkey.y, (byte*)in+1+((inLen-1)>>1),
(inLen-1)>>1);
if (err == MP_OKAY)
mp_set(&key->pubkey.z, 1);
if (in[0] == 0x02 || in[0] == 0x03) {
#ifdef HAVE_COMP_KEY
compressed = 1;
#else
err = NOT_COMPILED_IN;
#endif
}
if (err == MP_OKAY) {
/* determine the idx */
/* determine the idx */
if (compressed)
inLen = (inLen-1)*2 + 1; /* used uncompressed len */
for (x = 0; ecc_sets[x].size != 0; x++) {
if ((unsigned)ecc_sets[x].size >= ((inLen-1)>>1)) {
break;
@@ -2250,6 +2282,74 @@ int ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
}
}
/* read data */
if (err == MP_OKAY)
err = mp_read_unsigned_bin(&key->pubkey.x, (byte*)in+1, (inLen-1)>>1);
#ifdef HAVE_COMP_KEY
if (err == MP_OKAY && compressed == 1) { /* build y */
mp_int t1, t2, prime, a, b;
if (mp_init_multi(&t1, &t2, &prime, &a, &b, NULL) != MP_OKAY)
err = MEMORY_E;
/* load prime */
if (err == MP_OKAY)
err = mp_read_radix(&prime, (char *)key->dp->prime, 16);
/* load a */
if (err == MP_OKAY)
err = mp_read_radix(&a, (char *)key->dp->Af, 16);
/* load b */
if (err == MP_OKAY)
err = mp_read_radix(&b, (char *)key->dp->Bf, 16);
/* compute x^3 */
if (err == MP_OKAY)
err = mp_sqr(&key->pubkey.x, &t1);
if (err == MP_OKAY)
err = mp_mulmod(&t1, &key->pubkey.x, &prime, &t1);
/* compute x^3 + a*x */
if (err == MP_OKAY)
err = mp_mulmod(&a, &key->pubkey.x, &prime, &t2);
if (err == MP_OKAY)
err = mp_add(&t1, &t2, &t1);
/* compute x^3 + a*x + b */
if (err == MP_OKAY)
err = mp_add(&t1, &b, &t1);
/* compute sqrt(x^3 + a*x + b) */
if (err == MP_OKAY)
err = mp_sqrtmod_prime(&t1, &prime, &t2);
/* adjust y */
if (err == MP_OKAY) {
if ((mp_isodd(&t2) && in[0] == 0x03) ||
(!mp_isodd(&t2) && in[0] == 0x02)) {
err = mp_mod(&t2, &prime, &key->pubkey.y);
}
else {
err = mp_submod(&prime, &t2, &prime, &key->pubkey.y);
}
}
mp_clear(&prime);
mp_clear(&t2);
mp_clear(&t1);
}
#endif
if (err == MP_OKAY && compressed == 0)
err = mp_read_unsigned_bin(&key->pubkey.y, (byte*)in+1+((inLen-1)>>1),
(inLen-1)>>1);
if (err == MP_OKAY)
mp_set(&key->pubkey.z, 1);
if (err != MP_OKAY) {
mp_clear(&key->pubkey.x);
mp_clear(&key->pubkey.y);
@@ -4424,4 +4524,308 @@ int ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
#endif /* HAVE_ECC_ENCRYPT */
#ifdef HAVE_COMP_KEY
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
* HAC pp. 73 Algorithm 2.149
*/
int mp_jacobi(mp_int* a, mp_int* p, int* c)
{
mp_int a1, p1;
int k, s, r, res;
mp_digit residue;
/* if p <= 0 return MP_VAL */
if (mp_cmp_d(p, 0) != MP_GT) {
return MP_VAL;
}
/* step 1. if a == 0, return 0 */
if (mp_iszero (a) == 1) {
*c = 0;
return MP_OKAY;
}
/* step 2. if a == 1, return 1 */
if (mp_cmp_d (a, 1) == MP_EQ) {
*c = 1;
return MP_OKAY;
}
/* default */
s = 0;
/* step 3. write a = a1 * 2**k */
if ((res = mp_init_copy (&a1, a)) != MP_OKAY) {
return res;
}
if ((res = mp_init (&p1)) != MP_OKAY) {
mp_clear(&a1);
return res;
}
/* divide out larger power of two */
k = mp_cnt_lsb(&a1);
res = mp_div_2d(&a1, k, &a1, NULL);
if (res == MP_OKAY) {
/* step 4. if e is even set s=1 */
if ((k & 1) == 0) {
s = 1;
} else {
/* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
residue = p->dp[0] & 7;
if (residue == 1 || residue == 7) {
s = 1;
} else if (residue == 3 || residue == 5) {
s = -1;
}
}
/* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) {
s = -s;
}
}
if (res == MP_OKAY) {
/* if a1 == 1 we're done */
if (mp_cmp_d (&a1, 1) == MP_EQ) {
*c = s;
} else {
/* n1 = n mod a1 */
res = mp_mod (p, &a1, &p1);
if (res == MP_OKAY)
res = mp_jacobi (&p1, &a1, &r);
if (res == MP_OKAY)
*c = s * r;
}
}
/* done */
mp_clear (&p1);
mp_clear (&a1);
return res;
}
int mp_sqrtmod_prime(mp_int* n, mp_int* prime, mp_int* ret)
{
int res, legendre, done = 0;
mp_int t1, C, Q, S, Z, M, T, R, two;
mp_digit i;
/* first handle the simple cases */
if (mp_cmp_d(n, 0) == MP_EQ) {
mp_zero(ret);
return MP_OKAY;
}
if (mp_cmp_d(prime, 2) == MP_EQ) return MP_VAL; /* prime must be odd */
/* TAO removed
if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res;
if (legendre == -1) return MP_VAL; */ /* quadratic non-residue mod prime */
if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M)) != MP_OKAY)
return res;
if ((res = mp_init_multi(&T, &R, &two, NULL, NULL, NULL))
!= MP_OKAY) {
mp_clear(&t1); mp_clear(&C); mp_clear(&Q); mp_clear(&S); mp_clear(&Z);
mp_clear(&M);
return res;
}
/* SPECIAL CASE: if prime mod 4 == 3
* compute directly: res = n^(prime+1)/4 mod prime
* Handbook of Applied Cryptography algorithm 3.36
*/
res = mp_mod_d(prime, 4, &i);
if (res == MP_OKAY && i == 3) {
res = mp_add_d(prime, 1, &t1);
if (res == MP_OKAY)
res = mp_div_2(&t1, &t1);
if (res == MP_OKAY)
res = mp_div_2(&t1, &t1);
if (res == MP_OKAY)
res = mp_exptmod(n, &t1, prime, ret);
done = 1;
}
/* NOW: TonelliShanks algorithm */
if (res == MP_OKAY && done == 0) {
/* factor out powers of 2 from prime-1, defining Q and S
* as: prime-1 = Q*2^S */
res = mp_copy(prime, &Q);
if (res == MP_OKAY)
res = mp_sub_d(&Q, 1, &Q);
/* Q = prime - 1 */
if (res == MP_OKAY)
mp_zero(&S);
/* S = 0 */
while (res == MP_OKAY && mp_iseven(&Q)) {
res = mp_div_2(&Q, &Q);
/* Q = Q / 2 */
if (res == MP_OKAY)
res = mp_add_d(&S, 1, &S);
/* S = S + 1 */
}
/* find a Z such that the Legendre symbol (Z|prime) == -1 */
if (res == MP_OKAY)
res = mp_set_int(&Z, 2);
/* Z = 2 */
while (res == MP_OKAY) {
res = mp_jacobi(&Z, prime, &legendre);
if (legendre == -1)
break;
if (res == MP_OKAY)
res = mp_add_d(&Z, 1, &Z);
/* Z = Z + 1 */
}
if (res == MP_OKAY)
res = mp_exptmod(&Z, &Q, prime, &C);
/* C = Z ^ Q mod prime */
if (res == MP_OKAY)
res = mp_add_d(&Q, 1, &t1);
if (res == MP_OKAY)
res = mp_div_2(&t1, &t1);
/* t1 = (Q + 1) / 2 */
if (res == MP_OKAY)
res = mp_exptmod(n, &t1, prime, &R);
/* R = n ^ ((Q + 1) / 2) mod prime */
if (res == MP_OKAY)
res = mp_exptmod(n, &Q, prime, &T);
/* T = n ^ Q mod prime */
if (res == MP_OKAY)
res = mp_copy(&S, &M);
/* M = S */
if (res == MP_OKAY)
res = mp_set_int(&two, 2);
if (res == MP_OKAY)
res = MP_VAL;
while (res == MP_OKAY && done == 0) {
res = mp_copy(&T, &t1);
i = 0;
while (res == MP_OKAY) {
if (mp_cmp_d(&t1, 1) == MP_EQ)
break;
res = mp_exptmod(&t1, &two, prime, &t1);
if (res == MP_OKAY)
i++;
}
if (res == MP_OKAY && i == 0) {
mp_copy(&R, ret);
res = MP_OKAY;
done = 1;
}
if (done == 0) {
if (res == MP_OKAY)
res = mp_sub_d(&M, i, &t1);
if (res == MP_OKAY)
res = mp_sub_d(&t1, 1, &t1);
if (res == MP_OKAY)
res = mp_exptmod(&two, &t1, prime, &t1);
/* t1 = 2 ^ (M - i - 1) */
if (res == MP_OKAY)
res = mp_exptmod(&C, &t1, prime, &t1);
/* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
if (res == MP_OKAY)
res = mp_sqrmod(&t1, prime, &C);
/* C = (t1 * t1) mod prime */
if (res == MP_OKAY)
res = mp_mulmod(&R, &t1, prime, &R);
/* R = (R * t1) mod prime */
if (res == MP_OKAY)
res = mp_mulmod(&T, &C, prime, &T);
/* T = (T * C) mod prime */
if (res == MP_OKAY)
mp_set(&M, i);
/* M = i */
}
}
}
/* done */
mp_clear(&t1);
mp_clear(&C);
mp_clear(&Q);
mp_clear(&S);
mp_clear(&Z);
mp_clear(&M);
mp_clear(&T);
mp_clear(&R);
mp_clear(&two);
return res;
}
/* export public ECC key in ANSI X9.63 format compressed */
int ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen)
{
word32 numlen;
int ret = MP_OKAY;
if (key == NULL || out == NULL || outLen == NULL)
return ECC_BAD_ARG_E;
if (ecc_is_valid_idx(key->idx) == 0) {
return ECC_BAD_ARG_E;
}
numlen = key->dp->size;
if (*outLen < (1 + numlen)) {
*outLen = 1 + numlen;
return BUFFER_E;
}
/* store first byte */
out[0] = mp_isodd(&key->pubkey.y) ? 0x03 : 0x02;
/* pad and store x */
XMEMSET(out+1, 0, numlen);
ret = mp_to_unsigned_bin(&key->pubkey.x,
out+1 + (numlen - mp_unsigned_bin_size(&key->pubkey.x)));
*outLen = 1 + numlen;
return ret;
}
/* d = a - b (mod c) */
int mp_submod(mp_int* a, mp_int* b, mp_int* c, mp_int* d)
{
int res;
mp_int t;
if ((res = mp_init (&t)) != MP_OKAY) {
return res;
}
if ((res = mp_sub (a, b, &t)) != MP_OKAY) {
mp_clear (&t);
return res;
}
res = mp_mod (&t, c, d);
mp_clear (&t);
return res;
}
#endif /* HAVE_COMP_KEY */
#endif /* HAVE_ECC */

View File

@@ -3932,9 +3932,41 @@ int mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
#endif /* defined(HAVE_ECC) || !defined(NO_PWDBASED) */
#ifdef CYASSL_KEY_GEN
#if defined(CYASSL_KEY_GEN) || defined(HAVE_COMP_KEY)
static const int lnz[16] = {
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};
/* Counts the number of lsbs which are zero before the first zero bit */
int mp_cnt_lsb(mp_int *a)
{
int x;
mp_digit q, qq;
/* easy out */
if (mp_iszero(a) == 1) {
return 0;
}
/* scan lower digits until non-zero */
for (x = 0; x < a->used && a->dp[x] == 0; x++);
q = a->dp[x];
x *= DIGIT_BIT;
/* now scan this digit until a 1 is found */
if ((q & 1) == 0) {
do {
qq = q & 15;
x += lnz[qq];
q >>= 4;
} while (qq == 0);
}
return x;
}
int mp_cnt_lsb(mp_int *a);
static int s_is_power_of_two(mp_digit b, int *p)
{
@@ -4030,11 +4062,14 @@ static int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
}
static int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
{
return mp_div_d(a, b, NULL, c);
}
#endif /* defined(CYASSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
#ifdef CYASSL_KEY_GEN
const mp_digit ltm_prime_tab[] = {
0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
@@ -4291,37 +4326,6 @@ LBL_T:
}
static const int lnz[16] = {
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};
/* Counts the number of lsbs which are zero before the first zero bit */
int mp_cnt_lsb(mp_int *a)
{
int x;
mp_digit q, qq;
/* easy out */
if (mp_iszero(a) == 1) {
return 0;
}
/* scan lower digits until non-zero */
for (x = 0; x < a->used && a->dp[x] == 0; x++);
q = a->dp[x];
x *= DIGIT_BIT;
/* now scan this digit until a 1 is found */
if ((q & 1) == 0) {
do {
qq = q & 15;
x += lnz[qq];
q >>= 4;
} while (qq == 0);
}
return x;
}
/* Greatest Common Divisor using the binary method */
int mp_gcd (mp_int * a, mp_int * b, mp_int * c)

View File

@@ -2035,34 +2035,40 @@ int mp_montgomery_calc_normalization(mp_int *a, mp_int *b)
#endif /* CYASSL_KEYGEN || HAVE_ECC */
#ifdef CYASSL_KEY_GEN
#if defined(CYASSL_KEY_GEN) || defined(HAVE_COMP_KEY)
void fp_gcd(fp_int *a, fp_int *b, fp_int *c);
void fp_lcm(fp_int *a, fp_int *b, fp_int *c);
int fp_isprime(fp_int *a);
int fp_cnt_lsb(fp_int *a);
static const int lnz[16] = {
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};
int mp_gcd(fp_int *a, fp_int *b, fp_int *c)
/* Counts the number of lsbs which are zero before the first zero bit */
int fp_cnt_lsb(fp_int *a)
{
fp_gcd(a, b, c);
return MP_OKAY;
int x;
fp_digit q, qq;
/* easy out */
if (fp_iszero(a) == 1) {
return 0;
}
/* scan lower digits until non-zero */
for (x = 0; x < a->used && a->dp[x] == 0; x++);
q = a->dp[x];
x *= DIGIT_BIT;
/* now scan this digit until a 1 is found */
if ((q & 1) == 0) {
do {
qq = q & 15;
x += lnz[qq];
q >>= 4;
} while (qq == 0);
}
return x;
}
int mp_lcm(fp_int *a, fp_int *b, fp_int *c)
{
fp_lcm(a, b, c);
return MP_OKAY;
}
int mp_prime_is_prime(mp_int* a, int t, int* result)
{
(void)t;
*result = fp_isprime(a);
return MP_OKAY;
}
static int s_is_power_of_two(fp_digit b, int *p)
@@ -2155,6 +2161,39 @@ static int fp_mod_d(fp_int *a, fp_digit b, fp_digit *c)
return fp_div_d(a, b, NULL, c);
}
int mp_mod_d(fp_int *a, fp_digit b, fp_digit *c)
{
return fp_mod_d(a, b, c);
}
#endif /* defined(CYASSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
#ifdef CYASSL_KEY_GEN
void fp_gcd(fp_int *a, fp_int *b, fp_int *c);
void fp_lcm(fp_int *a, fp_int *b, fp_int *c);
int fp_isprime(fp_int *a);
int mp_gcd(fp_int *a, fp_int *b, fp_int *c)
{
fp_gcd(a, b, c);
return MP_OKAY;
}
int mp_lcm(fp_int *a, fp_int *b, fp_int *c)
{
fp_lcm(a, b, c);
return MP_OKAY;
}
int mp_prime_is_prime(mp_int* a, int t, int* result)
{
(void)t;
*result = fp_isprime(a);
return MP_OKAY;
}
/* Miller-Rabin test of "a" to the base of "b" as described in
* HAC pp. 139 Algorithm 4.24
@@ -2304,37 +2343,6 @@ void fp_lcm(fp_int *a, fp_int *b, fp_int *c)
}
static const int lnz[16] = {
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};
/* Counts the number of lsbs which are zero before the first zero bit */
int fp_cnt_lsb(fp_int *a)
{
int x;
fp_digit q, qq;
/* easy out */
if (fp_iszero(a) == 1) {
return 0;
}
/* scan lower digits until non-zero */
for (x = 0; x < a->used && a->dp[x] == 0; x++);
q = a->dp[x];
x *= DIGIT_BIT;
/* now scan this digit until a 1 is found */
if ((q & 1) == 0) {
do {
qq = q & 15;
x += lnz[qq];
q >>= 4;
} while (qq == 0);
}
return x;
}
/* c = (a, b) */
void fp_gcd(fp_int *a, fp_int *b, fp_int *c)
@@ -2508,6 +2516,22 @@ int mp_init_copy(fp_int * a, fp_int * b)
}
#ifdef HAVE_COMP_KEY
int mp_cnt_lsb(fp_int* a)
{
fp_cnt_lsb(a);
return MP_OKAY;
}
int mp_div_2d(fp_int* a, int b, fp_int* c, fp_int* d)
{
fp_div_2d(a, b, c, d);
return MP_OKAY;
}
#endif /* HAVE_COMP_KEY */
#endif /* HAVE_ECC */