Fix for CVE-2014-3570.
(With minor bn/generic.c revamp.) (Imported from upstream's 56df92efb6893abe323307939425957ce878c8f0) Change-Id: I9d85cfde4dfb29e64ff7417f781d0c9f1685e905 Reviewed-on: https://boringssl-review.googlesource.com/2780 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
+27
-65
@@ -292,80 +292,45 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) {
|
||||
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0)
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/* original macros are kept for reference purposes */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b); \
|
||||
t1 = ta * tb; \
|
||||
t2 = BN_UMULT_HIGH(ta, tb); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b), t0; \
|
||||
t1 = BN_UMULT_HIGH(ta, tb); \
|
||||
t0 = ta * tb; \
|
||||
t2 = t1 + t1; \
|
||||
c2 += (t2 < t1) ? 1 : 0; \
|
||||
t1 = t0 + t0; \
|
||||
t2 += (t1 < t0) ? 1 : 0; \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
#else
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
/* Keep in mind that carrying into high part of multiplication result can not
|
||||
* overflow, because it cannot be all-ones. */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG t1, t2; \
|
||||
asm("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \
|
||||
asm("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c0), "+d"(t2) \
|
||||
: "a"(t1), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c1), "+r"(c2) \
|
||||
: "d"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
|
||||
: "+r"(c0), "+r"(c1), "+r"(c2) \
|
||||
: "r"(t1), "r"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG t1, t2; \
|
||||
asm("mulq %2" : "=a"(t1), "=d"(t2) : "a"(a[i]) : "cc"); \
|
||||
asm("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c0), "+d"(t2) \
|
||||
: "a"(t1), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c1), "+r"(c2) \
|
||||
: "d"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
|
||||
: "+r"(c0), "+r"(c1), "+r"(c2) \
|
||||
: "r"(t1), "r"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
} while (0)
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG t1, t2; \
|
||||
asm("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \
|
||||
asm("addq %0,%0; adcq %2,%1" : "+d"(t2), "+r"(c2) : "g"(0) : "cc"); \
|
||||
asm("addq %0,%0; adcq %2,%1" : "+a"(t1), "+d"(t2) : "g"(0) : "cc"); \
|
||||
asm("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c0), "+d"(t2) \
|
||||
: "a"(t1), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %2,%0; adcq %3,%1" \
|
||||
: "+r"(c1), "+r"(c2) \
|
||||
: "d"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
|
||||
: "+r"(c0), "+r"(c1), "+r"(c2) \
|
||||
: "r"(t1), "r"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
|
||||
: "+r"(c0), "+r"(c1), "+r"(c2) \
|
||||
: "r"(t1), "r"(t2), "g"(0) \
|
||||
: "cc"); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#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) {
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -468,7 +433,6 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
}
|
||||
|
||||
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -507,7 +471,6 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
}
|
||||
|
||||
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -582,7 +545,6 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
|
||||
}
|
||||
|
||||
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
|
||||
+79
-21
@@ -653,40 +653,98 @@ int test_mul(BIO *bp) {
|
||||
}
|
||||
|
||||
int test_sqr(BIO *bp, BN_CTX *ctx) {
|
||||
BIGNUM a, c, d, e;
|
||||
int i;
|
||||
BIGNUM *a, *c, *d, *e;
|
||||
int i, ret = 0;
|
||||
|
||||
BN_init(&a);
|
||||
BN_init(&c);
|
||||
BN_init(&d);
|
||||
BN_init(&e);
|
||||
a = BN_new();
|
||||
c = BN_new();
|
||||
d = BN_new();
|
||||
e = BN_new();
|
||||
if (a == NULL || c == NULL || d == NULL || e == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < num0; i++) {
|
||||
BN_rand(&a, 40 + i * 10, 0, 0);
|
||||
a.neg = rand_neg();
|
||||
BN_sqr(&c, &a, ctx);
|
||||
BN_rand(a, 40 + i * 10, 0, 0);
|
||||
a->neg = rand_neg();
|
||||
BN_sqr(c, a, ctx);
|
||||
if (bp != NULL) {
|
||||
if (!results) {
|
||||
BN_print(bp, &a);
|
||||
BN_print(bp, a);
|
||||
BIO_puts(bp, " * ");
|
||||
BN_print(bp, &a);
|
||||
BN_print(bp, a);
|
||||
BIO_puts(bp, " - ");
|
||||
}
|
||||
BN_print(bp, &c);
|
||||
BN_print(bp, c);
|
||||
BIO_puts(bp, "\n");
|
||||
}
|
||||
BN_div(&d, &e, &c, &a, ctx);
|
||||
BN_sub(&d, &d, &a);
|
||||
if (!BN_is_zero(&d) || !BN_is_zero(&e)) {
|
||||
BN_div(d, e, c, a, ctx);
|
||||
BN_sub(d, d, a);
|
||||
if (!BN_is_zero(d) || !BN_is_zero(e)) {
|
||||
fprintf(stderr, "Square test failed!\n");
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
BN_free(&a);
|
||||
BN_free(&c);
|
||||
BN_free(&d);
|
||||
BN_free(&e);
|
||||
return (1);
|
||||
|
||||
/* Regression test for a BN_sqr overflow bug. */
|
||||
BN_hex2bn(&a,
|
||||
"80000000000000008000000000000001FFFFFFFFFFFFFFFE0000000000000000");
|
||||
BN_sqr(c, a, ctx);
|
||||
if (bp != NULL) {
|
||||
if (!results) {
|
||||
BN_print(bp, a);
|
||||
BIO_puts(bp, " * ");
|
||||
BN_print(bp, a);
|
||||
BIO_puts(bp, " - ");
|
||||
}
|
||||
BN_print(bp, c);
|
||||
BIO_puts(bp, "\n");
|
||||
}
|
||||
BN_mul(d, a, a, ctx);
|
||||
if (BN_cmp(c, d)) {
|
||||
fprintf(stderr,
|
||||
"Square test failed: BN_sqr and BN_mul produce "
|
||||
"different results!\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Regression test for a BN_sqr overflow bug. */
|
||||
BN_hex2bn(&a,
|
||||
"80000000000000000000000080000001FFFFFFFE000000000000000000000000");
|
||||
BN_sqr(c, a, ctx);
|
||||
if (bp != NULL) {
|
||||
if (!results) {
|
||||
BN_print(bp, a);
|
||||
BIO_puts(bp, " * ");
|
||||
BN_print(bp, a);
|
||||
BIO_puts(bp, " - ");
|
||||
}
|
||||
BN_print(bp, c);
|
||||
BIO_puts(bp, "\n");
|
||||
}
|
||||
BN_mul(d, a, a, ctx);
|
||||
if (BN_cmp(c, d)) {
|
||||
fprintf(stderr,
|
||||
"Square test failed: BN_sqr and BN_mul produce "
|
||||
"different results!\n");
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (a != NULL) {
|
||||
BN_free(a);
|
||||
}
|
||||
if (c != NULL) {
|
||||
BN_free(c);
|
||||
}
|
||||
if (d != NULL) {
|
||||
BN_free(d);
|
||||
}
|
||||
if (e != NULL) {
|
||||
BN_free(e);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+155
-154
@@ -659,175 +659,194 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
|
||||
|
||||
#ifdef BN_LLONG
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
t = (BN_ULLONG)a * b; \
|
||||
t1 = (BN_ULONG)Lw(t); \
|
||||
t2 = (BN_ULONG)Hw(t); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0) < t1) \
|
||||
t2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
t = (BN_ULLONG)a * b; \
|
||||
tt = (t + t) & BN_MASK; \
|
||||
if (tt < t) \
|
||||
c2++; \
|
||||
t1 = (BN_ULONG)Lw(tt); \
|
||||
t2 = (BN_ULONG)Hw(tt); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0 < t1) && (((++t2) & BN_MASK2) == 0)) \
|
||||
c2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
/* Keep in mind that additions to multiplication result can not overflow,
|
||||
* because its high half cannot be all-ones. */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG hi; \
|
||||
BN_ULLONG t = (BN_ULLONG)(a) * (b); \
|
||||
t += c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(t); \
|
||||
hi = (BN_ULONG)Hw(t); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
t = (BN_ULLONG)a[i] * a[i]; \
|
||||
t1 = (BN_ULONG)Lw(t); \
|
||||
t2 = (BN_ULONG)Hw(t); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0) < t1) \
|
||||
t2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG hi; \
|
||||
BN_ULLONG t = (BN_ULLONG)(a) * (b); \
|
||||
BN_ULLONG tt = t + c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(tt); \
|
||||
hi = (BN_ULONG)Hw(tt); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
t += c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(t); \
|
||||
hi = (BN_ULONG)Hw(t); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG hi; \
|
||||
BN_ULLONG t = (BN_ULLONG)a[i] * a[i]; \
|
||||
t += c0; /* no carry */ \
|
||||
c0 = (BN_ULONG)Lw(t); \
|
||||
hi = (BN_ULONG)Hw(t); \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
|
||||
#elif defined(BN_UMULT_LOHI)
|
||||
|
||||
/* Keep in mind that additions to hi can not overflow, because the high word of
|
||||
* a multiplication result cannot be all-ones. */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
do { \
|
||||
BN_ULONG ta = (a), tb = (b); \
|
||||
BN_UMULT_LOHI(t1, t2, ta, tb); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
BN_ULONG lo, hi; \
|
||||
BN_UMULT_LOHI(lo, hi, ta, tb); \
|
||||
c0 += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b), t0; \
|
||||
BN_UMULT_LOHI(t0, t1, ta, tb); \
|
||||
t2 = t1 + t1; \
|
||||
c2 += (t2 < t1) ? 1 : 0; \
|
||||
t1 = t0 + t0; \
|
||||
t2 += (t1 < t0) ? 1 : 0; \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
do { \
|
||||
BN_ULONG ta = (a), tb = (b); \
|
||||
BN_ULONG lo, hi, tt; \
|
||||
BN_UMULT_LOHI(lo, hi, ta, tb); \
|
||||
c0 += lo; \
|
||||
tt = hi + ((c0 < lo) ? 1 : 0); \
|
||||
c1 += tt; \
|
||||
c2 += (c1 < tt) ? 1 : 0; \
|
||||
c0 += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
{ \
|
||||
do { \
|
||||
BN_ULONG ta = (a)[i]; \
|
||||
BN_UMULT_LOHI(t1, t2, ta, ta); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
BN_ULONG lo, hi; \
|
||||
BN_UMULT_LOHI(lo, hi, ta, ta); \
|
||||
c0 += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
|
||||
#elif defined(BN_UMULT_HIGH)
|
||||
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b); \
|
||||
t1 = ta * tb; \
|
||||
t2 = BN_UMULT_HIGH(ta, tb); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
/* Keep in mind that additions to hi can not overflow, because
|
||||
* the high word of a multiplication result cannot be all-ones. */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG ta = (a), tb = (b); \
|
||||
BN_ULONG lo = ta * tb; \
|
||||
BN_ULONG hi = BN_UMULT_HIGH(ta, tb); \
|
||||
c0 += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a), tb = (b), t0; \
|
||||
t1 = BN_UMULT_HIGH(ta, tb); \
|
||||
t0 = ta * tb; \
|
||||
t2 = t1 + t1; \
|
||||
c2 += (t2 < t1) ? 1 : 0; \
|
||||
t1 = t0 + t0; \
|
||||
t2 += (t1 < t0) ? 1 : 0; \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG ta = (a), tb = (b), tt; \
|
||||
BN_ULONG lo = ta * tb; \
|
||||
BN_ULONG hi = BN_UMULT_HIGH(ta, tb); \
|
||||
c0 += lo; \
|
||||
tt = hi + ((c0 < lo) ? 1 : 0); \
|
||||
c1 += tt; \
|
||||
c2 += (c1 < tt) ? 1 : 0; \
|
||||
c0 += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
{ \
|
||||
BN_ULONG ta = (a)[i]; \
|
||||
t1 = ta * ta; \
|
||||
t2 = BN_UMULT_HIGH(ta, ta); \
|
||||
c0 += t1; \
|
||||
t2 += (c0 < t1) ? 1 : 0; \
|
||||
c1 += t2; \
|
||||
c2 += (c1 < t2) ? 1 : 0; \
|
||||
}
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG ta = (a)[i]; \
|
||||
BN_ULONG lo = ta * ta; \
|
||||
BN_ULONG hi = BN_UMULT_HIGH(ta, ta); \
|
||||
c0 += lo; \
|
||||
hi += (c0 < lo) ? 1 : 0; \
|
||||
c1 += hi; \
|
||||
c2 += (c1 < hi) ? 1 : 0; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
|
||||
#else /* !BN_LLONG */
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
t1 = LBITS(a); \
|
||||
t2 = HBITS(a); \
|
||||
bl = LBITS(b); \
|
||||
bh = HBITS(b); \
|
||||
mul64(t1, t2, bl, bh); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0) < t1) \
|
||||
t2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
t1 = LBITS(a); \
|
||||
t2 = HBITS(a); \
|
||||
bl = LBITS(b); \
|
||||
bh = HBITS(b); \
|
||||
mul64(t1, t2, bl, bh); \
|
||||
if (t2 & BN_TBIT) \
|
||||
c2++; \
|
||||
t2 = (t2 + t2) & BN_MASK2; \
|
||||
if (t1 & BN_TBIT) \
|
||||
t2++; \
|
||||
t1 = (t1 + t1) & BN_MASK2; \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0 < t1) && (((++t2) & BN_MASK2) == 0)) \
|
||||
c2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
/* Keep in mind that additions to hi can not overflow, because
|
||||
* the high word of a multiplication result cannot be all-ones. */
|
||||
|
||||
#define mul_add_c(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG lo = LBITS(a), hi = HBITS(a); \
|
||||
BN_ULONG bl = LBITS(b), bh = HBITS(b); \
|
||||
mul64(lo, hi, bl, bh); \
|
||||
c0 = (c0 + lo) & BN_MASK2; \
|
||||
if (c0 < lo) \
|
||||
hi++; \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define mul_add_c2(a, b, c0, c1, c2) \
|
||||
do { \
|
||||
BN_ULONG tt; \
|
||||
BN_ULONG lo = LBITS(a), hi = HBITS(a); \
|
||||
BN_ULONG bl = LBITS(b), bh = HBITS(b); \
|
||||
mul64(lo, hi, bl, bh); \
|
||||
tt = hi; \
|
||||
c0 = (c0 + lo) & BN_MASK2; \
|
||||
if (c0 < lo) \
|
||||
tt++; \
|
||||
c1 = (c1 + tt) & BN_MASK2; \
|
||||
if (c1 < tt) \
|
||||
c2++; \
|
||||
c0 = (c0 + lo) & BN_MASK2; \
|
||||
if (c0 < lo) \
|
||||
hi++; \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c(a, i, c0, c1, c2) \
|
||||
sqr64(t1, t2, (a)[i]); \
|
||||
c0 = (c0 + t1) & BN_MASK2; \
|
||||
if ((c0) < t1) \
|
||||
t2++; \
|
||||
c1 = (c1 + t2) & BN_MASK2; \
|
||||
if ((c1) < t2) \
|
||||
c2++;
|
||||
do { \
|
||||
BN_ULONG lo, hi; \
|
||||
sqr64(lo, hi, (a)[i]); \
|
||||
c0 = (c0 + lo) & BN_MASK2; \
|
||||
if (c0 < lo) \
|
||||
hi++; \
|
||||
c1 = (c1 + hi) & BN_MASK2; \
|
||||
if (c1 < hi) \
|
||||
c2++; \
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
#endif /* !BN_LLONG */
|
||||
|
||||
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
#if defined(BN_LLONG)
|
||||
BN_ULLONG t;
|
||||
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
|
||||
BN_ULONG bl, bh;
|
||||
#endif
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -930,12 +949,6 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
}
|
||||
|
||||
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
#if defined(BN_LLONG)
|
||||
BN_ULLONG t;
|
||||
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
|
||||
BN_ULONG bl, bh;
|
||||
#endif
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -974,12 +987,6 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
}
|
||||
|
||||
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
|
||||
#if defined(BN_LLONG)
|
||||
BN_ULLONG t, tt;
|
||||
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
|
||||
BN_ULONG bl, bh;
|
||||
#endif
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
@@ -1054,12 +1061,6 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) {
|
||||
}
|
||||
|
||||
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) {
|
||||
#if defined(BN_LLONG)
|
||||
BN_ULLONG t, tt;
|
||||
#elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH)
|
||||
BN_ULONG bl, bh;
|
||||
#endif
|
||||
BN_ULONG t1, t2;
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
c1 = 0;
|
||||
|
||||
Reference in New Issue
Block a user