add compressed key support

This commit is contained in:
toddouska 2014-08-29 14:25:58 -07:00
parent b6345d654a
commit 3072edb696
13 changed files with 602 additions and 109 deletions

4
certs/ecc-key-comp.pem Normal file
View File

@ -0,0 +1,4 @@
-----BEGIN EC PRIVATE KEY-----
MFcCAQEEIEW2aQJznGyFoThbcujox6zEA41TNQT6bCjcNI3hqAmMoAoGCCqGSM49
AwEHoSQDIgACuzOsTCdQSsZKpQTDPN6fNttyLc6U6iv6yyAJOSwW6GE=
-----END EC PRIVATE KEY-----

View File

@ -9,6 +9,7 @@ EXTRA_DIST += \
certs/client-keyEnc.pem \
certs/client-key.pem \
certs/ecc-key.pem \
certs/ecc-key-comp.pem \
certs/ecc-keyPkcs8.pem \
certs/ecc-client-key.pem \
certs/client-ecc-cert.pem \
@ -16,6 +17,7 @@ EXTRA_DIST += \
certs/dh2048.pem \
certs/server-cert.pem \
certs/server-ecc.pem \
certs/server-ecc-comp.pem \
certs/server-ecc-rsa.pem \
certs/server-keyEnc.pem \
certs/server-key.pem \

15
certs/server-ecc-comp.pem Normal file
View File

@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICZzCCAg2gAwIBAgIJAOpbhU0jW8ssMAoGCCqGSM49BAMCMIGfMQswCQYDVQQG
EwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHRWRtb25kczEcMBoG
A1UECgwTRWxsaXB0aWMgQ29tcHJlc3NlZDERMA8GA1UECwwIRUNDIENvbXAxGDAW
BgNVBAMMD3d3dy53b2xmc3NsLmNvbTEeMBwGCSqGSIb3DQEJARYPd3d3LndvbGZz
c2wuY29tMB4XDTE0MDgyNzIyNTczOVoXDTE3MDUyMzIyNTczOVowgZ8xCzAJBgNV
BAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdFZG1vbmRzMRww
GgYDVQQKDBNFbGxpcHRpYyBDb21wcmVzc2VkMREwDwYDVQQLDAhFQ0MgQ29tcDEY
MBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR4wHAYJKoZIhvcNAQkBFg93d3cud29s
ZnNzbC5jb20wOTATBgcqhkjOPQIBBggqhkjOPQMBBwMiAAK7M6xMJ1BKxkqlBMM8
3p8223ItzpTqK/rLIAk5LBboYaNQME4wHQYDVR0OBBYEFIw4Omu4JLffbvRZrFZO
quJYploYMB8GA1UdIwQYMBaAFIw4Omu4JLffbvRZrFZOquJYploYMAwGA1UdEwQF
MAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCNYOU7G50eHWoHoaadAXswKrN5Vj6nyh
YUGS3zttSk4CIQD1Abqc61PBUQF6LO4OmBy79zEtWv9PRNH95iJ7V58vXA==
-----END CERTIFICATE-----

View File

@ -123,6 +123,8 @@ openssl dhparam -in dh2048.param -text > dh2048.pem
make a new key
openssl ecparam -genkey -text -name secp256r1 -out ecc-key.pem
convert to compressed
openssl ec -in ecc-key.pem -conv_form compressed -out ecc-key-comp.pem
*** CRL ***

View File

@ -6,7 +6,7 @@
#
#
AC_INIT([cyassl],[3.1.1],[https://github.com/cyassl/cyassl/issues],[cyassl],[http://www.wolfssl.com])
AC_INIT([cyassl],[3.1.2],[https://github.com/cyassl/cyassl/issues],[cyassl],[http://www.wolfssl.com])
AC_CONFIG_AUX_DIR([build-aux])

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);
@ -4315,4 +4415,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 */

View File

@ -4472,8 +4472,32 @@ int ecc_test(void)
return -1008;
if (memcmp(sharedA, sharedB, y))
return -1009;
#ifdef HAVE_COMP_KEY
/* try compressed export / import too */
x = sizeof(exportBuf);
ret = ecc_export_x963_ex(&userA, exportBuf, &x, 1);
if (ret != 0)
return -1010;
ecc_free(&pubKey);
ecc_init(&pubKey);
ret = ecc_import_x963(exportBuf, x, &pubKey);
if (ret != 0)
return -1011;
#endif
y = sizeof(sharedB);
ret = ecc_shared_secret(&userB, &pubKey, sharedB, &y);
if (ret != 0)
return -1012;
if (memcmp(sharedA, sharedB, y))
return -1013;
/* test DSA sign hash */
for (i = 0; i < (int)sizeof(digest); i++)
digest[i] = (byte)i;
@ -4482,21 +4506,21 @@ int ecc_test(void)
ret = ecc_sign_hash(digest, sizeof(digest), sig, &x, &rng, &userA);
if (ret != 0)
return -1016;
return -1014;
verify = 0;
ret = ecc_verify_hash(sig, x, digest, sizeof(digest), &verify, &userA);
if (ret != 0)
return -1011;
return -1015;
if (verify != 1)
return -1012;
return -1016;
x = sizeof(exportBuf);
ret = ecc_export_private_only(&userA, exportBuf, &x);
if (ret != 0)
return -1013;
return -1017;
ecc_free(&pubKey);
ecc_free(&userB);

View File

@ -49,6 +49,7 @@ typedef struct {
int size; /* The size of the curve in octets */
const char* name; /* name of this curve */
const char* prime; /* prime that defines the field, curve is in (hex) */
const char* Af; /* fields A param (hex) */
const char* Bf; /* fields B param (hex) */
const char* order; /* order of the curve (hex) */
const char* Gx; /* x coordinate of the base point on curve (hex) */
@ -105,6 +106,9 @@ void ecc_fp_free(void);
CYASSL_API
int ecc_export_x963(ecc_key*, byte* out, word32* outLen);
CYASSL_API
int ecc_export_x963_ex(ecc_key*, byte* out, word32* outLen, int compressed);
/* extended functionality with compressed option */
CYASSL_API
int ecc_import_x963(const byte* in, word32 inLen, ecc_key* key);
CYASSL_API
int ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub,

View File

@ -310,6 +310,9 @@ int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,
int mp_lcm (mp_int * a, mp_int * b, mp_int * c);
#endif
int mp_cnt_lsb(mp_int *a);
int mp_mod_d(mp_int* a, mp_digit b, mp_digit* c);
#ifdef __cplusplus
}
#endif

View File

@ -398,7 +398,7 @@ void fp_mul_2(fp_int *a, fp_int *c);
void fp_div_2(fp_int *a, fp_int *c);
/* Counts the number of lsbs which are zero before the first zero bit */
/*int fp_cnt_lsb(fp_int *a);*/
int fp_cnt_lsb(fp_int *a);
/* c = a + b */
void fp_add(fp_int *a, fp_int *b, fp_int *c);
@ -630,11 +630,14 @@ void fp_sqr_comba64(fp_int *a, fp_int *b);
#define MP_LT FP_LT /* less than */
#define MP_EQ FP_EQ /* equal to */
#define MP_GT FP_GT /* greater than */
#define MP_VAL FP_VAL /* invalid */
#define MP_OKAY FP_OKAY /* ok result */
#define MP_NO FP_NO /* yes/no result */
#define MP_YES FP_YES /* yes/no result */
/* Prototypes */
#define mp_zero(a) fp_zero(a)
#define mp_iseven(a) fp_iseven(a)
int mp_init (mp_int * a);
void mp_clear (mp_int * a);
int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, mp_int* f);
@ -686,6 +689,10 @@ int mp_lcm(fp_int *a, fp_int *b, fp_int *c);
int mp_prime_is_prime(mp_int* a, int t, int* result);
#endif /* CYASSL_KEY_GEN */
int mp_cnt_lsb(fp_int *a);
int mp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d);
int mp_mod_d(fp_int* a, fp_digit b, fp_digit* c);
CYASSL_API word32 CheckRunTimeFastMath(void);
/* If user uses RSA, DH, DSA, or ECC math lib directly then fast math FP_SIZE

View File

@ -26,8 +26,8 @@
extern "C" {
#endif
#define LIBCYASSL_VERSION_STRING "3.1.1"
#define LIBCYASSL_VERSION_HEX 0x03001001
#define LIBCYASSL_VERSION_STRING "3.1.2"
#define LIBCYASSL_VERSION_HEX 0x03001002
#ifdef __cplusplus
}