Browse Source

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>
kris/onging/CECPQ3_patch15
David Benjamin 6 years ago
committed by Adam Langley
parent
commit
ad066861dd
2 changed files with 32 additions and 52 deletions
  1. +28
    -52
      crypto/fipsmodule/bn/add.c
  2. +4
    -0
      crypto/fipsmodule/bn/internal.h

+ 28
- 52
crypto/fipsmodule/bn/add.c View File

@@ -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;

max = bn_minimal_width(a);
min = bn_minimal_width(b);
dif = max - min;

if (dif < 0) // hmm... should not be happening
{
OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
return 0;
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;
}

if (!bn_wexpand(r, max)) {
if (!bn_wexpand(r, a->width)) {
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;
}
}
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 (dif > 0 && rp != ap) {
OPENSSL_memcpy(rp, ap, sizeof(*rp) * dif);
if (borrow) {
OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
return 0;
}

r->width = max;
r->width = a->width;
r->neg = 0;
bn_set_minimal_width(r);
return 1;
}

int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
if (!bn_usub_fixed(r, a, b)) {
return 0;
}
bn_set_minimal_width(r);
return 1;
}



+ 4
- 0
crypto/fipsmodule/bn/internal.h View File

@@ -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…
Cancel
Save