Update pre9
This commit is contained in:
@@ -234,6 +234,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
||||
wnum.neg = 0;
|
||||
wnum.d = &(snum->d[loop]);
|
||||
wnum.top = div_n;
|
||||
wnum.flags = BN_FLG_STATIC_DATA;
|
||||
/*
|
||||
* only needed when BN_ucmp messes up the values between top and max
|
||||
*/
|
||||
|
||||
+26
-21
@@ -361,17 +361,17 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
ret = 1;
|
||||
goto err;
|
||||
}
|
||||
if (!BN_to_montgomery(val[0], aa, mont, ctx))
|
||||
if (!bn_to_mont_fixed_top(val[0], aa, mont, ctx))
|
||||
goto err; /* 1 */
|
||||
|
||||
window = BN_window_bits_for_exponent_size(bits);
|
||||
if (window > 1) {
|
||||
if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx))
|
||||
if (!bn_mul_mont_fixed_top(d, val[0], val[0], mont, ctx))
|
||||
goto err; /* 2 */
|
||||
j = 1 << (window - 1);
|
||||
for (i = 1; i < j; i++) {
|
||||
if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
|
||||
!BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx))
|
||||
!bn_mul_mont_fixed_top(val[i], val[i - 1], d, mont, ctx))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@@ -393,19 +393,15 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
for (i = 1; i < j; i++)
|
||||
r->d[i] = (~m->d[i]) & BN_MASK2;
|
||||
r->top = j;
|
||||
/*
|
||||
* Upper words will be zero if the corresponding words of 'm' were
|
||||
* 0xfff[...], so decrement r->top accordingly.
|
||||
*/
|
||||
bn_correct_top(r);
|
||||
r->flags |= BN_FLG_FIXED_TOP;
|
||||
} else
|
||||
#endif
|
||||
if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
|
||||
if (!bn_to_mont_fixed_top(r, BN_value_one(), mont, ctx))
|
||||
goto err;
|
||||
for (;;) {
|
||||
if (BN_is_bit_set(p, wstart) == 0) {
|
||||
if (!start) {
|
||||
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
|
||||
if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx))
|
||||
goto err;
|
||||
}
|
||||
if (wstart == 0)
|
||||
@@ -436,12 +432,12 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
/* add the 'bytes above' */
|
||||
if (!start)
|
||||
for (i = 0; i < j; i++) {
|
||||
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
|
||||
if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* wvalue will be an odd number < 2^window */
|
||||
if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx))
|
||||
if (!bn_mul_mont_fixed_top(r, r, val[wvalue >> 1], mont, ctx))
|
||||
goto err;
|
||||
|
||||
/* move the 'window' down further */
|
||||
@@ -451,6 +447,11 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
if (wstart < 0)
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery
|
||||
* removes padding [if any] and makes return value suitable for public
|
||||
* API consumer.
|
||||
*/
|
||||
#if defined(SPARC_T4_MONT)
|
||||
if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
|
||||
j = mont->N.top; /* borrow j */
|
||||
@@ -575,7 +576,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
|
||||
}
|
||||
|
||||
b->top = top;
|
||||
bn_correct_top(b);
|
||||
b->flags |= BN_FLG_FIXED_TOP;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -747,16 +748,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
tmp.top = top;
|
||||
} else
|
||||
#endif
|
||||
if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))
|
||||
if (!bn_to_mont_fixed_top(&tmp, BN_value_one(), mont, ctx))
|
||||
goto err;
|
||||
|
||||
/* prepare a^1 in Montgomery domain */
|
||||
if (a->neg || BN_ucmp(a, m) >= 0) {
|
||||
if (!BN_nnmod(&am, a, m, ctx))
|
||||
goto err;
|
||||
if (!BN_to_montgomery(&am, &am, mont, ctx))
|
||||
if (!bn_to_mont_fixed_top(&am, &am, mont, ctx))
|
||||
goto err;
|
||||
} else if (!BN_to_montgomery(&am, a, mont, ctx))
|
||||
} else if (!bn_to_mont_fixed_top(&am, a, mont, ctx))
|
||||
goto err;
|
||||
|
||||
#if defined(SPARC_T4_MONT)
|
||||
@@ -1034,14 +1035,14 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
* performance advantage of sqr over mul).
|
||||
*/
|
||||
if (window > 1) {
|
||||
if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
|
||||
if (!bn_mul_mont_fixed_top(&tmp, &am, &am, mont, ctx))
|
||||
goto err;
|
||||
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2,
|
||||
window))
|
||||
goto err;
|
||||
for (i = 3; i < numPowers; i++) {
|
||||
/* Calculate a^i = a^(i-1) * a */
|
||||
if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx))
|
||||
if (!bn_mul_mont_fixed_top(&tmp, &am, &tmp, mont, ctx))
|
||||
goto err;
|
||||
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i,
|
||||
window))
|
||||
@@ -1072,7 +1073,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
|
||||
/* Square the result window-size times */
|
||||
for (i = 0; i < window; i++)
|
||||
if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx))
|
||||
if (!bn_mul_mont_fixed_top(&tmp, &tmp, &tmp, mont, ctx))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
@@ -1095,12 +1096,16 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
|
||||
goto err;
|
||||
|
||||
/* Multiply the result into the intermediate result */
|
||||
if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
|
||||
if (!bn_mul_mont_fixed_top(&tmp, &tmp, &am, mont, ctx))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert the final result from montgomery to standard format */
|
||||
/*
|
||||
* Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery
|
||||
* removes padding [if any] and makes return value suitable for public
|
||||
* API consumer.
|
||||
*/
|
||||
#if defined(SPARC_T4_MONT)
|
||||
if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
|
||||
am.d[0] = 1; /* borrow am */
|
||||
|
||||
+17
-4
@@ -141,7 +141,16 @@
|
||||
*/
|
||||
|
||||
# ifdef BN_DEBUG
|
||||
# include <assert.h>
|
||||
/*
|
||||
* The new BN_FLG_FIXED_TOP flag marks vectors that were not treated with
|
||||
* bn_correct_top, in other words such vectors are permitted to have zeros
|
||||
* in most significant limbs. Such vectors are used internally to achieve
|
||||
* execution time invariance for critical operations with private keys.
|
||||
* It's BN_DEBUG-only flag, because user application is not supposed to
|
||||
* observe it anyway. Moreover, optimizing compiler would actually remove
|
||||
* all operations manipulating the bit in question in non-BN_DEBUG build.
|
||||
*/
|
||||
# define BN_FLG_FIXED_TOP 0x10000
|
||||
# ifdef BN_DEBUG_RAND
|
||||
# define bn_pollute(a) \
|
||||
do { \
|
||||
@@ -165,8 +174,10 @@
|
||||
do { \
|
||||
const BIGNUM *_bnum2 = (a); \
|
||||
if (_bnum2 != NULL) { \
|
||||
assert(((_bnum2->top == 0) && !_bnum2->neg) || \
|
||||
(_bnum2->top && (_bnum2->d[_bnum2->top - 1] != 0))); \
|
||||
int _top = _bnum2->top; \
|
||||
(void)ossl_assert((_top == 0 && !_bnum2->neg) || \
|
||||
(_top && ((_bnum2->flags & BN_FLG_FIXED_TOP) \
|
||||
|| _bnum2->d[_top - 1] != 0))); \
|
||||
bn_pollute(_bnum2); \
|
||||
} \
|
||||
} while(0)
|
||||
@@ -185,6 +196,7 @@
|
||||
|
||||
# else /* !BN_DEBUG */
|
||||
|
||||
# define BN_FLG_FIXED_TOP 0
|
||||
# define bn_pollute(a)
|
||||
# define bn_check_top(a)
|
||||
# define bn_fix_top(a) bn_correct_top(a)
|
||||
@@ -216,7 +228,8 @@ struct bignum_st {
|
||||
/* Used for montgomery multiplication */
|
||||
struct bn_mont_ctx_st {
|
||||
int ri; /* number of bits in R */
|
||||
BIGNUM RR; /* used to convert to montgomery form */
|
||||
BIGNUM RR; /* used to convert to montgomery form,
|
||||
possibly zero-padded */
|
||||
BIGNUM N; /* The modulus */
|
||||
BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 (Ni is only
|
||||
* stored for bignum algorithm) */
|
||||
|
||||
+28
-20
@@ -12,6 +12,7 @@
|
||||
#include "internal/cryptlib.h"
|
||||
#include "bn_lcl.h"
|
||||
#include <openssl/opensslconf.h>
|
||||
#include "internal/constant_time_locl.h"
|
||||
|
||||
/* This stuff appears to be completely unused, so is deprecated */
|
||||
#if OPENSSL_API_COMPAT < 0x00908000L
|
||||
@@ -209,8 +210,6 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
|
||||
{
|
||||
BN_ULONG *a = NULL;
|
||||
|
||||
bn_check_top(b);
|
||||
|
||||
if (words > (INT_MAX / (4 * BN_BITS2))) {
|
||||
BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
|
||||
return NULL;
|
||||
@@ -245,8 +244,6 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
|
||||
|
||||
BIGNUM *bn_expand2(BIGNUM *b, int words)
|
||||
{
|
||||
bn_check_top(b);
|
||||
|
||||
if (words > b->dmax) {
|
||||
BN_ULONG *a = bn_expand_internal(b, words);
|
||||
if (!a)
|
||||
@@ -259,7 +256,6 @@ BIGNUM *bn_expand2(BIGNUM *b, int words)
|
||||
b->dmax = words;
|
||||
}
|
||||
|
||||
bn_check_top(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
@@ -294,15 +290,17 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
|
||||
if (b->top > 0)
|
||||
memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
|
||||
|
||||
a->top = b->top;
|
||||
a->neg = b->neg;
|
||||
a->top = b->top;
|
||||
a->flags |= b->flags & BN_FLG_FIXED_TOP;
|
||||
bn_check_top(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
#define FLAGS_DATA(flags) ((flags) & (BN_FLG_STATIC_DATA \
|
||||
| BN_FLG_CONSTTIME \
|
||||
| BN_FLG_SECURE))
|
||||
| BN_FLG_SECURE \
|
||||
| BN_FLG_FIXED_TOP))
|
||||
#define FLAGS_STRUCT(flags) ((flags) & (BN_FLG_MALLOCED))
|
||||
|
||||
void BN_swap(BIGNUM *a, BIGNUM *b)
|
||||
@@ -343,8 +341,9 @@ void BN_clear(BIGNUM *a)
|
||||
bn_check_top(a);
|
||||
if (a->d != NULL)
|
||||
OPENSSL_cleanse(a->d, sizeof(*a->d) * a->dmax);
|
||||
a->top = 0;
|
||||
a->neg = 0;
|
||||
a->top = 0;
|
||||
a->flags &= ~BN_FLG_FIXED_TOP;
|
||||
}
|
||||
|
||||
BN_ULONG BN_get_word(const BIGNUM *a)
|
||||
@@ -365,6 +364,7 @@ int BN_set_word(BIGNUM *a, BN_ULONG w)
|
||||
a->neg = 0;
|
||||
a->d[0] = w;
|
||||
a->top = (w ? 1 : 0);
|
||||
a->flags &= ~BN_FLG_FIXED_TOP;
|
||||
bn_check_top(a);
|
||||
return 1;
|
||||
}
|
||||
@@ -417,24 +417,29 @@ BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
|
||||
/* ignore negative */
|
||||
static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
|
||||
{
|
||||
int i;
|
||||
int n;
|
||||
size_t i, inc, lasti, j;
|
||||
BN_ULONG l;
|
||||
|
||||
bn_check_top(a);
|
||||
i = BN_num_bytes(a);
|
||||
n = BN_num_bytes(a);
|
||||
if (tolen == -1)
|
||||
tolen = i;
|
||||
else if (tolen < i)
|
||||
tolen = n;
|
||||
else if (tolen < n)
|
||||
return -1;
|
||||
/* Add leading zeroes if necessary */
|
||||
if (tolen > i) {
|
||||
memset(to, 0, tolen - i);
|
||||
to += tolen - i;
|
||||
|
||||
if (n == 0) {
|
||||
OPENSSL_cleanse(to, tolen);
|
||||
return tolen;
|
||||
}
|
||||
while (i--) {
|
||||
|
||||
lasti = n - 1;
|
||||
for (i = 0, inc = 1, j = tolen; j > 0;) {
|
||||
l = a->d[i / BN_BYTES];
|
||||
*(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
|
||||
to[--j] = (unsigned char)(l >> (8 * (i % BN_BYTES)) & (0 - inc));
|
||||
inc = (i - lasti) >> (8 * sizeof(i) - 1);
|
||||
i += inc; /* stay on top limb */
|
||||
}
|
||||
|
||||
return tolen;
|
||||
}
|
||||
|
||||
@@ -601,6 +606,7 @@ int BN_set_bit(BIGNUM *a, int n)
|
||||
for (k = a->top; k < i + 1; k++)
|
||||
a->d[k] = 0;
|
||||
a->top = i + 1;
|
||||
a->flags &= ~BN_FLG_FIXED_TOP;
|
||||
}
|
||||
|
||||
a->d[i] |= (((BN_ULONG)1) << j);
|
||||
@@ -833,8 +839,9 @@ int BN_security_bits(int L, int N)
|
||||
|
||||
void BN_zero_ex(BIGNUM *a)
|
||||
{
|
||||
a->top = 0;
|
||||
a->neg = 0;
|
||||
a->top = 0;
|
||||
a->flags &= ~BN_FLG_FIXED_TOP;
|
||||
}
|
||||
|
||||
int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
|
||||
@@ -958,5 +965,6 @@ void bn_correct_top(BIGNUM *a)
|
||||
}
|
||||
if (a->top == 0)
|
||||
a->neg = 0;
|
||||
a->flags &= ~BN_FLG_FIXED_TOP;
|
||||
bn_pollute(a);
|
||||
}
|
||||
+60
-6
@@ -35,16 +35,70 @@ int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
|
||||
|
||||
/*
|
||||
* BN_mod_add variant that may be used if both a and b are non-negative and
|
||||
* less than m
|
||||
* less than m. The original algorithm was
|
||||
*
|
||||
* if (!BN_uadd(r, a, b))
|
||||
* return 0;
|
||||
* if (BN_ucmp(r, m) >= 0)
|
||||
* return BN_usub(r, r, m);
|
||||
*
|
||||
* which is replaced with addition, subtracting modulus, and conditional
|
||||
* move depending on whether or not subtraction borrowed.
|
||||
*/
|
||||
int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
const BIGNUM *m)
|
||||
{
|
||||
size_t i, ai, bi, mtop = m->top;
|
||||
BN_ULONG storage[1024 / BN_BITS2];
|
||||
BN_ULONG carry, temp, mask, *rp, *tp = storage;
|
||||
const BN_ULONG *ap, *bp;
|
||||
|
||||
if (bn_wexpand(r, mtop) == NULL)
|
||||
return 0;
|
||||
|
||||
if (mtop > sizeof(storage) / sizeof(storage[0])
|
||||
&& (tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG))) == NULL)
|
||||
return 0;
|
||||
|
||||
ap = a->d != NULL ? a->d : tp;
|
||||
bp = b->d != NULL ? b->d : tp;
|
||||
|
||||
for (i = 0, ai = 0, bi = 0, carry = 0; i < mtop;) {
|
||||
mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1));
|
||||
temp = ((ap[ai] & mask) + carry) & BN_MASK2;
|
||||
carry = (temp < carry);
|
||||
|
||||
mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1));
|
||||
tp[i] = ((bp[bi] & mask) + temp) & BN_MASK2;
|
||||
carry += (tp[i] < temp);
|
||||
|
||||
i++;
|
||||
ai += (i - a->dmax) >> (8 * sizeof(i) - 1);
|
||||
bi += (i - b->dmax) >> (8 * sizeof(i) - 1);
|
||||
}
|
||||
rp = r->d;
|
||||
carry -= bn_sub_words(rp, tp, m->d, mtop);
|
||||
for (i = 0; i < mtop; i++) {
|
||||
rp[i] = (carry & tp[i]) | (~carry & rp[i]);
|
||||
((volatile BN_ULONG *)tp)[i] = 0;
|
||||
}
|
||||
r->top = mtop;
|
||||
|
||||
if (tp != storage)
|
||||
OPENSSL_free(tp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
const BIGNUM *m)
|
||||
{
|
||||
if (!BN_uadd(r, a, b))
|
||||
return 0;
|
||||
if (BN_ucmp(r, m) >= 0)
|
||||
return BN_usub(r, r, m);
|
||||
return 1;
|
||||
int ret = bn_mod_add_fixed_top(r, a, b, m);
|
||||
|
||||
if (ret)
|
||||
bn_correct_top(r);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
|
||||
|
||||
+43
-20
@@ -20,29 +20,43 @@
|
||||
#define MONT_WORD /* use the faster word-based algorithm */
|
||||
|
||||
#ifdef MONT_WORD
|
||||
static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
|
||||
static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
|
||||
#endif
|
||||
|
||||
int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
BN_MONT_CTX *mont, BN_CTX *ctx)
|
||||
{
|
||||
int ret = bn_mul_mont_fixed_top(r, a, b, mont, ctx);
|
||||
|
||||
bn_correct_top(r);
|
||||
bn_check_top(r);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
BN_MONT_CTX *mont, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *tmp;
|
||||
int ret = 0;
|
||||
#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
|
||||
int num = mont->N.top;
|
||||
|
||||
#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
|
||||
if (num > 1 && a->top == num && b->top == num) {
|
||||
if (bn_wexpand(r, num) == NULL)
|
||||
return 0;
|
||||
if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {
|
||||
r->neg = a->neg ^ b->neg;
|
||||
r->top = num;
|
||||
bn_correct_top(r);
|
||||
r->flags |= BN_FLG_FIXED_TOP;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((a->top + b->top) > 2 * num)
|
||||
return 0;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
tmp = BN_CTX_get(ctx);
|
||||
if (tmp == NULL)
|
||||
@@ -58,13 +72,12 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
}
|
||||
/* reduce from aRR to aR */
|
||||
#ifdef MONT_WORD
|
||||
if (!BN_from_montgomery_word(r, tmp, mont))
|
||||
if (!bn_from_montgomery_word(r, tmp, mont))
|
||||
goto err;
|
||||
#else
|
||||
if (!BN_from_montgomery(r, tmp, mont, ctx))
|
||||
goto err;
|
||||
#endif
|
||||
bn_check_top(r);
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
@@ -72,7 +85,7 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
|
||||
}
|
||||
|
||||
#ifdef MONT_WORD
|
||||
static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
|
||||
static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
|
||||
{
|
||||
BIGNUM *n;
|
||||
BN_ULONG *ap, *np, *rp, n0, v, carry;
|
||||
@@ -95,12 +108,11 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
|
||||
|
||||
/* clear the top words of T */
|
||||
i = max - r->top;
|
||||
if (i < 0)
|
||||
return 0;
|
||||
if (i)
|
||||
memset(&rp[r->top], 0, sizeof(*rp) * i);
|
||||
|
||||
r->top = max;
|
||||
r->flags |= BN_FLG_FIXED_TOP;
|
||||
n0 = mont->n0[0];
|
||||
|
||||
/*
|
||||
@@ -119,6 +131,7 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
|
||||
if (bn_wexpand(ret, nl) == NULL)
|
||||
return 0;
|
||||
ret->top = nl;
|
||||
ret->flags |= BN_FLG_FIXED_TOP;
|
||||
ret->neg = r->neg;
|
||||
|
||||
rp = ret->d;
|
||||
@@ -129,20 +142,16 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
|
||||
*/
|
||||
ap = &(r->d[nl]);
|
||||
|
||||
carry -= bn_sub_words(rp, ap, np, nl);
|
||||
/*
|
||||
* |v| is one if |ap| - |np| underflowed or zero if it did not. Note |v|
|
||||
* cannot be -1. That would imply the subtraction did not fit in |nl| words,
|
||||
* and we know at most one subtraction is needed.
|
||||
* |carry| is -1 if |ap| - |np| underflowed or zero if it did not. Note
|
||||
* |carry| cannot be 1. That would imply the subtraction did not fit in
|
||||
* |nl| words, and we know at most one subtraction is needed.
|
||||
*/
|
||||
v = bn_sub_words(rp, ap, np, nl) - carry;
|
||||
v = 0 - v;
|
||||
for (i = 0; i < nl; i++) {
|
||||
rp[i] = (v & ap[i]) | (~v & rp[i]);
|
||||
rp[i] = (carry & ap[i]) | (~carry & rp[i]);
|
||||
ap[i] = 0;
|
||||
}
|
||||
bn_correct_top(r);
|
||||
bn_correct_top(ret);
|
||||
bn_check_top(ret);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -156,8 +165,11 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
|
||||
BIGNUM *t;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((t = BN_CTX_get(ctx)) && BN_copy(t, a))
|
||||
retn = BN_from_montgomery_word(ret, t, mont);
|
||||
if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) {
|
||||
retn = bn_from_montgomery_word(ret, t, mont);
|
||||
bn_correct_top(ret);
|
||||
bn_check_top(ret);
|
||||
}
|
||||
BN_CTX_end(ctx);
|
||||
#else /* !MONT_WORD */
|
||||
BIGNUM *t1, *t2;
|
||||
@@ -195,6 +207,12 @@ int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
|
||||
return retn;
|
||||
}
|
||||
|
||||
int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
return bn_mul_mont_fixed_top(r, a, &(mont->RR), mont, ctx);
|
||||
}
|
||||
|
||||
BN_MONT_CTX *BN_MONT_CTX_new(void)
|
||||
{
|
||||
BN_MONT_CTX *ret;
|
||||
@@ -232,7 +250,7 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont)
|
||||
|
||||
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
int i, ret = 0;
|
||||
BIGNUM *Ri, *R;
|
||||
|
||||
if (BN_is_zero(mod))
|
||||
@@ -367,6 +385,11 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
|
||||
if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx))
|
||||
goto err;
|
||||
|
||||
for (i = mont->RR.top, ret = mont->N.top; i < ret; i++)
|
||||
mont->RR.d[i] = 0;
|
||||
mont->RR.top = ret;
|
||||
mont->RR.flags |= BN_FLG_FIXED_TOP;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
|
||||
+1
-1
@@ -254,7 +254,7 @@ static void nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max)
|
||||
int i;
|
||||
|
||||
#ifdef BN_DEBUG
|
||||
assert(top <= max);
|
||||
(void)ossl_assert(top <= max);
|
||||
#endif
|
||||
for (i = 0; i < top; i++)
|
||||
dst[i] = src[i];
|
||||
|
||||
+2
-8
@@ -82,14 +82,8 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
|
||||
}
|
||||
|
||||
rr->neg = 0;
|
||||
/*
|
||||
* If the most-significant half of the top word of 'a' is zero, then the
|
||||
* square of 'a' will max-1 words.
|
||||
*/
|
||||
if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
|
||||
rr->top = max - 1;
|
||||
else
|
||||
rr->top = max;
|
||||
rr->top = max;
|
||||
bn_correct_top(rr);
|
||||
if (r != rr && BN_copy(r, rr) == NULL)
|
||||
goto err;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user