mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #2581 from SparkiDev/ecc_fixes_add
Add deterministic ECDSA sig gen. Fix corner cases for add point.pull/2611/head
commit
1ba366920c
|
@ -2640,8 +2640,8 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,
|
||||||
/* now find (8+k)G for k=1..7 */
|
/* now find (8+k)G for k=1..7 */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
for (j = 9; j < 16; j++) {
|
for (j = 9; j < 16; j++) {
|
||||||
err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a,
|
err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a, modulus,
|
||||||
modulus, mp);
|
mp);
|
||||||
if (err != MP_OKAY) break;
|
if (err != MP_OKAY) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2709,7 +2709,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,
|
||||||
|
|
||||||
/* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
|
/* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
|
||||||
err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a,
|
err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a,
|
||||||
modulus, mp);
|
modulus, mp);
|
||||||
}
|
}
|
||||||
if (err != MP_OKAY) break;
|
if (err != MP_OKAY) break;
|
||||||
/* empty window and reset */
|
/* empty window and reset */
|
||||||
|
@ -2745,8 +2745,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,
|
||||||
first = 0;
|
first = 0;
|
||||||
} else {
|
} else {
|
||||||
/* then add */
|
/* then add */
|
||||||
err = ecc_projective_add_point(R, tG, R, a, modulus,
|
err = ecc_projective_add_point(R, tG, R, a, modulus, mp);
|
||||||
mp);
|
|
||||||
if (err != MP_OKAY) break;
|
if (err != MP_OKAY) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4353,13 +4352,16 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
|
||||||
alt_fp_init(key->pubkey.y);
|
alt_fp_init(key->pubkey.y);
|
||||||
alt_fp_init(key->pubkey.z);
|
alt_fp_init(key->pubkey.z);
|
||||||
ret = mp_init(&key->k);
|
ret = mp_init(&key->k);
|
||||||
#else
|
|
||||||
ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
|
|
||||||
NULL, NULL);
|
|
||||||
#endif /* ALT_ECC_SIZE */
|
|
||||||
if (ret != MP_OKAY) {
|
if (ret != MP_OKAY) {
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
ret = mp_init_multi(&key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
|
||||||
|
NULL, NULL);
|
||||||
|
if (ret != MP_OKAY) {
|
||||||
|
return MEMORY_E;
|
||||||
|
}
|
||||||
|
#endif /* ALT_ECC_SIZE */
|
||||||
#endif /* WOLFSSL_ATECC508A */
|
#endif /* WOLFSSL_ATECC508A */
|
||||||
|
|
||||||
#ifdef WOLFSSL_HEAP_TEST
|
#ifdef WOLFSSL_HEAP_TEST
|
||||||
|
@ -4714,7 +4716,13 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||||
}
|
}
|
||||||
#endif /* !NO_ASN */
|
#endif /* !NO_ASN */
|
||||||
|
|
||||||
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
|
#if defined(WOLFSSL_STM32_PKA)
|
||||||
|
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||||
|
ecc_key* key, mp_int *r, mp_int *s)
|
||||||
|
{
|
||||||
|
return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
|
||||||
|
}
|
||||||
|
#elif !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_CRYPTOCELL)
|
||||||
/**
|
/**
|
||||||
Sign a message digest
|
Sign a message digest
|
||||||
in The message digest to sign
|
in The message digest to sign
|
||||||
|
@ -4726,11 +4734,6 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||||
*/
|
*/
|
||||||
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||||
ecc_key* key, mp_int *r, mp_int *s)
|
ecc_key* key, mp_int *r, mp_int *s)
|
||||||
#if defined(WOLFSSL_STM32_PKA)
|
|
||||||
{
|
|
||||||
return stm32_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
#ifndef WOLFSSL_SP_MATH
|
#ifndef WOLFSSL_SP_MATH
|
||||||
|
@ -4739,11 +4742,16 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||||
!defined(WOLFSSL_SMALL_STACK)
|
!defined(WOLFSSL_SMALL_STACK)
|
||||||
mp_int e_lcl;
|
mp_int e_lcl;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef WOLFSSL_ECDSA_SET_K
|
||||||
DECLARE_CURVE_SPECS(curve, 1);
|
DECLARE_CURVE_SPECS(curve, 1);
|
||||||
|
#else
|
||||||
|
DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
|
||||||
|
#endif
|
||||||
#endif /* !WOLFSSL_SP_MATH */
|
#endif /* !WOLFSSL_SP_MATH */
|
||||||
|
|
||||||
if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL)
|
if (in == NULL || r == NULL || s == NULL || key == NULL || rng == NULL) {
|
||||||
return ECC_BAD_ARG_E;
|
return ECC_BAD_ARG_E;
|
||||||
|
}
|
||||||
|
|
||||||
/* is this a private key? */
|
/* is this a private key? */
|
||||||
if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
|
if (key->type != ECC_PRIVATEKEY && key->type != ECC_PRIVATEKEY_ONLY) {
|
||||||
|
@ -4756,20 +4764,33 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_SP_MATH
|
#ifdef WOLFSSL_SP_MATH
|
||||||
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)
|
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
|
||||||
return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap);
|
#ifndef WOLFSSL_ECDSA_SET_K
|
||||||
else
|
return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL, key->heap);
|
||||||
|
#else
|
||||||
|
return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k,
|
||||||
|
key->heap);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
return WC_KEY_SIZE_E;
|
return WC_KEY_SIZE_E;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#ifdef WOLFSSL_HAVE_SP_ECC
|
#ifdef WOLFSSL_HAVE_SP_ECC
|
||||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
|
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
|
||||||
if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)
|
if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifndef WOLFSSL_SP_NO_256
|
#ifndef WOLFSSL_SP_NO_256
|
||||||
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)
|
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1)
|
||||||
return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->heap);
|
#ifndef WOLFSSL_ECDSA_SET_K
|
||||||
#endif
|
return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL,
|
||||||
|
key->heap);
|
||||||
|
#else
|
||||||
|
return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k,
|
||||||
|
key->heap);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSL_HAVE_SP_ECC */
|
#endif /* WOLFSSL_HAVE_SP_ECC */
|
||||||
|
|
||||||
|
@ -4820,7 +4841,11 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* load curve info */
|
/* load curve info */
|
||||||
|
#ifndef WOLFSSL_ECDSA_SET_K
|
||||||
err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
|
err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER);
|
||||||
|
#else
|
||||||
|
err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* load digest into e */
|
/* load digest into e */
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
@ -4974,8 +4999,28 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||||
err = RNG_FAILURE_E;
|
err = RNG_FAILURE_E;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey,
|
#ifdef WOLFSSL_ECDSA_SET_K
|
||||||
|
if (key->sign_k != NULL) {
|
||||||
|
if (loop_check > 1) {
|
||||||
|
err = RNG_FAILURE_E;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = mp_copy(key->sign_k, &pubkey->k);
|
||||||
|
if (err != MP_OKAY) break;
|
||||||
|
|
||||||
|
mp_forcezero(key->sign_k);
|
||||||
|
mp_free(key->sign_k);
|
||||||
|
XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
|
||||||
|
key->sign_k = NULL;
|
||||||
|
err = wc_ecc_make_pub_ex(pubkey, curve, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
err = wc_ecc_make_key_ex(rng, key->dp->size, pubkey,
|
||||||
key->dp->id);
|
key->dp->id);
|
||||||
|
}
|
||||||
if (err != MP_OKAY) break;
|
if (err != MP_OKAY) break;
|
||||||
|
|
||||||
/* find r = x1 mod n */
|
/* find r = x1 mod n */
|
||||||
|
@ -5054,8 +5099,35 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSL_STM32_PKA */
|
|
||||||
|
#ifdef WOLFSSL_ECDSA_SET_K
|
||||||
|
int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (k == NULL || klen <= 0 || key == NULL) {
|
||||||
|
ret = BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
if (key->sign_k == NULL) {
|
||||||
|
key->sign_k = (mp_int*)XMALLOC(sizeof(mp_int), key->heap,
|
||||||
|
DYNAMIC_TYPE_ECC);
|
||||||
|
if (key->sign_k == NULL) {
|
||||||
|
ret = MEMORY_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = mp_read_unsigned_bin(key->sign_k, k, klen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_ECDSA_SET_K */
|
||||||
#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL*/
|
#endif /* WOLFSSL_ATECC508A && WOLFSSL_CRYPTOCELL*/
|
||||||
|
|
||||||
#endif /* HAVE_ECC_SIGN */
|
#endif /* HAVE_ECC_SIGN */
|
||||||
|
|
||||||
#ifdef WOLFSSL_CUSTOM_CURVES
|
#ifdef WOLFSSL_CUSTOM_CURVES
|
||||||
|
@ -5091,6 +5163,14 @@ int wc_ecc_free(ecc_key* key)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_ECDSA_SET_K
|
||||||
|
if (key->sign_k != NULL) {
|
||||||
|
mp_forcezero(key->sign_k);
|
||||||
|
mp_free(key->sign_k);
|
||||||
|
XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
|
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
|
||||||
#ifdef WC_ASYNC_ENABLE_ECC
|
#ifdef WC_ASYNC_ENABLE_ECC
|
||||||
wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
|
wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_ECC);
|
||||||
|
@ -5291,10 +5371,12 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
|
||||||
|
|
||||||
/* done with mu */
|
/* done with mu */
|
||||||
mp_clear(mu);
|
mp_clear(mu);
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
|
||||||
XFREE(mu, heap, DYNAMIC_TYPE_ECC);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
if (mu != NULL) {
|
||||||
|
XFREE(mu, heap, DYNAMIC_TYPE_ECC);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
|
@ -5383,8 +5465,30 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C,
|
err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C,
|
||||||
a, modulus, mp);
|
a, modulus, mp);
|
||||||
else
|
if (err != MP_OKAY)
|
||||||
break;
|
break;
|
||||||
|
if (mp_iszero(C->z)) {
|
||||||
|
/* When all zero then should have done an add */
|
||||||
|
if (mp_iszero(C->x) && mp_iszero(C->y)) {
|
||||||
|
err = ecc_projective_dbl_point(precomp[nA + (nB<<2)], C,
|
||||||
|
a, modulus, mp);
|
||||||
|
if (err != MP_OKAY)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* When only Z zero then result is infinity */
|
||||||
|
else {
|
||||||
|
err = mp_set(C->x, 0);
|
||||||
|
if (err != MP_OKAY)
|
||||||
|
break;
|
||||||
|
err = mp_set(C->y, 0);
|
||||||
|
if (err != MP_OKAY)
|
||||||
|
break;
|
||||||
|
err = mp_set(C->z, 1);
|
||||||
|
if (err != MP_OKAY)
|
||||||
|
break;
|
||||||
|
first = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5897,38 +6001,62 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
|
||||||
err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
|
err = wc_ecc_point_add(mG, mQ, mG, curve->prime);
|
||||||
#else
|
#else
|
||||||
#ifndef ECC_SHAMIR
|
#ifndef ECC_SHAMIR
|
||||||
|
if (err == MP_OKAY)
|
||||||
{
|
{
|
||||||
mp_digit mp = 0;
|
mp_digit mp = 0;
|
||||||
|
|
||||||
/* compute u1*mG + u2*mQ = mG */
|
if (!mp_iszero(u1)) {
|
||||||
if (err == MP_OKAY) {
|
/* compute u1*mG + u2*mQ = mG */
|
||||||
err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
|
err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
|
||||||
key->heap);
|
key->heap);
|
||||||
}
|
if (err == MP_OKAY) {
|
||||||
if (err == MP_OKAY) {
|
err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
|
||||||
err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
|
|
||||||
key->heap);
|
key->heap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find the montgomery mp */
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_montgomery_setup(curve->prime, &mp);
|
||||||
|
|
||||||
|
/* add them */
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = ecc_projective_add_point(mQ, mG, mG, curve->Af,
|
||||||
|
curve->prime, mp);
|
||||||
|
if (err == MP_OKAY && mp_iszero(mG->z)) {
|
||||||
|
/* When all zero then should have done an add */
|
||||||
|
if (mp_iszero(mG->x) && mp_iszero(mG->y)) {
|
||||||
|
err = ecc_projective_dbl_point(mQ, mG, curve->Af,
|
||||||
|
curve->prime, mp);
|
||||||
|
}
|
||||||
|
/* When only Z zero then result is infinity */
|
||||||
|
else {
|
||||||
|
err = mp_set(mG->x, 0);
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_set(mG->y, 0);
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_set(mG->z, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* compute 0*mG + u2*mQ = mG */
|
||||||
|
err = wc_ecc_mulmod_ex(u2, mQ, mG, curve->Af, curve->prime, 0,
|
||||||
|
key->heap);
|
||||||
|
/* find the montgomery mp */
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
err = mp_montgomery_setup(curve->prime, &mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the montgomery mp */
|
|
||||||
if (err == MP_OKAY)
|
|
||||||
err = mp_montgomery_setup(curve->prime, &mp);
|
|
||||||
|
|
||||||
/* add them */
|
|
||||||
if (err == MP_OKAY)
|
|
||||||
err = ecc_projective_add_point(mQ, mG, mG, curve->Af,
|
|
||||||
curve->prime, mp);
|
|
||||||
|
|
||||||
/* reduce */
|
/* reduce */
|
||||||
if (err == MP_OKAY)
|
if (err == MP_OKAY)
|
||||||
err = ecc_map(mG, curve->prime, mp);
|
err = ecc_map(mG, curve->prime, mp);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
|
/* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
|
err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
|
||||||
key->heap);
|
key->heap);
|
||||||
}
|
}
|
||||||
#endif /* ECC_SHAMIR */
|
#endif /* ECC_SHAMIR */
|
||||||
#endif /* FREESCALE_LTC_ECC */
|
#endif /* FREESCALE_LTC_ECC */
|
||||||
/* v = X_x1 mod n */
|
/* v = X_x1 mod n */
|
||||||
|
@ -7527,6 +7655,9 @@ int wc_ecc_sig_size(ecc_key* key)
|
||||||
extra byte for r and s, so add 2 */
|
extra byte for r and s, so add 2 */
|
||||||
keySz = key->dp->size;
|
keySz = key->dp->size;
|
||||||
orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
|
orderBits = wc_ecc_get_curve_order_bit_count(key->dp);
|
||||||
|
if (orderBits > keySz * 8) {
|
||||||
|
keySz = (orderBits + 7) / 8;
|
||||||
|
}
|
||||||
/* maximum possible signature header size is 7 bytes */
|
/* maximum possible signature header size is 7 bytes */
|
||||||
maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
|
maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
|
||||||
if ((orderBits % 8) == 0) {
|
if ((orderBits % 8) == 0) {
|
||||||
|
@ -8450,17 +8581,42 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a,
|
||||||
/* double if not first */
|
/* double if not first */
|
||||||
if (!first) {
|
if (!first) {
|
||||||
if ((err = ecc_projective_dbl_point(R, R, a, modulus,
|
if ((err = ecc_projective_dbl_point(R, R, a, modulus,
|
||||||
mp)) != MP_OKAY) {
|
mp)) != MP_OKAY) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add if not first, otherwise copy */
|
/* add if not first, otherwise copy */
|
||||||
if (!first && z) {
|
if (!first && z) {
|
||||||
if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R,
|
if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, a,
|
||||||
a, modulus, mp)) != MP_OKAY) {
|
modulus, mp)) != MP_OKAY) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (mp_iszero(R->z)) {
|
||||||
|
/* When all zero then should have done an add */
|
||||||
|
if (mp_iszero(R->x) && mp_iszero(R->y)) {
|
||||||
|
if ((err = ecc_projective_dbl_point(fp_cache[idx].LUT[z],
|
||||||
|
R, a, modulus, mp)) != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* When only Z zero then result is infinity */
|
||||||
|
else {
|
||||||
|
err = mp_set(R->x, 0);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
err = mp_set(R->y, 0);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
err = mp_copy(&fp_cache[idx].mu, R->z);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
first = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (z) {
|
} else if (z) {
|
||||||
if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
|
if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != MP_OKAY) ||
|
||||||
(mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
|
(mp_copy(fp_cache[idx].LUT[z]->y, R->y) != MP_OKAY) ||
|
||||||
|
@ -8468,7 +8624,7 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a,
|
||||||
err = GEN_MEM_ERR;
|
err = GEN_MEM_ERR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
first = 0;
|
first = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8671,21 +8827,74 @@ static int accel_fp_mul2add(int idx1, int idx2,
|
||||||
if (!first) {
|
if (!first) {
|
||||||
if (zA) {
|
if (zA) {
|
||||||
if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA],
|
if ((err = ecc_projective_add_point(R, fp_cache[idx1].LUT[zA],
|
||||||
R, a, modulus, mp)) != MP_OKAY) {
|
R, a, modulus, mp)) != MP_OKAY) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (mp_iszero(R->z)) {
|
||||||
|
/* When all zero then should have done an add */
|
||||||
|
if (mp_iszero(R->x) && mp_iszero(R->y)) {
|
||||||
|
if ((err = ecc_projective_dbl_point(
|
||||||
|
fp_cache[idx1].LUT[zA], R,
|
||||||
|
a, modulus, mp)) != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* When only Z zero then result is infinity */
|
||||||
|
else {
|
||||||
|
err = mp_set(R->x, 0);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
err = mp_set(R->y, 0);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
err = mp_copy(&fp_cache[idx1].mu, R->z);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
first = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zB) {
|
if (zB) {
|
||||||
if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB],
|
if ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB],
|
||||||
R, a, modulus, mp)) != MP_OKAY) {
|
R, a, modulus, mp)) != MP_OKAY) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (mp_iszero(R->z)) {
|
||||||
|
/* When all zero then should have done an add */
|
||||||
|
if (mp_iszero(R->x) && mp_iszero(R->y)) {
|
||||||
|
if ((err = ecc_projective_dbl_point(
|
||||||
|
fp_cache[idx2].LUT[zB], R,
|
||||||
|
a, modulus, mp)) != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* When only Z zero then result is infinity */
|
||||||
|
else {
|
||||||
|
err = mp_set(R->x, 0);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
err = mp_set(R->y, 0);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
err = mp_copy(&fp_cache[idx2].mu, R->z);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
first = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (zA) {
|
if (zA) {
|
||||||
if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
|
if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != MP_OKAY) ||
|
||||||
(mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
|
(mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
|
||||||
(mp_copy(&fp_cache[idx1].mu, R->z) != MP_OKAY)) {
|
(mp_copy(&fp_cache[idx1].mu, R->z) != MP_OKAY)) {
|
||||||
err = GEN_MEM_ERR;
|
err = GEN_MEM_ERR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -8694,14 +8903,40 @@ static int accel_fp_mul2add(int idx1, int idx2,
|
||||||
if (zB && first == 0) {
|
if (zB && first == 0) {
|
||||||
if (zB) {
|
if (zB) {
|
||||||
if ((err = ecc_projective_add_point(R,
|
if ((err = ecc_projective_add_point(R,
|
||||||
fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){
|
fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != MP_OKAY){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (mp_iszero(R->z)) {
|
||||||
|
/* When all zero then should have done an add */
|
||||||
|
if (mp_iszero(R->x) && mp_iszero(R->y)) {
|
||||||
|
if ((err = ecc_projective_dbl_point(
|
||||||
|
fp_cache[idx2].LUT[zB], R,
|
||||||
|
a, modulus, mp)) != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* When only Z zero then result is infinity */
|
||||||
|
else {
|
||||||
|
err = mp_set(R->x, 0);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
err = mp_set(R->y, 0);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
err = mp_copy(&fp_cache[idx2].mu, R->z);
|
||||||
|
if (err != MP_OKAY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
first = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (zB && first == 1) {
|
} else if (zB && first == 1) {
|
||||||
if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
|
if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != MP_OKAY) ||
|
||||||
(mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
|
(mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
|
||||||
(mp_copy(&fp_cache[idx2].mu, R->z) != MP_OKAY)) {
|
(mp_copy(&fp_cache[idx2].mu, R->z) != MP_OKAY)) {
|
||||||
err = GEN_MEM_ERR;
|
err = GEN_MEM_ERR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79395,7 +79395,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a,
|
||||||
* MP_OKAY on success.
|
* MP_OKAY on success.
|
||||||
*/
|
*/
|
||||||
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
mp_int* rm, mp_int* sm, void* heap)
|
mp_int* rm, mp_int* sm, mp_int* km, void* heap)
|
||||||
{
|
{
|
||||||
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
||||||
sp_digit* d = NULL;
|
sp_digit* d = NULL;
|
||||||
|
@ -79461,7 +79461,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
sp_256_from_mp(x, 8, priv);
|
sp_256_from_mp(x, 8, priv);
|
||||||
|
|
||||||
/* New random point. */
|
/* New random point. */
|
||||||
err = sp_256_ecc_gen_k_8(rng, k);
|
if (km == NULL || mp_iszero(km)) {
|
||||||
|
err = sp_256_ecc_gen_k_8(rng, k);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sp_256_from_mp(k, 8, km);
|
||||||
|
mp_zero(km);
|
||||||
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);
|
err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);
|
||||||
}
|
}
|
||||||
|
@ -79620,7 +79626,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
sp_256_from_mp(p2->y, 8, pY);
|
sp_256_from_mp(p2->y, 8, pY);
|
||||||
sp_256_from_mp(p2->z, 8, pZ);
|
sp_256_from_mp(p2->z, 8, pZ);
|
||||||
|
|
||||||
|
{
|
||||||
sp_256_mul_8(s, s, p256_norm_order);
|
sp_256_mul_8(s, s, p256_norm_order);
|
||||||
|
}
|
||||||
err = sp_256_mod_8(s, s, p256_order);
|
err = sp_256_mod_8(s, s, p256_order);
|
||||||
}
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
@ -79638,7 +79646,26 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
{
|
||||||
sp_256_proj_point_add_8(p1, p1, p2, tmp);
|
sp_256_proj_point_add_8(p1, p1, p2, tmp);
|
||||||
|
if (sp_256_iszero_8(p1->z)) {
|
||||||
|
if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) {
|
||||||
|
sp_256_proj_point_dbl_8(p1, p2, tmp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Y ordinate is not used from here - don't set. */
|
||||||
|
p1->x[0] = 0;
|
||||||
|
p1->x[1] = 0;
|
||||||
|
p1->x[2] = 0;
|
||||||
|
p1->x[3] = 0;
|
||||||
|
p1->x[4] = 0;
|
||||||
|
p1->x[5] = 0;
|
||||||
|
p1->x[6] = 0;
|
||||||
|
p1->x[7] = 0;
|
||||||
|
XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
||||||
/* Reload r and convert to Montgomery form. */
|
/* Reload r and convert to Montgomery form. */
|
||||||
|
@ -79668,7 +79695,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
/* u1 = (r + 1*order).z'.z' mod prime */
|
/* u1 = (r + 1*order).z'.z' mod prime */
|
||||||
sp_256_mont_mul_8(u1, u2, p1->z, p256_mod,
|
sp_256_mont_mul_8(u1, u2, p1->z, p256_mod,
|
||||||
p256_mp_mod);
|
p256_mp_mod);
|
||||||
*res = (int)(sp_256_cmp_8(p1->x, u2) == 0);
|
*res = (int)(sp_256_cmp_8(p1->x, u1) == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47453,7 +47453,7 @@ static void sp_256_mont_inv_order_4(sp_digit* r, const sp_digit* a,
|
||||||
* MP_OKAY on success.
|
* MP_OKAY on success.
|
||||||
*/
|
*/
|
||||||
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
mp_int* rm, mp_int* sm, void* heap)
|
mp_int* rm, mp_int* sm, mp_int* km, void* heap)
|
||||||
{
|
{
|
||||||
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
||||||
sp_digit* d = NULL;
|
sp_digit* d = NULL;
|
||||||
|
@ -47519,7 +47519,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
sp_256_from_mp(x, 4, priv);
|
sp_256_from_mp(x, 4, priv);
|
||||||
|
|
||||||
/* New random point. */
|
/* New random point. */
|
||||||
err = sp_256_ecc_gen_k_4(rng, k);
|
if (km == NULL || mp_iszero(km)) {
|
||||||
|
err = sp_256_ecc_gen_k_4(rng, k);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sp_256_from_mp(k, 4, km);
|
||||||
|
mp_zero(km);
|
||||||
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
err = sp_256_ecc_mulmod_base_4(point, k, 1, NULL);
|
err = sp_256_ecc_mulmod_base_4(point, k, 1, NULL);
|
||||||
}
|
}
|
||||||
|
@ -47678,7 +47684,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
sp_256_from_mp(p2->y, 4, pY);
|
sp_256_from_mp(p2->y, 4, pY);
|
||||||
sp_256_from_mp(p2->z, 4, pZ);
|
sp_256_from_mp(p2->z, 4, pZ);
|
||||||
|
|
||||||
|
{
|
||||||
sp_256_mul_4(s, s, p256_norm_order);
|
sp_256_mul_4(s, s, p256_norm_order);
|
||||||
|
}
|
||||||
err = sp_256_mod_4(s, s, p256_order);
|
err = sp_256_mod_4(s, s, p256_order);
|
||||||
}
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
@ -47696,7 +47704,22 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
{
|
||||||
sp_256_proj_point_add_4(p1, p1, p2, tmp);
|
sp_256_proj_point_add_4(p1, p1, p2, tmp);
|
||||||
|
if (sp_256_iszero_4(p1->z)) {
|
||||||
|
if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) {
|
||||||
|
sp_256_proj_point_dbl_4(p1, p2, tmp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Y ordinate is not used from here - don't set. */
|
||||||
|
p1->x[0] = 0;
|
||||||
|
p1->x[1] = 0;
|
||||||
|
p1->x[2] = 0;
|
||||||
|
p1->x[3] = 0;
|
||||||
|
XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
||||||
/* Reload r and convert to Montgomery form. */
|
/* Reload r and convert to Montgomery form. */
|
||||||
|
@ -47726,7 +47749,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
/* u1 = (r + 1*order).z'.z' mod prime */
|
/* u1 = (r + 1*order).z'.z' mod prime */
|
||||||
sp_256_mont_mul_4(u1, u2, p1->z, p256_mod,
|
sp_256_mont_mul_4(u1, u2, p1->z, p256_mod,
|
||||||
p256_mp_mod);
|
p256_mp_mod);
|
||||||
*res = (int)(sp_256_cmp_4(p1->x, u2) == 0);
|
*res = (int)(sp_256_cmp_4(p1->x, u1) == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20862,7 +20862,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a,
|
||||||
* MP_OKAY on success.
|
* MP_OKAY on success.
|
||||||
*/
|
*/
|
||||||
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
mp_int* rm, mp_int* sm, void* heap)
|
mp_int* rm, mp_int* sm, mp_int* km, void* heap)
|
||||||
{
|
{
|
||||||
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
||||||
sp_digit* d = NULL;
|
sp_digit* d = NULL;
|
||||||
|
@ -20928,7 +20928,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
sp_256_from_mp(x, 8, priv);
|
sp_256_from_mp(x, 8, priv);
|
||||||
|
|
||||||
/* New random point. */
|
/* New random point. */
|
||||||
err = sp_256_ecc_gen_k_8(rng, k);
|
if (km == NULL || mp_iszero(km)) {
|
||||||
|
err = sp_256_ecc_gen_k_8(rng, k);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sp_256_from_mp(k, 8, km);
|
||||||
|
mp_zero(km);
|
||||||
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);
|
err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);
|
||||||
}
|
}
|
||||||
|
@ -21087,7 +21093,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
sp_256_from_mp(p2->y, 8, pY);
|
sp_256_from_mp(p2->y, 8, pY);
|
||||||
sp_256_from_mp(p2->z, 8, pZ);
|
sp_256_from_mp(p2->z, 8, pZ);
|
||||||
|
|
||||||
|
{
|
||||||
sp_256_mul_8(s, s, p256_norm_order);
|
sp_256_mul_8(s, s, p256_norm_order);
|
||||||
|
}
|
||||||
err = sp_256_mod_8(s, s, p256_order);
|
err = sp_256_mod_8(s, s, p256_order);
|
||||||
}
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
@ -21105,7 +21113,26 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
{
|
||||||
sp_256_proj_point_add_8(p1, p1, p2, tmp);
|
sp_256_proj_point_add_8(p1, p1, p2, tmp);
|
||||||
|
if (sp_256_iszero_8(p1->z)) {
|
||||||
|
if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) {
|
||||||
|
sp_256_proj_point_dbl_8(p1, p2, tmp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Y ordinate is not used from here - don't set. */
|
||||||
|
p1->x[0] = 0;
|
||||||
|
p1->x[1] = 0;
|
||||||
|
p1->x[2] = 0;
|
||||||
|
p1->x[3] = 0;
|
||||||
|
p1->x[4] = 0;
|
||||||
|
p1->x[5] = 0;
|
||||||
|
p1->x[6] = 0;
|
||||||
|
p1->x[7] = 0;
|
||||||
|
XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
||||||
/* Reload r and convert to Montgomery form. */
|
/* Reload r and convert to Montgomery form. */
|
||||||
|
@ -21135,7 +21162,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
/* u1 = (r + 1*order).z'.z' mod prime */
|
/* u1 = (r + 1*order).z'.z' mod prime */
|
||||||
sp_256_mont_mul_8(u1, u2, p1->z, p256_mod,
|
sp_256_mont_mul_8(u1, u2, p1->z, p256_mod,
|
||||||
p256_mp_mod);
|
p256_mp_mod);
|
||||||
*res = (int)(sp_256_cmp_8(p1->x, u2) == 0);
|
*res = (int)(sp_256_cmp_8(p1->x, u1) == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12452,13 +12452,11 @@ static const sp_digit p256_mod[10] = {
|
||||||
0x3ffffff,0x3ffffff,0x3ffffff,0x003ffff,0x0000000,0x0000000,0x0000000,
|
0x3ffffff,0x3ffffff,0x3ffffff,0x003ffff,0x0000000,0x0000000,0x0000000,
|
||||||
0x0000400,0x3ff0000,0x03fffff
|
0x0000400,0x3ff0000,0x03fffff
|
||||||
};
|
};
|
||||||
#ifndef WOLFSSL_SP_SMALL
|
|
||||||
/* The Montogmery normalizer for modulus of the curve P256. */
|
/* The Montogmery normalizer for modulus of the curve P256. */
|
||||||
static const sp_digit p256_norm_mod[10] = {
|
static const sp_digit p256_norm_mod[10] = {
|
||||||
0x0000001,0x0000000,0x0000000,0x3fc0000,0x3ffffff,0x3ffffff,0x3ffffff,
|
0x0000001,0x0000000,0x0000000,0x3fc0000,0x3ffffff,0x3ffffff,0x3ffffff,
|
||||||
0x3fffbff,0x000ffff,0x0000000
|
0x3fffbff,0x000ffff,0x0000000
|
||||||
};
|
};
|
||||||
#endif /* WOLFSSL_SP_SMALL */
|
|
||||||
/* The Montogmery multiplier for modulus of the curve P256. */
|
/* The Montogmery multiplier for modulus of the curve P256. */
|
||||||
static const sp_digit p256_mp_mod = 0x000001;
|
static const sp_digit p256_mp_mod = 0x000001;
|
||||||
#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
|
#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
|
||||||
|
@ -16867,7 +16865,7 @@ static void sp_256_mont_inv_order_10(sp_digit* r, const sp_digit* a,
|
||||||
* MP_OKAY on success.
|
* MP_OKAY on success.
|
||||||
*/
|
*/
|
||||||
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
mp_int* rm, mp_int* sm, void* heap)
|
mp_int* rm, mp_int* sm, mp_int* km, void* heap)
|
||||||
{
|
{
|
||||||
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
||||||
sp_digit* d = NULL;
|
sp_digit* d = NULL;
|
||||||
|
@ -16933,7 +16931,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
sp_256_from_mp(x, 10, priv);
|
sp_256_from_mp(x, 10, priv);
|
||||||
|
|
||||||
/* New random point. */
|
/* New random point. */
|
||||||
err = sp_256_ecc_gen_k_10(rng, k);
|
if (km == NULL || mp_iszero(km)) {
|
||||||
|
err = sp_256_ecc_gen_k_10(rng, k);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sp_256_from_mp(k, 10, km);
|
||||||
|
mp_zero(km);
|
||||||
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
err = sp_256_ecc_mulmod_base_10(point, k, 1, NULL);
|
err = sp_256_ecc_mulmod_base_10(point, k, 1, NULL);
|
||||||
}
|
}
|
||||||
|
@ -17092,7 +17096,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
sp_256_from_mp(p2->y, 10, pY);
|
sp_256_from_mp(p2->y, 10, pY);
|
||||||
sp_256_from_mp(p2->z, 10, pZ);
|
sp_256_from_mp(p2->z, 10, pZ);
|
||||||
|
|
||||||
|
{
|
||||||
sp_256_mul_10(s, s, p256_norm_order);
|
sp_256_mul_10(s, s, p256_norm_order);
|
||||||
|
}
|
||||||
err = sp_256_mod_10(s, s, p256_order);
|
err = sp_256_mod_10(s, s, p256_order);
|
||||||
}
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
@ -17110,7 +17116,28 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
{
|
||||||
sp_256_proj_point_add_10(p1, p1, p2, tmp);
|
sp_256_proj_point_add_10(p1, p1, p2, tmp);
|
||||||
|
if (sp_256_iszero_10(p1->z)) {
|
||||||
|
if (sp_256_iszero_10(p1->x) && sp_256_iszero_10(p1->y)) {
|
||||||
|
sp_256_proj_point_dbl_10(p1, p2, tmp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Y ordinate is not used from here - don't set. */
|
||||||
|
p1->x[0] = 0;
|
||||||
|
p1->x[1] = 0;
|
||||||
|
p1->x[2] = 0;
|
||||||
|
p1->x[3] = 0;
|
||||||
|
p1->x[4] = 0;
|
||||||
|
p1->x[5] = 0;
|
||||||
|
p1->x[6] = 0;
|
||||||
|
p1->x[7] = 0;
|
||||||
|
p1->x[8] = 0;
|
||||||
|
p1->x[9] = 0;
|
||||||
|
XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
||||||
/* Reload r and convert to Montgomery form. */
|
/* Reload r and convert to Montgomery form. */
|
||||||
|
@ -17140,7 +17167,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
/* u1 = (r + 1*order).z'.z' mod prime */
|
/* u1 = (r + 1*order).z'.z' mod prime */
|
||||||
sp_256_mont_mul_10(u1, u2, p1->z, p256_mod,
|
sp_256_mont_mul_10(u1, u2, p1->z, p256_mod,
|
||||||
p256_mp_mod);
|
p256_mp_mod);
|
||||||
*res = (int)(sp_256_cmp_10(p1->x, u2) == 0);
|
*res = (int)(sp_256_cmp_10(p1->x, u1) == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12270,13 +12270,11 @@ static const sp_digit p256_mod[5] = {
|
||||||
0xfffffffffffffL,0x00fffffffffffL,0x0000000000000L,0x0001000000000L,
|
0xfffffffffffffL,0x00fffffffffffL,0x0000000000000L,0x0001000000000L,
|
||||||
0x0ffffffff0000L
|
0x0ffffffff0000L
|
||||||
};
|
};
|
||||||
#ifndef WOLFSSL_SP_SMALL
|
|
||||||
/* The Montogmery normalizer for modulus of the curve P256. */
|
/* The Montogmery normalizer for modulus of the curve P256. */
|
||||||
static const sp_digit p256_norm_mod[5] = {
|
static const sp_digit p256_norm_mod[5] = {
|
||||||
0x0000000000001L,0xff00000000000L,0xfffffffffffffL,0xfffefffffffffL,
|
0x0000000000001L,0xff00000000000L,0xfffffffffffffL,0xfffefffffffffL,
|
||||||
0x000000000ffffL
|
0x000000000ffffL
|
||||||
};
|
};
|
||||||
#endif /* WOLFSSL_SP_SMALL */
|
|
||||||
/* The Montogmery multiplier for modulus of the curve P256. */
|
/* The Montogmery multiplier for modulus of the curve P256. */
|
||||||
static const sp_digit p256_mp_mod = 0x0000000000001;
|
static const sp_digit p256_mp_mod = 0x0000000000001;
|
||||||
#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
|
#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \
|
||||||
|
@ -16460,7 +16458,7 @@ static void sp_256_mont_inv_order_5(sp_digit* r, const sp_digit* a,
|
||||||
* MP_OKAY on success.
|
* MP_OKAY on success.
|
||||||
*/
|
*/
|
||||||
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
mp_int* rm, mp_int* sm, void* heap)
|
mp_int* rm, mp_int* sm, mp_int* km, void* heap)
|
||||||
{
|
{
|
||||||
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
||||||
sp_digit* d = NULL;
|
sp_digit* d = NULL;
|
||||||
|
@ -16526,7 +16524,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
sp_256_from_mp(x, 5, priv);
|
sp_256_from_mp(x, 5, priv);
|
||||||
|
|
||||||
/* New random point. */
|
/* New random point. */
|
||||||
err = sp_256_ecc_gen_k_5(rng, k);
|
if (km == NULL || mp_iszero(km)) {
|
||||||
|
err = sp_256_ecc_gen_k_5(rng, k);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sp_256_from_mp(k, 5, km);
|
||||||
|
mp_zero(km);
|
||||||
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
err = sp_256_ecc_mulmod_base_5(point, k, 1, NULL);
|
err = sp_256_ecc_mulmod_base_5(point, k, 1, NULL);
|
||||||
}
|
}
|
||||||
|
@ -16685,7 +16689,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
sp_256_from_mp(p2->y, 5, pY);
|
sp_256_from_mp(p2->y, 5, pY);
|
||||||
sp_256_from_mp(p2->z, 5, pZ);
|
sp_256_from_mp(p2->z, 5, pZ);
|
||||||
|
|
||||||
|
{
|
||||||
sp_256_mul_5(s, s, p256_norm_order);
|
sp_256_mul_5(s, s, p256_norm_order);
|
||||||
|
}
|
||||||
err = sp_256_mod_5(s, s, p256_order);
|
err = sp_256_mod_5(s, s, p256_order);
|
||||||
}
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
@ -16703,7 +16709,23 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
{
|
||||||
sp_256_proj_point_add_5(p1, p1, p2, tmp);
|
sp_256_proj_point_add_5(p1, p1, p2, tmp);
|
||||||
|
if (sp_256_iszero_5(p1->z)) {
|
||||||
|
if (sp_256_iszero_5(p1->x) && sp_256_iszero_5(p1->y)) {
|
||||||
|
sp_256_proj_point_dbl_5(p1, p2, tmp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Y ordinate is not used from here - don't set. */
|
||||||
|
p1->x[0] = 0;
|
||||||
|
p1->x[1] = 0;
|
||||||
|
p1->x[2] = 0;
|
||||||
|
p1->x[3] = 0;
|
||||||
|
p1->x[4] = 0;
|
||||||
|
XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
||||||
/* Reload r and convert to Montgomery form. */
|
/* Reload r and convert to Montgomery form. */
|
||||||
|
@ -16733,7 +16755,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
/* u1 = (r + 1*order).z'.z' mod prime */
|
/* u1 = (r + 1*order).z'.z' mod prime */
|
||||||
sp_256_mont_mul_5(u1, u2, p1->z, p256_mod,
|
sp_256_mont_mul_5(u1, u2, p1->z, p256_mod,
|
||||||
p256_mp_mod);
|
p256_mp_mod);
|
||||||
*res = (int)(sp_256_cmp_5(p1->x, u2) == 0);
|
*res = (int)(sp_256_cmp_5(p1->x, u1) == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20604,7 +20604,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a,
|
||||||
* MP_OKAY on success.
|
* MP_OKAY on success.
|
||||||
*/
|
*/
|
||||||
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
mp_int* rm, mp_int* sm, void* heap)
|
mp_int* rm, mp_int* sm, mp_int* km, void* heap)
|
||||||
{
|
{
|
||||||
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
||||||
sp_digit* d = NULL;
|
sp_digit* d = NULL;
|
||||||
|
@ -20670,7 +20670,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
sp_256_from_mp(x, 8, priv);
|
sp_256_from_mp(x, 8, priv);
|
||||||
|
|
||||||
/* New random point. */
|
/* New random point. */
|
||||||
err = sp_256_ecc_gen_k_8(rng, k);
|
if (km == NULL || mp_iszero(km)) {
|
||||||
|
err = sp_256_ecc_gen_k_8(rng, k);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sp_256_from_mp(k, 8, km);
|
||||||
|
mp_zero(km);
|
||||||
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);
|
err = sp_256_ecc_mulmod_base_8(point, k, 1, NULL);
|
||||||
}
|
}
|
||||||
|
@ -20829,7 +20835,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
sp_256_from_mp(p2->y, 8, pY);
|
sp_256_from_mp(p2->y, 8, pY);
|
||||||
sp_256_from_mp(p2->z, 8, pZ);
|
sp_256_from_mp(p2->z, 8, pZ);
|
||||||
|
|
||||||
|
{
|
||||||
sp_256_mul_8(s, s, p256_norm_order);
|
sp_256_mul_8(s, s, p256_norm_order);
|
||||||
|
}
|
||||||
err = sp_256_mod_8(s, s, p256_order);
|
err = sp_256_mod_8(s, s, p256_order);
|
||||||
}
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
@ -20847,7 +20855,26 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
{
|
||||||
sp_256_proj_point_add_8(p1, p1, p2, tmp);
|
sp_256_proj_point_add_8(p1, p1, p2, tmp);
|
||||||
|
if (sp_256_iszero_8(p1->z)) {
|
||||||
|
if (sp_256_iszero_8(p1->x) && sp_256_iszero_8(p1->y)) {
|
||||||
|
sp_256_proj_point_dbl_8(p1, p2, tmp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Y ordinate is not used from here - don't set. */
|
||||||
|
p1->x[0] = 0;
|
||||||
|
p1->x[1] = 0;
|
||||||
|
p1->x[2] = 0;
|
||||||
|
p1->x[3] = 0;
|
||||||
|
p1->x[4] = 0;
|
||||||
|
p1->x[5] = 0;
|
||||||
|
p1->x[6] = 0;
|
||||||
|
p1->x[7] = 0;
|
||||||
|
XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
||||||
/* Reload r and convert to Montgomery form. */
|
/* Reload r and convert to Montgomery form. */
|
||||||
|
@ -20877,7 +20904,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
/* u1 = (r + 1*order).z'.z' mod prime */
|
/* u1 = (r + 1*order).z'.z' mod prime */
|
||||||
sp_256_mont_mul_8(u1, u2, p1->z, p256_mod,
|
sp_256_mont_mul_8(u1, u2, p1->z, p256_mod,
|
||||||
p256_mp_mod);
|
p256_mp_mod);
|
||||||
*res = (int)(sp_256_cmp_8(p1->x, u2) == 0);
|
*res = (int)(sp_256_cmp_8(p1->x, u1) == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -851,8 +851,14 @@ int sp_add(sp_int* a, sp_int* b, sp_int* r)
|
||||||
*/
|
*/
|
||||||
int sp_set_int(sp_int* a, unsigned long b)
|
int sp_set_int(sp_int* a, unsigned long b)
|
||||||
{
|
{
|
||||||
a->used = 1;
|
if (b == 0) {
|
||||||
a->dp[0] = b;
|
a->used = 0;
|
||||||
|
a->dp[0] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
a->used = 1;
|
||||||
|
a->dp[0] = b;
|
||||||
|
}
|
||||||
|
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22700,7 +22700,7 @@ static void sp_256_mont_inv_order_avx2_4(sp_digit* r, const sp_digit* a,
|
||||||
* MP_OKAY on success.
|
* MP_OKAY on success.
|
||||||
*/
|
*/
|
||||||
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
mp_int* rm, mp_int* sm, void* heap)
|
mp_int* rm, mp_int* sm, mp_int* km, void* heap)
|
||||||
{
|
{
|
||||||
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)
|
||||||
sp_digit* d = NULL;
|
sp_digit* d = NULL;
|
||||||
|
@ -22769,7 +22769,13 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
sp_256_from_mp(x, 4, priv);
|
sp_256_from_mp(x, 4, priv);
|
||||||
|
|
||||||
/* New random point. */
|
/* New random point. */
|
||||||
err = sp_256_ecc_gen_k_4(rng, k);
|
if (km == NULL || mp_iszero(km)) {
|
||||||
|
err = sp_256_ecc_gen_k_4(rng, k);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sp_256_from_mp(k, 4, km);
|
||||||
|
mp_zero(km);
|
||||||
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
#ifdef HAVE_INTEL_AVX2
|
#ifdef HAVE_INTEL_AVX2
|
||||||
if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
|
if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
|
||||||
|
@ -22957,11 +22963,14 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
sp_256_from_mp(p2->z, 4, pZ);
|
sp_256_from_mp(p2->z, 4, pZ);
|
||||||
|
|
||||||
#ifdef HAVE_INTEL_AVX2
|
#ifdef HAVE_INTEL_AVX2
|
||||||
if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
|
if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {
|
||||||
sp_256_mul_avx2_4(s, s, p256_norm_order);
|
sp_256_mul_avx2_4(s, s, p256_norm_order);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
sp_256_mul_4(s, s, p256_norm_order);
|
sp_256_mul_4(s, s, p256_norm_order);
|
||||||
|
}
|
||||||
err = sp_256_mod_4(s, s, p256_order);
|
err = sp_256_mod_4(s, s, p256_order);
|
||||||
}
|
}
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
|
@ -22998,11 +23007,40 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
|
|
||||||
if (err == MP_OKAY) {
|
if (err == MP_OKAY) {
|
||||||
#ifdef HAVE_INTEL_AVX2
|
#ifdef HAVE_INTEL_AVX2
|
||||||
if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags))
|
if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) {
|
||||||
sp_256_proj_point_add_avx2_4(p1, p1, p2, tmp);
|
sp_256_proj_point_add_avx2_4(p1, p1, p2, tmp);
|
||||||
|
if (sp_256_iszero_4(p1->z)) {
|
||||||
|
if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) {
|
||||||
|
sp_256_proj_point_dbl_avx2_4(p1, p2, tmp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Y ordinate is not used from here - don't set. */
|
||||||
|
p1->x[0] = 0;
|
||||||
|
p1->x[1] = 0;
|
||||||
|
p1->x[2] = 0;
|
||||||
|
p1->x[3] = 0;
|
||||||
|
XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
sp_256_proj_point_add_4(p1, p1, p2, tmp);
|
sp_256_proj_point_add_4(p1, p1, p2, tmp);
|
||||||
|
if (sp_256_iszero_4(p1->z)) {
|
||||||
|
if (sp_256_iszero_4(p1->x) && sp_256_iszero_4(p1->y)) {
|
||||||
|
sp_256_proj_point_dbl_4(p1, p2, tmp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Y ordinate is not used from here - don't set. */
|
||||||
|
p1->x[0] = 0;
|
||||||
|
p1->x[1] = 0;
|
||||||
|
p1->x[2] = 0;
|
||||||
|
p1->x[3] = 0;
|
||||||
|
XMEMCPY(p1->z, p256_norm_mod, sizeof(p256_norm_mod));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
/* (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' */
|
||||||
/* Reload r and convert to Montgomery form. */
|
/* Reload r and convert to Montgomery form. */
|
||||||
|
@ -23032,7 +23070,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX,
|
||||||
/* u1 = (r + 1*order).z'.z' mod prime */
|
/* u1 = (r + 1*order).z'.z' mod prime */
|
||||||
sp_256_mont_mul_4(u1, u2, p1->z, p256_mod,
|
sp_256_mont_mul_4(u1, u2, p1->z, p256_mod,
|
||||||
p256_mp_mod);
|
p256_mp_mod);
|
||||||
*res = (int)(sp_256_cmp_4(p1->x, u2) == 0);
|
*res = (int)(sp_256_cmp_4(p1->x, u1) == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16587,6 +16587,85 @@ static int ecc_test_vector(int keySize)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_ECC_SIGN) && defined(WOLFSSL_ECDSA_SET_K)
|
||||||
|
static int ecc_test_sign_vectors(WC_RNG* rng)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ecc_key key;
|
||||||
|
byte sig[72];
|
||||||
|
word32 sigSz;
|
||||||
|
unsigned char hash[32] = "test wolfSSL deterministic sign";
|
||||||
|
const char* dIUT = "7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534";
|
||||||
|
const char* QIUTx = "ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b230";
|
||||||
|
const char* QIUTy = "28af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141";
|
||||||
|
const byte k[1] = { 0x02 };
|
||||||
|
const byte expSig[71] = {
|
||||||
|
0x30, 0x45, 0x02, 0x20, 0x7c, 0xf2, 0x7b, 0x18,
|
||||||
|
0x8d, 0x03, 0x4f, 0x7e, 0x8a, 0x52, 0x38, 0x03,
|
||||||
|
0x04, 0xb5, 0x1a, 0xc3, 0xc0, 0x89, 0x69, 0xe2,
|
||||||
|
0x77, 0xf2, 0x1b, 0x35, 0xa6, 0x0b, 0x48, 0xfc,
|
||||||
|
0x47, 0x66, 0x99, 0x78, 0x02, 0x21, 0x00, 0xa8,
|
||||||
|
0x43, 0xa0, 0xce, 0x6c, 0x5e, 0x17, 0x8a, 0x53,
|
||||||
|
0x4d, 0xaf, 0xd2, 0x95, 0x78, 0x9f, 0x84, 0x4f,
|
||||||
|
0x94, 0xb8, 0x75, 0xa3, 0x19, 0xa5, 0xd4, 0xdf,
|
||||||
|
0xe1, 0xd4, 0x5e, 0x9d, 0x97, 0xfe, 0x81
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = wc_ecc_init_ex(&key, HEAP_HINT, devId);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = wc_ecc_import_raw(&key, QIUTx, QIUTy, dIUT, "SECP256R1");
|
||||||
|
if (ret != 0) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = wc_ecc_sign_set_k(k, sizeof(k), &key);
|
||||||
|
if (ret != 0) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
sigSz = sizeof(sig);
|
||||||
|
do {
|
||||||
|
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||||
|
ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
|
||||||
|
#endif
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_ecc_sign_hash(hash, sizeof(hash), sig, &sigSz, rng, &key);
|
||||||
|
} while (ret == WC_PENDING_E);
|
||||||
|
if (ret != 0) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
TEST_SLEEP();
|
||||||
|
|
||||||
|
if (sigSz != sizeof(expSig)) {
|
||||||
|
ret = -8350;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (XMEMCMP(sig, expSig, sigSz) != 0) {
|
||||||
|
ret = -8351;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
sigSz = sizeof(sig);
|
||||||
|
do {
|
||||||
|
#if defined(WOLFSSL_ASYNC_CRYPT)
|
||||||
|
ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
|
||||||
|
#endif
|
||||||
|
if (ret == 0)
|
||||||
|
ret = wc_ecc_sign_hash(hash, sizeof(hash), sig, &sigSz, rng, &key);
|
||||||
|
} while (ret == WC_PENDING_E);
|
||||||
|
if (ret != 0) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
TEST_SLEEP();
|
||||||
|
|
||||||
|
done:
|
||||||
|
wc_ecc_free(&key);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_ECC_CDH
|
#ifdef HAVE_ECC_CDH
|
||||||
static int ecc_test_cdh_vectors(void)
|
static int ecc_test_cdh_vectors(void)
|
||||||
{
|
{
|
||||||
|
@ -16609,7 +16688,7 @@ static int ecc_test_cdh_vectors(void)
|
||||||
ret = wc_ecc_init_ex(&priv_key, HEAP_HINT, devId);
|
ret = wc_ecc_init_ex(&priv_key, HEAP_HINT, devId);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
wc_ecc_free(&pub_key);
|
wc_ecc_free(&pub_key);
|
||||||
goto done;
|
return ret;
|
||||||
}
|
}
|
||||||
wc_ecc_set_flags(&pub_key, WC_ECC_FLAG_COFACTOR);
|
wc_ecc_set_flags(&pub_key, WC_ECC_FLAG_COFACTOR);
|
||||||
wc_ecc_set_flags(&priv_key, WC_ECC_FLAG_COFACTOR);
|
wc_ecc_set_flags(&priv_key, WC_ECC_FLAG_COFACTOR);
|
||||||
|
@ -18459,6 +18538,13 @@ int ecc_test(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_ECC_SIGN) && defined(WOLFSSL_ECDSA_SET_K)
|
||||||
|
ret = ecc_test_sign_vectors(&rng);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("ecc_test_sign_vectors failed! %d\n", ret);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef HAVE_ECC_CDH
|
#ifdef HAVE_ECC_CDH
|
||||||
ret = ecc_test_cdh_vectors();
|
ret = ecc_test_cdh_vectors();
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
|
|
@ -391,6 +391,10 @@ struct ecc_key {
|
||||||
ecc_context_t ctx;
|
ecc_context_t ctx;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_ECDSA_SET_K
|
||||||
|
mp_int *sign_k;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK_CACHE
|
#ifdef WOLFSSL_SMALL_STACK_CACHE
|
||||||
mp_int* t1;
|
mp_int* t1;
|
||||||
mp_int* t2;
|
mp_int* t2;
|
||||||
|
@ -470,6 +474,10 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||||
WOLFSSL_API
|
WOLFSSL_API
|
||||||
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||||
ecc_key* key, mp_int *r, mp_int *s);
|
ecc_key* key, mp_int *r, mp_int *s);
|
||||||
|
#ifdef WOLFSSL_ECDSA_SET_K
|
||||||
|
WOLFSSL_API
|
||||||
|
int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key);
|
||||||
|
#endif
|
||||||
#endif /* HAVE_ECC_SIGN */
|
#endif /* HAVE_ECC_SIGN */
|
||||||
|
|
||||||
#ifdef HAVE_ECC_VERIFY
|
#ifdef HAVE_ECC_VERIFY
|
||||||
|
|
|
@ -106,7 +106,7 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap);
|
||||||
int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,
|
int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out,
|
||||||
word32* outlen, void* heap);
|
word32* outlen, void* heap);
|
||||||
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv,
|
||||||
mp_int* rm, mp_int* sm, void* heap);
|
mp_int* rm, mp_int* sm, mp_int* km, void* heap);
|
||||||
int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, mp_int* pY,
|
int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, mp_int* pY,
|
||||||
mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap);
|
mp_int* pZ, mp_int* r, mp_int* sm, int* res, void* heap);
|
||||||
int sp_ecc_is_point_256(mp_int* pX, mp_int* pY);
|
int sp_ecc_is_point_256(mp_int* pX, mp_int* pY);
|
||||||
|
|
Loading…
Reference in New Issue