mirror of https://github.com/wolfSSL/wolfssl.git
Merge pull request #3736 from SparkiDev/sp_int_neg_zero
SP int neg: fix handling of negative zero and mp_cond_copypull/3713/head
commit
fc30f379ee
|
@ -1991,6 +1991,20 @@ WOLFSSL_LOCAL int sp_ModExp_4096(sp_int* base, sp_int* exp, sp_int* mod,
|
|||
static int _sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp);
|
||||
#endif
|
||||
|
||||
/* Set the multi-precision number to zero.
|
||||
*
|
||||
* Assumes a is not NULL.
|
||||
*
|
||||
* @param [out] a SP integer to set to zero.
|
||||
*/
|
||||
static void _sp_zero(sp_int* a)
|
||||
{
|
||||
a->used = 0;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
a->sign = MP_ZPOS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize the multi-precision number to be zero.
|
||||
*
|
||||
* @param [out] a SP integer.
|
||||
|
@ -2006,11 +2020,8 @@ int sp_init(sp_int* a)
|
|||
err = MP_VAL;
|
||||
}
|
||||
if (err == MP_OKAY) {
|
||||
a->used = 0;
|
||||
_sp_zero(a);
|
||||
a->size = SP_INT_DIGITS;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
a->sign = MP_ZPOS;
|
||||
#endif
|
||||
#ifdef HAVE_WOLF_BIGINT
|
||||
wc_bigint_init(&a->raw);
|
||||
#endif
|
||||
|
@ -2046,46 +2057,34 @@ int sp_init_multi(sp_int* n1, sp_int* n2, sp_int* n3, sp_int* n4, sp_int* n5,
|
|||
sp_int* n6)
|
||||
{
|
||||
if (n1 != NULL) {
|
||||
n1->used = 0;
|
||||
_sp_zero(n1);
|
||||
n1->dp[0] = 0;
|
||||
n1->size = SP_INT_DIGITS;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
n1->sign = MP_ZPOS;
|
||||
#endif
|
||||
}
|
||||
if (n2 != NULL) {
|
||||
n2->used = 0;
|
||||
_sp_zero(n2);
|
||||
n2->dp[0] = 0;
|
||||
n2->size = SP_INT_DIGITS;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
n2->sign = MP_ZPOS;
|
||||
#endif
|
||||
}
|
||||
if (n3 != NULL) {
|
||||
n3->used = 0;
|
||||
_sp_zero(n3);
|
||||
n3->dp[0] = 0;
|
||||
n3->size = SP_INT_DIGITS;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
n3->sign = MP_ZPOS;
|
||||
#endif
|
||||
}
|
||||
if (n4 != NULL) {
|
||||
n4->used = 0;
|
||||
_sp_zero(n4);
|
||||
n4->dp[0] = 0;
|
||||
n4->size = SP_INT_DIGITS;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
n4->sign = MP_ZPOS;
|
||||
#endif
|
||||
}
|
||||
if (n5 != NULL) {
|
||||
n5->used = 0;
|
||||
_sp_zero(n5);
|
||||
n5->dp[0] = 0;
|
||||
n5->size = SP_INT_DIGITS;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
n5->sign = MP_ZPOS;
|
||||
#endif
|
||||
}
|
||||
if (n6 != NULL) {
|
||||
n6->used = 0;
|
||||
_sp_zero(n6);
|
||||
n6->dp[0] = 0;
|
||||
n6->size = SP_INT_DIGITS;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
n6->sign = MP_ZPOS;
|
||||
#endif
|
||||
}
|
||||
|
||||
return MP_OKAY;
|
||||
|
@ -2137,21 +2136,6 @@ int sp_grow(sp_int* a, int l)
|
|||
}
|
||||
#endif /* !WOLFSSL_RSA_VERIFY_ONLY || !NO_DH || HAVE_ECC */
|
||||
|
||||
/* Set the multi-precision number to zero.
|
||||
*
|
||||
* Assumes a is not NULL.
|
||||
*
|
||||
* @param [out] a SP integer to set to zero.
|
||||
*/
|
||||
static void _sp_zero(sp_int* a)
|
||||
{
|
||||
a->dp[0] = 0;
|
||||
a->used = 0;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
a->sign = MP_ZPOS;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(WOLFSSL_RSA_VERIFY_ONLY)
|
||||
/* Set the multi-precision number to zero.
|
||||
*
|
||||
|
@ -2177,10 +2161,7 @@ void sp_clear(sp_int* a)
|
|||
for (i = 0; i < a->used; i++) {
|
||||
a->dp[i] = 0;
|
||||
}
|
||||
a->used = 0;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
a->sign = MP_ZPOS;
|
||||
#endif
|
||||
_sp_zero(a);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2194,10 +2175,7 @@ void sp_clear(sp_int* a)
|
|||
void sp_forcezero(sp_int* a)
|
||||
{
|
||||
ForceZero(a->dp, a->used * sizeof(sp_int_digit));
|
||||
a->used = 0;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
a->sign = MP_ZPOS;
|
||||
#endif
|
||||
_sp_zero(a);
|
||||
#ifdef HAVE_WOLF_BIGINT
|
||||
wc_bigint_zero(&a->raw);
|
||||
#endif
|
||||
|
@ -2323,14 +2301,23 @@ int sp_cond_swap_ct(sp_int * a, sp_int * b, int c, int m)
|
|||
#endif
|
||||
|
||||
t->used = (int)((a->used ^ b->used) & mask);
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
t->sign = (int)((a->sign ^ b->sign) & mask);
|
||||
#endif
|
||||
for (i = 0; i < c; i++) {
|
||||
t->dp[i] = (a->dp[i] ^ b->dp[i]) & mask;
|
||||
}
|
||||
a->used ^= t->used;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
a->sign ^= t->sign;
|
||||
#endif
|
||||
for (i = 0; i < c; i++) {
|
||||
a->dp[i] ^= t->dp[i];
|
||||
}
|
||||
b->used ^= t->used;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
b->sign ^= b->sign;
|
||||
#endif
|
||||
for (i = 0; i < c; i++) {
|
||||
b->dp[i] ^= t->dp[i];
|
||||
}
|
||||
|
@ -2709,12 +2696,12 @@ int sp_set_bit(sp_int* a, int i)
|
|||
*/
|
||||
int sp_2expt(sp_int* a, int e)
|
||||
{
|
||||
int err = 0;
|
||||
int err = MP_OKAY;
|
||||
|
||||
if (a == NULL) {
|
||||
err = MP_VAL;
|
||||
}
|
||||
else {
|
||||
if (err == MP_OKAY) {
|
||||
_sp_zero(a);
|
||||
err = sp_set_bit(a, e);
|
||||
}
|
||||
|
@ -2973,7 +2960,7 @@ int sp_add_d(sp_int* a, sp_int_digit d, sp_int* r)
|
|||
r->sign = MP_ZPOS;
|
||||
err = _sp_add_d(a, d, r);
|
||||
}
|
||||
else if ((a->used > 1) || (a->dp[0] >= d)) {
|
||||
else if ((a->used > 1) || (a->dp[0] > d)) {
|
||||
r->sign = MP_NEG;
|
||||
_sp_sub_d(a, d, r);
|
||||
}
|
||||
|
@ -3097,7 +3084,12 @@ int sp_mul_d(sp_int* a, sp_int_digit d, sp_int* r)
|
|||
if (err == MP_OKAY) {
|
||||
_sp_mul_d(a, d, r, 0);
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
if (d == 0) {
|
||||
r->sign = MP_ZPOS;
|
||||
}
|
||||
else {
|
||||
r->sign = a->sign;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3724,12 +3716,22 @@ int sp_add(sp_int* a, sp_int* b, sp_int* r)
|
|||
err = _sp_add_off(a, b, r, 0);
|
||||
}
|
||||
else if (_sp_cmp_abs(a, b) != MP_LT) {
|
||||
r->sign = a->sign;
|
||||
err = _sp_sub_off(a, b, r, 0);
|
||||
if (sp_iszero(r)) {
|
||||
r->sign = MP_ZPOS;
|
||||
}
|
||||
else {
|
||||
r->sign = a->sign;
|
||||
}
|
||||
}
|
||||
else {
|
||||
err = _sp_sub_off(b, a, r, 0);
|
||||
if (sp_iszero(r)) {
|
||||
r->sign = MP_ZPOS;
|
||||
}
|
||||
else {
|
||||
r->sign = b->sign;
|
||||
err = _sp_sub_off(b, a, r, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -3767,12 +3769,22 @@ int sp_sub(sp_int* a, sp_int* b, sp_int* r)
|
|||
err = _sp_add_off(a, b, r, 0);
|
||||
}
|
||||
else if (_sp_cmp_abs(a, b) != MP_LT) {
|
||||
r->sign = a->sign;
|
||||
err = _sp_sub_off(a, b, r, 0);
|
||||
if (sp_iszero(r)) {
|
||||
r->sign = MP_ZPOS;
|
||||
}
|
||||
else {
|
||||
r->sign = a->sign;
|
||||
}
|
||||
}
|
||||
else {
|
||||
err = _sp_sub_off(b, a, r, 0);
|
||||
if (sp_iszero(r)) {
|
||||
r->sign = MP_ZPOS;
|
||||
}
|
||||
else {
|
||||
r->sign = 1 - a->sign;
|
||||
err = _sp_sub_off(b, a, r, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -4205,8 +4217,7 @@ void sp_rshd(sp_int* a, int c)
|
|||
int j;
|
||||
|
||||
if (c >= a->used) {
|
||||
a->dp[0] = 0;
|
||||
a->used = 0;
|
||||
_sp_zero(a);
|
||||
}
|
||||
else {
|
||||
for (i = c, j = 0; i < a->used; i++, j++) {
|
||||
|
@ -4233,11 +4244,7 @@ void sp_rshb(sp_int* a, int n, sp_int* r)
|
|||
int i = n >> SP_WORD_SHIFT;
|
||||
|
||||
if (i >= a->used) {
|
||||
r->dp[0] = 0;
|
||||
r->used = 0;
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
r->sign = MP_ZPOS;
|
||||
#endif
|
||||
_sp_zero(r);
|
||||
}
|
||||
else {
|
||||
int j;
|
||||
|
@ -4256,7 +4263,12 @@ void sp_rshb(sp_int* a, int n, sp_int* r)
|
|||
sp_clamp(r);
|
||||
}
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
if (sp_iszero(r)) {
|
||||
r->sign = MP_ZPOS;
|
||||
}
|
||||
else {
|
||||
r->sign = a->sign;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -4491,12 +4503,22 @@ int sp_div(sp_int* a, sp_int* d, sp_int* r, sp_int* rem)
|
|||
}
|
||||
sp_copy(sa, rem);
|
||||
sp_clamp(rem);
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
if (sp_iszero(rem)) {
|
||||
rem->sign = MP_ZPOS;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (r != NULL) {
|
||||
sp_copy(tr, r);
|
||||
sp_clamp(r);
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
if (sp_iszero(r)) {
|
||||
r->sign = MP_ZPOS;
|
||||
}
|
||||
else {
|
||||
r->sign = (aSign == dSign) ? MP_ZPOS : MP_NEG;
|
||||
}
|
||||
#endif /* WOLFSSL_SP_INT_NEGATIVE */
|
||||
}
|
||||
}
|
||||
|
@ -9296,7 +9318,7 @@ int sp_div_2d(sp_int* a, int e, sp_int* r, sp_int* rem)
|
|||
|
||||
if (remBits <= 0) {
|
||||
/* Shifting down by more bits than in number. */
|
||||
sp_set(r, 0);
|
||||
_sp_zero(r);
|
||||
sp_copy(a, rem);
|
||||
}
|
||||
else {
|
||||
|
@ -9314,6 +9336,9 @@ int sp_div_2d(sp_int* a, int e, sp_int* r, sp_int* rem)
|
|||
rem->dp[rem->used - 1] &= ((sp_int_digit)1 << e) - 1;
|
||||
}
|
||||
sp_clamp(rem);
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
rem->sign = MP_ZPOS;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9344,9 +9369,6 @@ int sp_mod_2d(sp_int* a, int e, sp_int* r)
|
|||
int digits = (e + SP_WORD_SIZE - 1) >> SP_WORD_SHIFT;
|
||||
if (a != r) {
|
||||
XMEMCPY(r->dp, a->dp, digits * sizeof(sp_int_digit));
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
r->sign = a->sign;
|
||||
#endif /* WOLFSSL_SP_INT_NEGATIVE */
|
||||
}
|
||||
/* Set used and mask off top digit of result. */
|
||||
r->used = digits;
|
||||
|
@ -9355,6 +9377,14 @@ int sp_mod_2d(sp_int* a, int e, sp_int* r)
|
|||
r->dp[r->used - 1] &= ((sp_int_digit)1 << e) - 1;
|
||||
}
|
||||
sp_clamp(r);
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
if (sp_iszero(r)) {
|
||||
r->sign = MP_ZPOS;
|
||||
}
|
||||
else if (a != r) {
|
||||
r->sign = a->sign;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -12653,8 +12683,12 @@ static int _sp_read_radix_16(sp_int* a, const char* in)
|
|||
if (err == MP_OKAY) {
|
||||
a->used = j + 1;
|
||||
sp_clamp(a);
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
if (sp_iszero(a)) {
|
||||
a->sign = MP_ZPOS;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif /* (WOLFSSL_SP_MATH_ALL && !WOLFSSL_RSA_VERIFY_ONLY) || HAVE_ECC */
|
||||
|
@ -12679,6 +12713,7 @@ static int _sp_read_radix_10(sp_int* a, const char* in)
|
|||
int len;
|
||||
char ch;
|
||||
|
||||
_sp_zero(a);
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
if (*in == '-') {
|
||||
a->sign = MP_NEG;
|
||||
|
@ -12690,8 +12725,6 @@ static int _sp_read_radix_10(sp_int* a, const char* in)
|
|||
in++;
|
||||
}
|
||||
|
||||
a->dp[0] = 0;
|
||||
a->used = 0;
|
||||
len = (int)XSTRLEN(in);
|
||||
for (i = 0; i < len; i++) {
|
||||
ch = in[i];
|
||||
|
@ -12709,6 +12742,11 @@ static int _sp_read_radix_10(sp_int* a, const char* in)
|
|||
_sp_mul_d(a, 10, a, 0);
|
||||
(void)_sp_add_d(a, ch, a);
|
||||
}
|
||||
#ifdef WOLFSSL_SP_INT_NEGATIVE
|
||||
if ((err == MP_OKAY) && sp_iszero(a)) {
|
||||
a->sign = MP_ZPOS;
|
||||
}
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -122,6 +122,10 @@ int mp_cond_copy(mp_int* a, int copy, mp_int* b)
|
|||
b->dp[i] ^= (get_digit(a, i) ^ get_digit(b, i)) & mask;
|
||||
}
|
||||
b->used ^= (a->used ^ b->used) & (int)mask;
|
||||
#if (!defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_SP_MATH_ALL)) || \
|
||||
defined(WOLFSSL_SP_INT_NEGATIVE)
|
||||
b->sign ^= (a->sign ^ b->sign) & (int)mask;
|
||||
#endif
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
|
@ -500,6 +500,8 @@ typedef struct sp_ecc_ctx {
|
|||
* @return 0 when not zero.
|
||||
*/
|
||||
#define sp_iszero(a) ((a)->used == 0)
|
||||
|
||||
#ifndef WOLFSSL_SP_INT_NEGATIVE
|
||||
/* Returns whether multi-precision number has the value one.
|
||||
*
|
||||
* Assumes a is not NULL.
|
||||
|
@ -509,6 +511,20 @@ typedef struct sp_ecc_ctx {
|
|||
* @return 0 when not one.
|
||||
*/
|
||||
#define sp_isone(a) (((a)->used == 1) && ((a)->dp[0] == 1))
|
||||
#else
|
||||
/* Returns whether multi-precision number has the value of positive one.
|
||||
*
|
||||
* Assumes a is not NULL.
|
||||
*
|
||||
* @param [in] a SP integer to check.
|
||||
* @return 1 when one.
|
||||
* @return 0 when not one.
|
||||
*/
|
||||
#define sp_isone(a) \
|
||||
(((a)->used == 1) && ((a)->dp[0] == 1) && ((a)->sign == MP_ZPOS))
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_SP_INT_NEGATIVE
|
||||
/* Returns whether multi-precision number has the value 'd'.
|
||||
*
|
||||
* Assumes a is not NULL.
|
||||
|
@ -518,7 +534,23 @@ typedef struct sp_ecc_ctx {
|
|||
* @return 1 when one.
|
||||
* @return 0 when not one.
|
||||
*/
|
||||
#define sp_isword(a, d) (((a)->used == 1) && ((a)->dp[0] == d))
|
||||
#define sp_isword(a, d) \
|
||||
((((d) == 0) && sp_iszero(a)) || (((a)->used == 1) && ((a)->dp[0] == (d))))
|
||||
#else
|
||||
/* Returns whether multi-precision number has the value 'd'.
|
||||
*
|
||||
* Assumes a is not NULL.
|
||||
*
|
||||
* @param [in] a SP integer to check.
|
||||
* @param [in] d SP integer digit.
|
||||
* @return 1 when one.
|
||||
* @return 0 when not one.
|
||||
*/
|
||||
#define sp_isword(a, d) \
|
||||
((((d) == 0) && sp_iszero(a)) || \
|
||||
(((a)->used == 1) && ((a)->dp[0] == (d)) && ((a)->sign == MP_ZPOS)))
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_SP_INT_NEGATIVE
|
||||
/* Calculate the absolute value of the multi-precision number.
|
||||
*
|
||||
|
@ -552,6 +584,7 @@ typedef struct sp_ecc_ctx {
|
|||
*/
|
||||
#define sp_isneg(a) ((a)->sign == MP_NEG)
|
||||
#endif
|
||||
|
||||
/* Updates the used count to exclude leading zeros.
|
||||
*
|
||||
* Assumes a is not NULL.
|
||||
|
|
Loading…
Reference in New Issue