Add bn_usub_fixed.
There are a number of random subtractions in RSA key generation. Add a fixed-width version. Median of 29 RSA keygens: 0m0.859s -> 0m0.811s (Accuracy beyond 0.1s is questionable.) Bug: 238 Change-Id: I9fa0771b95a438fd7d2635fd77a332146ccc96d9 Reviewed-on: https://boringssl-review.googlesource.com/25884 Commit-Queue: Adam Langley <agl@google.com> Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
d89d65ba12
commit
ad066861dd
@ -223,69 +223,45 @@ int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
int max, min, dif;
|
||||
register BN_ULONG t1, t2, *ap, *bp, *rp;
|
||||
int i, carry;
|
||||
int bn_usub_fixed(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
// |b| may have more words than |a| given non-minimal inputs, but all words
|
||||
// beyond |a->width| must then be zero.
|
||||
int b_width = b->width;
|
||||
if (b_width > a->width) {
|
||||
if (!bn_fits_in_words(b, a->width)) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
|
||||
return 0;
|
||||
}
|
||||
b_width = a->width;
|
||||
}
|
||||
|
||||
max = bn_minimal_width(a);
|
||||
min = bn_minimal_width(b);
|
||||
dif = max - min;
|
||||
if (!bn_wexpand(r, a->width)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dif < 0) // hmm... should not be happening
|
||||
{
|
||||
BN_ULONG borrow = bn_sub_words(r->d, a->d, b->d, b_width);
|
||||
for (int i = b_width; i < a->width; i++) {
|
||||
// |r| and |a| may alias, so use a temporary.
|
||||
BN_ULONG tmp = a->d[i];
|
||||
r->d[i] = a->d[i] - borrow;
|
||||
borrow = tmp < r->d[i];
|
||||
}
|
||||
|
||||
if (borrow) {
|
||||
OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!bn_wexpand(r, max)) {
|
||||
r->width = a->width;
|
||||
r->neg = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
if (!bn_usub_fixed(r, a, b)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ap = a->d;
|
||||
bp = b->d;
|
||||
rp = r->d;
|
||||
|
||||
carry = 0;
|
||||
for (i = min; i != 0; i--) {
|
||||
t1 = *(ap++);
|
||||
t2 = *(bp++);
|
||||
if (carry) {
|
||||
carry = (t1 <= t2);
|
||||
t1 -= t2 + 1;
|
||||
} else {
|
||||
carry = (t1 < t2);
|
||||
t1 -= t2;
|
||||
}
|
||||
*(rp++) = t1;
|
||||
}
|
||||
|
||||
if (carry) // subtracted
|
||||
{
|
||||
if (!dif) {
|
||||
// error: a < b
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (dif) {
|
||||
dif--;
|
||||
t1 = *(ap++);
|
||||
t2 = t1 - 1;
|
||||
*(rp++) = t2;
|
||||
if (t1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dif > 0 && rp != ap) {
|
||||
OPENSSL_memcpy(rp, ap, sizeof(*rp) * dif);
|
||||
}
|
||||
|
||||
r->width = max;
|
||||
r->neg = 0;
|
||||
bn_set_minimal_width(r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -366,6 +366,10 @@ int bn_less_than_montgomery_R(const BIGNUM *bn, const BN_MONT_CTX *mont);
|
||||
// |r->width| = |a->width| + |b->width| + 1.
|
||||
int bn_uadd_fixed(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
|
||||
|
||||
// bn_usub_fixed behaves like |BN_usub|, but it pessimally sets
|
||||
// |r->width| = |a->width|.
|
||||
int bn_usub_fixed(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
|
||||
|
||||
// bn_mul_fixed behaves like |BN_mul|, but it rejects negative inputs and
|
||||
// pessimally sets |r->width| to |a->width| + |b->width|, to avoid leaking
|
||||
// information about |a| and |b|.
|
||||
|
Loading…
Reference in New Issue
Block a user