Remove redundant BN_ucmp, fix boundary condition in BN_nist_mod_224 and
reimplement BN_nist_mod_521.
This commit is contained in:
parent
28b6d5020e
commit
762a2e3cab
@ -345,11 +345,6 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
|
|||||||
r->top = BN_NIST_192_TOP;
|
r->top = BN_NIST_192_TOP;
|
||||||
bn_correct_top(r);
|
bn_correct_top(r);
|
||||||
|
|
||||||
if (BN_ucmp(field, r) <= 0)
|
|
||||||
{
|
|
||||||
if (!BN_usub(r, r, field)) return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +376,7 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
|
|||||||
|
|
||||||
field = &_bignum_nist_p_224; /* just to make sure */
|
field = &_bignum_nist_p_224; /* just to make sure */
|
||||||
|
|
||||||
if (BN_is_negative(a) || a->top > 2*BN_NIST_224_TOP)
|
if (BN_is_negative(a) || a->top > (2*224+BN_BITS2-1)/BN_BITS2)
|
||||||
return BN_nnmod(r, field, a, ctx);
|
return BN_nnmod(r, field, a, ctx);
|
||||||
|
|
||||||
i = BN_ucmp(field, a);
|
i = BN_ucmp(field, a);
|
||||||
@ -456,11 +451,6 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
|
|||||||
r->top = BN_NIST_224_TOP;
|
r->top = BN_NIST_224_TOP;
|
||||||
bn_correct_top(r);
|
bn_correct_top(r);
|
||||||
|
|
||||||
if (BN_ucmp(field, r) <= 0)
|
|
||||||
{
|
|
||||||
if (!BN_usub(r, r, field)) return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,11 +564,6 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
|
|||||||
r->top = BN_NIST_256_TOP;
|
r->top = BN_NIST_256_TOP;
|
||||||
bn_correct_top(r);
|
bn_correct_top(r);
|
||||||
|
|
||||||
if (BN_ucmp(field, r) <= 0)
|
|
||||||
{
|
|
||||||
if (!BN_usub(r, r, field)) return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,81 +683,65 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
|
|||||||
r->top = BN_NIST_384_TOP;
|
r->top = BN_NIST_384_TOP;
|
||||||
bn_correct_top(r);
|
bn_correct_top(r);
|
||||||
|
|
||||||
if (BN_ucmp(field, r) <= 0)
|
|
||||||
{
|
|
||||||
if (!BN_usub(r, r, field)) return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BN_NIST_521_RSHIFT (521%BN_BITS2)
|
||||||
|
#define BN_NIST_521_LSHIFT (BN_BITS2-BN_NIST_521_RSHIFT)
|
||||||
|
#define BN_NIST_521_TOP_MASK ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
|
||||||
|
|
||||||
int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
|
int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
|
||||||
BN_CTX *ctx)
|
BN_CTX *ctx)
|
||||||
{
|
{
|
||||||
#if BN_BITS2 == 64
|
int top = a->top, i;
|
||||||
#define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF
|
BN_ULONG *r_d, *a_d = a->d,
|
||||||
#elif BN_BITS2 == 32
|
t_d[BN_NIST_521_TOP],
|
||||||
#define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF
|
val,tmp,*res;
|
||||||
#endif
|
size_t mask;
|
||||||
int top, ret = 0;
|
|
||||||
BIGNUM *tmp;
|
|
||||||
|
|
||||||
field = &_bignum_nist_p_521; /* just to make sure */
|
field = &_bignum_nist_p_521; /* just to make sure */
|
||||||
|
|
||||||
if (BN_is_negative(a))
|
if (BN_is_negative(a) || BN_num_bits(a)>2*521)
|
||||||
return BN_nnmod(r, field, a, ctx);
|
return BN_nnmod(r, field, a, ctx);
|
||||||
|
|
||||||
/* check whether a reduction is necessary */
|
i = BN_ucmp(field, a);
|
||||||
top = a->top;
|
if (i == 0)
|
||||||
if (top < BN_NIST_521_TOP || ( top == BN_NIST_521_TOP &&
|
|
||||||
(!(a->d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK)))))
|
|
||||||
{
|
{
|
||||||
int i = BN_ucmp(field, a);
|
BN_zero(r);
|
||||||
if (i == 0)
|
return 1;
|
||||||
{
|
|
||||||
BN_zero(r);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef BN_DEBUG
|
|
||||||
OPENSSL_assert(i > 0); /* because 'field' is 1111...1111 */
|
|
||||||
#endif
|
|
||||||
return (r == a)? 1 : (BN_copy(r ,a) != NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (i > 0)
|
||||||
|
return (r == a)? 1 : (BN_copy(r ,a) != NULL);
|
||||||
|
|
||||||
if (BN_num_bits(a) > 2*521)
|
if (r != a)
|
||||||
return BN_nnmod(r, field, a, ctx);
|
|
||||||
|
|
||||||
BN_CTX_start(ctx);
|
|
||||||
tmp = BN_CTX_get(ctx);
|
|
||||||
if (!tmp)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (!bn_wexpand(tmp, BN_NIST_521_TOP))
|
|
||||||
goto err;
|
|
||||||
nist_cp_bn(tmp->d, a->d, BN_NIST_521_TOP);
|
|
||||||
|
|
||||||
tmp->top = BN_NIST_521_TOP;
|
|
||||||
tmp->d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK;
|
|
||||||
bn_correct_top(tmp);
|
|
||||||
|
|
||||||
if (!BN_rshift(r, a, 521))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (!BN_uadd(r, tmp, r))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (BN_ucmp(field, r) <= 0)
|
|
||||||
{
|
{
|
||||||
if (!BN_usub(r, r, field)) goto err;
|
if (!bn_wexpand(r,BN_NIST_521_TOP))
|
||||||
|
return 0;
|
||||||
|
r_d = r->d;
|
||||||
|
nist_cp_bn(r_d,a_d, BN_NIST_521_TOP);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
r_d = a_d;
|
||||||
|
|
||||||
ret = 1;
|
/* upper 521 bits, copy ... */
|
||||||
err:
|
nist_cp_bn_0(t_d,a_d + (BN_NIST_521_TOP-1), top - (BN_NIST_521_TOP-1),BN_NIST_521_TOP);
|
||||||
BN_CTX_end(ctx);
|
/* ... and right shift */
|
||||||
|
for (val=t_d[0],i=0; i<BN_NIST_521_TOP-1; i++)
|
||||||
|
{
|
||||||
|
tmp = val>>BN_NIST_521_RSHIFT;
|
||||||
|
val = t_d[i+1];
|
||||||
|
t_d[i] = (tmp | val<<BN_NIST_521_LSHIFT) & BN_MASK2;
|
||||||
|
}
|
||||||
|
t_d[i] = val>>BN_NIST_521_RSHIFT;
|
||||||
|
/* lower 521 bits */
|
||||||
|
r_d[i] &= BN_NIST_521_TOP_MASK;
|
||||||
|
|
||||||
bn_check_top(r);
|
bn_add_words(r_d,r_d,t_d,BN_NIST_521_TOP);
|
||||||
return ret;
|
mask = 0-(size_t)bn_sub_words(t_d,r_d,_nist_p_521,BN_NIST_521_TOP);
|
||||||
|
res = (BN_ULONG *)(((size_t)t_d&~mask) | ((size_t)r_d&mask));
|
||||||
|
nist_cp_bn(r_d,res,BN_NIST_521_TOP);
|
||||||
|
r->top = BN_NIST_521_TOP;
|
||||||
|
bn_correct_top(r);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user