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:
parent
0a9222b824
commit
bf3f6caaf3
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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|.
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user