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 */
|
||||
if (err == MP_OKAY)
|
||||
for (j = 9; j < 16; j++) {
|
||||
err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a,
|
||||
modulus, mp);
|
||||
err = ecc_projective_add_point(M[j-9], tG, M[j-M_POINTS], a, modulus,
|
||||
mp);
|
||||
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 */
|
||||
err = ecc_projective_add_point(R, M[bitbuf-M_POINTS], R, a,
|
||||
modulus, mp);
|
||||
modulus, mp);
|
||||
}
|
||||
if (err != MP_OKAY) break;
|
||||
/* empty window and reset */
|
||||
|
@ -2745,8 +2745,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R,
|
|||
first = 0;
|
||||
} else {
|
||||
/* then add */
|
||||
err = ecc_projective_add_point(R, tG, R, a, modulus,
|
||||
mp);
|
||||
err = ecc_projective_add_point(R, tG, R, a, modulus, mp);
|
||||
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.z);
|
||||
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) {
|
||||
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 */
|
||||
|
||||
#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 */
|
||||
|
||||
#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
|
||||
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,
|
||||
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;
|
||||
#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)
|
||||
mp_int e_lcl;
|
||||
#endif
|
||||
#ifndef WOLFSSL_ECDSA_SET_K
|
||||
DECLARE_CURVE_SPECS(curve, 1);
|
||||
#else
|
||||
DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
|
||||
#endif
|
||||
#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;
|
||||
}
|
||||
|
||||
/* is this a private key? */
|
||||
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
|
||||
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);
|
||||
else
|
||||
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
|
||||
#ifndef WOLFSSL_ECDSA_SET_K
|
||||
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;
|
||||
}
|
||||
#else
|
||||
#ifdef WOLFSSL_HAVE_SP_ECC
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC)
|
||||
if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC)
|
||||
#endif
|
||||
{
|
||||
#ifndef WOLFSSL_SP_NO_256
|
||||
#ifndef WOLFSSL_SP_NO_256
|
||||
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);
|
||||
#endif
|
||||
#ifndef WOLFSSL_ECDSA_SET_K
|
||||
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 */
|
||||
|
||||
|
@ -4820,7 +4841,11 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
|||
}
|
||||
|
||||
/* load curve info */
|
||||
#ifndef WOLFSSL_ECDSA_SET_K
|
||||
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 */
|
||||
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;
|
||||
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);
|
||||
}
|
||||
if (err != MP_OKAY) break;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
#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 /* HAVE_ECC_SIGN */
|
||||
|
||||
#ifdef WOLFSSL_CUSTOM_CURVES
|
||||
|
@ -5091,6 +5163,14 @@ int wc_ecc_free(ecc_key* key)
|
|||
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)
|
||||
#ifdef WC_ASYNC_ENABLE_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 */
|
||||
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)
|
||||
|
@ -5383,8 +5465,30 @@ int ecc_mul2add(ecc_point* A, mp_int* kA,
|
|||
if (err == MP_OKAY)
|
||||
err = ecc_projective_add_point(C, precomp[nA + (nB<<2)], C,
|
||||
a, modulus, mp);
|
||||
else
|
||||
if (err != MP_OKAY)
|
||||
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);
|
||||
#else
|
||||
#ifndef ECC_SHAMIR
|
||||
if (err == MP_OKAY)
|
||||
{
|
||||
mp_digit mp = 0;
|
||||
|
||||
/* compute u1*mG + u2*mQ = mG */
|
||||
if (err == MP_OKAY) {
|
||||
if (!mp_iszero(u1)) {
|
||||
/* compute u1*mG + u2*mQ = mG */
|
||||
err = wc_ecc_mulmod_ex(u1, mG, mG, curve->Af, curve->prime, 0,
|
||||
key->heap);
|
||||
}
|
||||
if (err == MP_OKAY) {
|
||||
err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
|
||||
if (err == MP_OKAY) {
|
||||
err = wc_ecc_mulmod_ex(u2, mQ, mQ, curve->Af, curve->prime, 0,
|
||||
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 */
|
||||
if (err == MP_OKAY)
|
||||
err = ecc_map(mG, curve->prime, mp);
|
||||
}
|
||||
#else
|
||||
/* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
|
||||
if (err == MP_OKAY) {
|
||||
err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
|
||||
key->heap);
|
||||
}
|
||||
/* use Shamir's trick to compute u1*mG + u2*mQ using half the doubles */
|
||||
if (err == MP_OKAY) {
|
||||
err = ecc_mul2add(mG, u1, mQ, u2, mG, curve->Af, curve->prime,
|
||||
key->heap);
|
||||
}
|
||||
#endif /* ECC_SHAMIR */
|
||||
#endif /* FREESCALE_LTC_ECC */
|
||||
/* 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 */
|
||||
keySz = key->dp->size;
|
||||
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 */
|
||||
maxSigSz = (keySz * 2) + SIG_HEADER_SZ;
|
||||
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 */
|
||||
if (!first) {
|
||||
if ((err = ecc_projective_dbl_point(R, R, a, modulus,
|
||||
mp)) != MP_OKAY) {
|
||||
mp)) != MP_OKAY) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* add if not first, otherwise copy */
|
||||
if (!first && z) {
|
||||
if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R,
|
||||
a, modulus, mp)) != MP_OKAY) {
|
||||
if ((err = ecc_projective_add_point(R, fp_cache[idx].LUT[z], R, a,
|
||||
modulus, mp)) != MP_OKAY) {
|
||||
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) {
|
||||
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) ||
|
||||
|
@ -8468,7 +8624,7 @@ static int accel_fp_mul(int idx, mp_int* k, ecc_point *R, mp_int* a,
|
|||
err = GEN_MEM_ERR;
|
||||
break;
|
||||
}
|
||||
first = 0;
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8671,21 +8827,74 @@ static int accel_fp_mul2add(int idx1, int idx2,
|
|||
if (!first) {
|
||||
if (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;
|
||||
}
|
||||
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 ((err = ecc_projective_add_point(R, fp_cache[idx2].LUT[zB],
|
||||
R, a, modulus, mp)) != MP_OKAY) {
|
||||
R, a, modulus, mp)) != MP_OKAY) {
|
||||
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 (zA) {
|
||||
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].mu, R->z) != MP_OKAY)) {
|
||||
(mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != MP_OKAY) ||
|
||||
(mp_copy(&fp_cache[idx1].mu, R->z) != MP_OKAY)) {
|
||||
err = GEN_MEM_ERR;
|
||||
break;
|
||||
}
|
||||
|
@ -8694,14 +8903,40 @@ static int accel_fp_mul2add(int idx1, int idx2,
|
|||
if (zB && first == 0) {
|
||||
if (zB) {
|
||||
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;
|
||||
}
|
||||
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) {
|
||||
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].mu, R->z) != MP_OKAY)) {
|
||||
(mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != MP_OKAY) ||
|
||||
(mp_copy(&fp_cache[idx2].mu, R->z) != MP_OKAY)) {
|
||||
err = GEN_MEM_ERR;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -79395,7 +79395,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a,
|
|||
* MP_OKAY on success.
|
||||
*/
|
||||
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)
|
||||
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);
|
||||
|
||||
/* 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) {
|
||||
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->z, 8, pZ);
|
||||
|
||||
{
|
||||
sp_256_mul_8(s, s, p256_norm_order);
|
||||
}
|
||||
err = sp_256_mod_8(s, s, p256_order);
|
||||
}
|
||||
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) {
|
||||
{
|
||||
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' */
|
||||
/* 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 */
|
||||
sp_256_mont_mul_8(u1, u2, p1->z, p256_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.
|
||||
*/
|
||||
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)
|
||||
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);
|
||||
|
||||
/* 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) {
|
||||
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->z, 4, pZ);
|
||||
|
||||
{
|
||||
sp_256_mul_4(s, s, p256_norm_order);
|
||||
}
|
||||
err = sp_256_mod_4(s, s, p256_order);
|
||||
}
|
||||
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) {
|
||||
{
|
||||
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' */
|
||||
/* 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 */
|
||||
sp_256_mont_mul_4(u1, u2, p1->z, p256_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.
|
||||
*/
|
||||
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)
|
||||
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);
|
||||
|
||||
/* 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) {
|
||||
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->z, 8, pZ);
|
||||
|
||||
{
|
||||
sp_256_mul_8(s, s, p256_norm_order);
|
||||
}
|
||||
err = sp_256_mod_8(s, s, p256_order);
|
||||
}
|
||||
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) {
|
||||
{
|
||||
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' */
|
||||
/* 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 */
|
||||
sp_256_mont_mul_8(u1, u2, p1->z, p256_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,
|
||||
0x0000400,0x3ff0000,0x03fffff
|
||||
};
|
||||
#ifndef WOLFSSL_SP_SMALL
|
||||
/* The Montogmery normalizer for modulus of the curve P256. */
|
||||
static const sp_digit p256_norm_mod[10] = {
|
||||
0x0000001,0x0000000,0x0000000,0x3fc0000,0x3ffffff,0x3ffffff,0x3ffffff,
|
||||
0x3fffbff,0x000ffff,0x0000000
|
||||
};
|
||||
#endif /* WOLFSSL_SP_SMALL */
|
||||
/* The Montogmery multiplier for modulus of the curve P256. */
|
||||
static const sp_digit p256_mp_mod = 0x000001;
|
||||
#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.
|
||||
*/
|
||||
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)
|
||||
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);
|
||||
|
||||
/* 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) {
|
||||
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->z, 10, pZ);
|
||||
|
||||
{
|
||||
sp_256_mul_10(s, s, p256_norm_order);
|
||||
}
|
||||
err = sp_256_mod_10(s, s, p256_order);
|
||||
}
|
||||
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) {
|
||||
{
|
||||
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' */
|
||||
/* 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 */
|
||||
sp_256_mont_mul_10(u1, u2, p1->z, p256_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,
|
||||
0x0ffffffff0000L
|
||||
};
|
||||
#ifndef WOLFSSL_SP_SMALL
|
||||
/* The Montogmery normalizer for modulus of the curve P256. */
|
||||
static const sp_digit p256_norm_mod[5] = {
|
||||
0x0000000000001L,0xff00000000000L,0xfffffffffffffL,0xfffefffffffffL,
|
||||
0x000000000ffffL
|
||||
};
|
||||
#endif /* WOLFSSL_SP_SMALL */
|
||||
/* The Montogmery multiplier for modulus of the curve P256. */
|
||||
static const sp_digit p256_mp_mod = 0x0000000000001;
|
||||
#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.
|
||||
*/
|
||||
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)
|
||||
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);
|
||||
|
||||
/* 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) {
|
||||
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->z, 5, pZ);
|
||||
|
||||
{
|
||||
sp_256_mul_5(s, s, p256_norm_order);
|
||||
}
|
||||
err = sp_256_mod_5(s, s, p256_order);
|
||||
}
|
||||
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) {
|
||||
{
|
||||
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' */
|
||||
/* 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 */
|
||||
sp_256_mont_mul_5(u1, u2, p1->z, p256_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.
|
||||
*/
|
||||
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)
|
||||
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);
|
||||
|
||||
/* 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) {
|
||||
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->z, 8, pZ);
|
||||
|
||||
{
|
||||
sp_256_mul_8(s, s, p256_norm_order);
|
||||
}
|
||||
err = sp_256_mod_8(s, s, p256_order);
|
||||
}
|
||||
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) {
|
||||
{
|
||||
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' */
|
||||
/* 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 */
|
||||
sp_256_mont_mul_8(u1, u2, p1->z, p256_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)
|
||||
{
|
||||
a->used = 1;
|
||||
a->dp[0] = b;
|
||||
if (b == 0) {
|
||||
a->used = 0;
|
||||
a->dp[0] = 0;
|
||||
}
|
||||
else {
|
||||
a->used = 1;
|
||||
a->dp[0] = b;
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
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)
|
||||
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);
|
||||
|
||||
/* 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) {
|
||||
#ifdef HAVE_INTEL_AVX2
|
||||
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);
|
||||
|
||||
#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);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
sp_256_mul_4(s, s, p256_norm_order);
|
||||
}
|
||||
err = sp_256_mod_4(s, s, p256_order);
|
||||
}
|
||||
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) {
|
||||
#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);
|
||||
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
|
||||
#endif
|
||||
{
|
||||
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' */
|
||||
/* 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 */
|
||||
sp_256_mont_mul_4(u1, u2, p1->z, p256_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;
|
||||
}
|
||||
|
||||
#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
|
||||
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);
|
||||
if (ret != 0) {
|
||||
wc_ecc_free(&pub_key);
|
||||
goto done;
|
||||
return ret;
|
||||
}
|
||||
wc_ecc_set_flags(&pub_key, WC_ECC_FLAG_COFACTOR);
|
||||
wc_ecc_set_flags(&priv_key, WC_ECC_FLAG_COFACTOR);
|
||||
|
@ -18459,6 +18538,13 @@ int ecc_test(void)
|
|||
}
|
||||
#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
|
||||
ret = ecc_test_cdh_vectors();
|
||||
if (ret != 0) {
|
||||
|
|
|
@ -391,6 +391,10 @@ struct ecc_key {
|
|||
ecc_context_t ctx;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_ECDSA_SET_K
|
||||
mp_int *sign_k;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK_CACHE
|
||||
mp_int* t1;
|
||||
mp_int* t2;
|
||||
|
@ -470,6 +474,10 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
|||
WOLFSSL_API
|
||||
int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
|
||||
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 */
|
||||
|
||||
#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,
|
||||
word32* outlen, void* heap);
|
||||
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,
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue