diff options
| author | jsing <> | 2023-02-22 05:46:37 +0000 |
|---|---|---|
| committer | jsing <> | 2023-02-22 05:46:37 +0000 |
| commit | b78cccc526d31cefe3af77cef6ddab0981e8a45b (patch) | |
| tree | 3ef166da90c41a8837c572bb101b829f7820919c /src/lib/libc | |
| parent | 6f66480e47f11d7c590e1c3719c68facc3cc379a (diff) | |
| download | openbsd-b78cccc526d31cefe3af77cef6ddab0981e8a45b.tar.gz openbsd-b78cccc526d31cefe3af77cef6ddab0981e8a45b.tar.bz2 openbsd-b78cccc526d31cefe3af77cef6ddab0981e8a45b.zip | |
Rework bn_add()/bn_sub() to operate on word arrays.
Rather than working on BIGNUMs, change bn_add()/bn_sub() to operate on word
arrays that potentially differ in length. This matches the behaviour of
s2n-bignum's bignum_add() and bignum_sub().
ok tb@
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/bn/arch/amd64/bn_arch.c | 17 | ||||
| -rw-r--r-- | src/lib/libcrypto/bn/bn_add.c | 157 | ||||
| -rw-r--r-- | src/lib/libcrypto/bn/bn_local.h | 7 |
3 files changed, 99 insertions, 82 deletions
diff --git a/src/lib/libcrypto/bn/arch/amd64/bn_arch.c b/src/lib/libcrypto/bn/arch/amd64/bn_arch.c index a4a2d93ada..55275aa14e 100644 --- a/src/lib/libcrypto/bn/arch/amd64/bn_arch.c +++ b/src/lib/libcrypto/bn/arch/amd64/bn_arch.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: bn_arch.c,v 1.5 2023/02/16 11:13:05 jsing Exp $ */ | 1 | /* $OpenBSD: bn_arch.c,v 1.6 2023/02/22 05:46:37 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -23,13 +23,15 @@ | |||
| 23 | 23 | ||
| 24 | #ifdef HAVE_BN_ADD | 24 | #ifdef HAVE_BN_ADD |
| 25 | BN_ULONG | 25 | BN_ULONG |
| 26 | bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) | 26 | bn_add(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, const BN_ULONG *b, |
| 27 | int b_len) | ||
| 27 | { | 28 | { |
| 28 | return bignum_add(rn, (uint64_t *)r->d, a->top, (uint64_t *)a->d, | 29 | return bignum_add(r_len, (uint64_t *)r, a_len, (uint64_t *)a, |
| 29 | b->top, (uint64_t *)b->d); | 30 | b_len, (uint64_t *)b); |
| 30 | } | 31 | } |
| 31 | #endif | 32 | #endif |
| 32 | 33 | ||
| 34 | |||
| 33 | #ifdef HAVE_BN_ADD_WORDS | 35 | #ifdef HAVE_BN_ADD_WORDS |
| 34 | BN_ULONG | 36 | BN_ULONG |
| 35 | bn_add_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n) | 37 | bn_add_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n) |
| @@ -41,10 +43,11 @@ bn_add_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n) | |||
| 41 | 43 | ||
| 42 | #ifdef HAVE_BN_SUB | 44 | #ifdef HAVE_BN_SUB |
| 43 | BN_ULONG | 45 | BN_ULONG |
| 44 | bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) | 46 | bn_sub(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, const BN_ULONG *b, |
| 47 | int b_len) | ||
| 45 | { | 48 | { |
| 46 | return bignum_sub(rn, (uint64_t *)r->d, a->top, (uint64_t *)a->d, | 49 | return bignum_sub(r_len, (uint64_t *)r, a_len, (uint64_t *)a, |
| 47 | b->top, (uint64_t *)b->d); | 50 | b_len, (uint64_t *)b); |
| 48 | } | 51 | } |
| 49 | #endif | 52 | #endif |
| 50 | 53 | ||
diff --git a/src/lib/libcrypto/bn/bn_add.c b/src/lib/libcrypto/bn/bn_add.c index 51b87104cf..92489b7da3 100644 --- a/src/lib/libcrypto/bn/bn_add.c +++ b/src/lib/libcrypto/bn/bn_add.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: bn_add.c,v 1.23 2023/02/16 04:42:20 jsing Exp $ */ | 1 | /* $OpenBSD: bn_add.c,v 1.24 2023/02/22 05:46:37 jsing Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -66,9 +66,6 @@ | |||
| 66 | #include "bn_local.h" | 66 | #include "bn_local.h" |
| 67 | #include "bn_internal.h" | 67 | #include "bn_internal.h" |
| 68 | 68 | ||
| 69 | BN_ULONG bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b); | ||
| 70 | BN_ULONG bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b); | ||
| 71 | |||
| 72 | /* | 69 | /* |
| 73 | * bn_add_words() computes (carry:r[i]) = a[i] + b[i] + carry, where a and b | 70 | * bn_add_words() computes (carry:r[i]) = a[i] + b[i] + carry, where a and b |
| 74 | * are both arrays of words. Any carry resulting from the addition is returned. | 71 | * are both arrays of words. Any carry resulting from the addition is returned. |
| @@ -107,6 +104,53 @@ bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | |||
| 107 | #endif | 104 | #endif |
| 108 | 105 | ||
| 109 | /* | 106 | /* |
| 107 | * bn_add() computes (carry:r[i]) = a[i] + b[i] + carry, where a and b are both | ||
| 108 | * arrays of words (r may be the same as a or b). The length of a and b may | ||
| 109 | * differ, while r must be at least max(a_len, b_len) in length. Any carry | ||
| 110 | * resulting from the addition is returned. | ||
| 111 | */ | ||
| 112 | #ifndef HAVE_BN_ADD | ||
| 113 | BN_ULONG | ||
| 114 | bn_add(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, const BN_ULONG *b, | ||
| 115 | int b_len) | ||
| 116 | { | ||
| 117 | int min_len, diff_len; | ||
| 118 | BN_ULONG carry = 0; | ||
| 119 | |||
| 120 | if ((min_len = a_len) > b_len) | ||
| 121 | min_len = b_len; | ||
| 122 | |||
| 123 | diff_len = a_len - b_len; | ||
| 124 | |||
| 125 | carry = bn_add_words(r, a, b, min_len); | ||
| 126 | |||
| 127 | a += min_len; | ||
| 128 | b += min_len; | ||
| 129 | r += min_len; | ||
| 130 | |||
| 131 | /* XXX - consider doing four at a time to match bn_add_words(). */ | ||
| 132 | while (diff_len < 0) { | ||
| 133 | /* Compute r[0] = 0 + b[0] + carry. */ | ||
| 134 | bn_addw(b[0], carry, &carry, &r[0]); | ||
| 135 | diff_len++; | ||
| 136 | b++; | ||
| 137 | r++; | ||
| 138 | } | ||
| 139 | |||
| 140 | /* XXX - consider doing four at a time to match bn_add_words(). */ | ||
| 141 | while (diff_len > 0) { | ||
| 142 | /* Compute r[0] = a[0] + 0 + carry. */ | ||
| 143 | bn_addw(a[0], carry, &carry, &r[0]); | ||
| 144 | diff_len--; | ||
| 145 | a++; | ||
| 146 | r++; | ||
| 147 | } | ||
| 148 | |||
| 149 | return carry; | ||
| 150 | } | ||
| 151 | #endif | ||
| 152 | |||
| 153 | /* | ||
| 110 | * bn_sub_words() computes (borrow:r[i]) = a[i] - b[i] - borrow, where a and b | 154 | * bn_sub_words() computes (borrow:r[i]) = a[i] - b[i] - borrow, where a and b |
| 111 | * are both arrays of words. Any borrow resulting from the subtraction is | 155 | * are both arrays of words. Any borrow resulting from the subtraction is |
| 112 | * returned. | 156 | * returned. |
| @@ -145,81 +189,46 @@ bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | |||
| 145 | #endif | 189 | #endif |
| 146 | 190 | ||
| 147 | /* | 191 | /* |
| 148 | * bn_add() computes a + b, storing the result in r (which may be the same as a | 192 | * bn_sub() computes (borrow:r[i]) = a[i] - b[i] - borrow, where a and b are both |
| 149 | * or b). The caller must ensure that r has been expanded to max(a->top, b->top) | 193 | * arrays of words (r may be the same as a or b). The length of a and b may |
| 150 | * words. Any carry resulting from the addition is returned. | 194 | * differ, while r must be at least max(a_len, b_len) in length. Any borrow |
| 195 | * resulting from the subtraction is returned. | ||
| 151 | */ | 196 | */ |
| 152 | #ifndef HAVE_BN_ADD | 197 | #ifndef HAVE_BN_SUB |
| 153 | BN_ULONG | 198 | BN_ULONG |
| 154 | bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) | 199 | bn_sub(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, const BN_ULONG *b, |
| 200 | int b_len) | ||
| 155 | { | 201 | { |
| 156 | BN_ULONG *rp, carry, t1, t2; | 202 | int min_len, diff_len; |
| 157 | const BN_ULONG *ap, *bp; | 203 | BN_ULONG borrow = 0; |
| 158 | int max, min, dif; | ||
| 159 | 204 | ||
| 160 | if (a->top < b->top) { | 205 | if ((min_len = a_len) > b_len) |
| 161 | const BIGNUM *tmp; | 206 | min_len = b_len; |
| 162 | 207 | ||
| 163 | tmp = a; | 208 | diff_len = a_len - b_len; |
| 164 | a = b; | ||
| 165 | b = tmp; | ||
| 166 | } | ||
| 167 | max = a->top; | ||
| 168 | min = b->top; | ||
| 169 | dif = max - min; | ||
| 170 | |||
| 171 | ap = a->d; | ||
| 172 | bp = b->d; | ||
| 173 | rp = r->d; | ||
| 174 | |||
| 175 | carry = bn_add_words(rp, ap, bp, min); | ||
| 176 | rp += min; | ||
| 177 | ap += min; | ||
| 178 | |||
| 179 | while (dif) { | ||
| 180 | dif--; | ||
| 181 | t1 = *(ap++); | ||
| 182 | t2 = (t1 + carry) & BN_MASK2; | ||
| 183 | *(rp++) = t2; | ||
| 184 | carry &= (t2 == 0); | ||
| 185 | } | ||
| 186 | 209 | ||
| 187 | return carry; | 210 | borrow = bn_sub_words(r, a, b, min_len); |
| 188 | } | ||
| 189 | #endif | ||
| 190 | 211 | ||
| 191 | /* | 212 | a += min_len; |
| 192 | * bn_sub() computes a - b, storing the result in r (which may be the same as a | 213 | b += min_len; |
| 193 | * or b). The caller must ensure that the number of words in a is greater than | 214 | r += min_len; |
| 194 | * or equal to the number of words in b and that r has been expanded to | 215 | |
| 195 | * a->top words. Any borrow resulting from the subtraction is returned. | 216 | /* XXX - consider doing four at a time to match bn_sub_words. */ |
| 196 | */ | 217 | while (diff_len < 0) { |
| 197 | #ifndef HAVE_BN_SUB | 218 | /* Compute r[0] = 0 - b[0] - borrow. */ |
| 198 | BN_ULONG | 219 | bn_subw(0 - b[0], borrow, &borrow, &r[0]); |
| 199 | bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) | 220 | diff_len++; |
| 200 | { | 221 | b++; |
| 201 | BN_ULONG t1, t2, borrow, *rp; | 222 | r++; |
| 202 | const BN_ULONG *ap, *bp; | 223 | } |
| 203 | int max, min, dif; | 224 | |
| 204 | 225 | /* XXX - consider doing four at a time to match bn_sub_words. */ | |
| 205 | max = a->top; | 226 | while (diff_len > 0) { |
| 206 | min = b->top; | 227 | /* Compute r[0] = a[0] - 0 - borrow. */ |
| 207 | dif = max - min; | 228 | bn_subw(a[0], borrow, &borrow, &r[0]); |
| 208 | 229 | diff_len--; | |
| 209 | ap = a->d; | 230 | a++; |
| 210 | bp = b->d; | 231 | r++; |
| 211 | rp = r->d; | ||
| 212 | |||
| 213 | borrow = bn_sub_words(rp, ap, bp, min); | ||
| 214 | ap += min; | ||
| 215 | rp += min; | ||
| 216 | |||
| 217 | while (dif) { | ||
| 218 | dif--; | ||
| 219 | t1 = *(ap++); | ||
| 220 | t2 = (t1 - borrow) & BN_MASK2; | ||
| 221 | *(rp++) = t2; | ||
| 222 | borrow &= (t1 == 0); | ||
| 223 | } | 232 | } |
| 224 | 233 | ||
| 225 | return borrow; | 234 | return borrow; |
| @@ -239,7 +248,7 @@ BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | |||
| 239 | if (!bn_wexpand(r, rn + 1)) | 248 | if (!bn_wexpand(r, rn + 1)) |
| 240 | return 0; | 249 | return 0; |
| 241 | 250 | ||
| 242 | carry = bn_add(r, rn, a, b); | 251 | carry = bn_add(r->d, rn, a->d, a->top, b->d, b->top); |
| 243 | r->d[rn] = carry; | 252 | r->d[rn] = carry; |
| 244 | 253 | ||
| 245 | r->top = rn + (carry & 1); | 254 | r->top = rn + (carry & 1); |
| @@ -263,7 +272,7 @@ BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) | |||
| 263 | if (!bn_wexpand(r, rn)) | 272 | if (!bn_wexpand(r, rn)) |
| 264 | return 0; | 273 | return 0; |
| 265 | 274 | ||
| 266 | borrow = bn_sub(r, rn, a, b); | 275 | borrow = bn_sub(r->d, rn, a->d, a->top, b->d, b->top); |
| 267 | if (borrow > 0) { | 276 | if (borrow > 0) { |
| 268 | BNerror(BN_R_ARG2_LT_ARG3); | 277 | BNerror(BN_R_ARG2_LT_ARG3); |
| 269 | return 0; | 278 | return 0; |
diff --git a/src/lib/libcrypto/bn/bn_local.h b/src/lib/libcrypto/bn/bn_local.h index 35e9073e2d..3e37238c5e 100644 --- a/src/lib/libcrypto/bn/bn_local.h +++ b/src/lib/libcrypto/bn/bn_local.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: bn_local.h,v 1.15 2023/02/22 05:25:47 jsing Exp $ */ | 1 | /* $OpenBSD: bn_local.h,v 1.16 2023/02/22 05:46:37 jsing Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -243,6 +243,11 @@ struct bn_gencb_st { | |||
| 243 | /* The least significant word of a BIGNUM. */ | 243 | /* The least significant word of a BIGNUM. */ |
| 244 | #define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0]) | 244 | #define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0]) |
| 245 | 245 | ||
| 246 | BN_ULONG bn_add(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, | ||
| 247 | const BN_ULONG *b, int b_len); | ||
| 248 | BN_ULONG bn_sub(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len, | ||
| 249 | const BN_ULONG *b, int b_len); | ||
| 250 | |||
| 246 | void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb); | 251 | void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb); |
| 247 | void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); | 252 | void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); |
| 248 | void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); | 253 | void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); |
