Document some BIGNUM internals.

Change-Id: I8f044febf16afe04da8b176c638111a9574c4d02
Reviewed-on: https://boringssl-review.googlesource.com/22887
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2017-11-09 14:07:54 -08:00 committed by Adam Langley
parent 0a9222b824
commit bf3f6caaf3
4 changed files with 88 additions and 53 deletions

View File

@ -280,7 +280,7 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) #define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) { void bn_mul_comba8(BN_ULONG r[16], BN_ULONG a[8], BN_ULONG b[8]) {
BN_ULONG c1, c2, c3; BN_ULONG c1, c2, c3;
c1 = 0; c1 = 0;
@ -382,7 +382,7 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
r[15] = c1; r[15] = c1;
} }
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) { void bn_mul_comba4(BN_ULONG r[8], BN_ULONG a[4], BN_ULONG b[4]) {
BN_ULONG c1, c2, c3; BN_ULONG c1, c2, c3;
c1 = 0; c1 = 0;
@ -420,7 +420,7 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
r[7] = c2; r[7] = c2;
} }
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) { void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[8]) {
BN_ULONG c1, c2, c3; BN_ULONG c1, c2, c3;
c1 = 0; c1 = 0;
@ -494,7 +494,7 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
r[15] = c1; r[15] = c1;
} }
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) { void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) {
BN_ULONG c1, c2, c3; BN_ULONG c1, c2, c3;
c1 = 0; c1 = 0;

View File

@ -458,7 +458,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
#endif // !BN_ULLONG #endif // !BN_ULLONG
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) { void bn_mul_comba8(BN_ULONG r[16], BN_ULONG a[8], BN_ULONG b[8]) {
BN_ULONG c1, c2, c3; BN_ULONG c1, c2, c3;
c1 = 0; c1 = 0;
@ -560,7 +560,7 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
r[15] = c1; r[15] = c1;
} }
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) { void bn_mul_comba4(BN_ULONG r[8], BN_ULONG a[4], BN_ULONG b[4]) {
BN_ULONG c1, c2, c3; BN_ULONG c1, c2, c3;
c1 = 0; c1 = 0;
@ -598,7 +598,7 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
r[7] = c2; r[7] = c2;
} }
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) { void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[8]) {
BN_ULONG c1, c2, c3; BN_ULONG c1, c2, c3;
c1 = 0; c1 = 0;
@ -672,7 +672,7 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
r[15] = c1; r[15] = c1;
} }
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) { void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) {
BN_ULONG c1, c2, c3; BN_ULONG c1, c2, c3;
c1 = 0; c1 = 0;

View File

@ -212,16 +212,50 @@ int bn_expand(BIGNUM *bn, size_t bits);
// least significant word first. // least significant word first.
int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num); int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num);
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); // bn_mul_add_words multiples |ap| by |w|, adds the result to |rp|, and places
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); // the result in |rp|. |ap| and |rp| must both be |num| words long. It returns
void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num); // the carry word of the operation. |ap| and |rp| may be equal but otherwise may
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num); // not alias.
BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num); BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
BN_ULONG w);
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); // bn_mul_words multiples |ap| by |w| and places the result in |rp|. |ap| and
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); // |rp| must both be |num| words long. It returns the carry word of the
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a); // operation. |ap| and |rp| may be equal but otherwise may not alias.
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a); BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
// bn_sqr_words sets |rp[2*i]| and |rp[2*i+1]| to |ap[i]|'s square, for all |i|
// up to |num|. |ap| is an array of |num| words and |rp| an array of |2*num|
// words. |ap| and |rp| may not alias.
//
// This gives the contribution of the |ap[i]*ap[i]| terms when squaring |ap|.
void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
// bn_add_words adds |ap| to |bp| and places the result in |rp|, each of which
// are |num| words long. It returns the carry bit, which is one if the operation
// overflowed and zero otherwise. Any pair of |ap|, |bp|, and |rp| may be equal
// to each other but otherwise may not alias.
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
int num);
// bn_sub_words subtracts |bp| from |ap| and places the result in |rp|. It
// returns the borrow bit, which is one if the computation underflowed and zero
// otherwise. Any pair of |ap|, |bp|, and |rp| may be equal to each other but
// otherwise may not alias.
BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
int num);
// bn_mul_comba4 sets |r| to the product of |a| and |b|.
void bn_mul_comba4(BN_ULONG r[8], BN_ULONG a[4], BN_ULONG b[4]);
// bn_mul_comba8 sets |r| to the product of |a| and |b|.
void bn_mul_comba8(BN_ULONG r[16], BN_ULONG a[8], BN_ULONG b[8]);
// bn_sqr_comba8 sets |r| to |a|^2.
void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[4]);
// bn_sqr_comba4 sets |r| to |a|^2.
void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]);
// bn_cmp_words returns a value less than, equal to or greater than zero if // bn_cmp_words returns a value less than, equal to or greater than zero if
// the, length |n|, array |a| is less than, equal to or greater than |b|. // the, length |n|, array |a| is less than, equal to or greater than |b|.

View File

@ -659,37 +659,37 @@ err:
} }
// tmp must have 2*n words // tmp must have 2*n words
static void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp) { static void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n,
int i, j, max; BN_ULONG *tmp) {
const BN_ULONG *ap; int max = n * 2;
BN_ULONG *rp; const BN_ULONG *ap = a;
BN_ULONG *rp = r;
max = n * 2;
ap = a;
rp = r;
rp[0] = rp[max - 1] = 0; rp[0] = rp[max - 1] = 0;
rp++; rp++;
j = n; int j = n;
// Compute the contribution of a[i] * a[j] for all i < j.
if (--j > 0) { if (--j > 0) {
ap++; ap++;
rp[j] = bn_mul_words(rp, ap, j, ap[-1]); rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
rp += 2; rp += 2;
} }
for (i = n - 2; i > 0; i--) { for (int i = n - 2; i > 0; i--) {
j--; j--;
ap++; ap++;
rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]); rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);
rp += 2; rp += 2;
} }
// The final result fits in |max| words, so none of the following operations
// will overflow.
// Double |r|, giving the contribution of a[i] * a[j] for all i != j.
bn_add_words(r, r, r, max); bn_add_words(r, r, r, max);
// There will not be a carry // Add in the contribution of a[i] * a[i] for all i.
bn_sqr_words(tmp, a, n); bn_sqr_words(tmp, a, n);
bn_add_words(r, r, tmp, max); bn_add_words(r, r, tmp, max);
} }
@ -702,7 +702,8 @@ static void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
// a[0]*b[0] // a[0]*b[0]
// a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) // a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
// a[1]*b[1] // a[1]*b[1]
static void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t) { static void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2,
BN_ULONG *t) {
int n = n2 / 2; int n = n2 / 2;
int zero, c1; int zero, c1;
BN_ULONG ln, lo, *p; BN_ULONG ln, lo, *p;