diff options
| author | jsing <> | 2023-02-16 04:42:20 +0000 |
|---|---|---|
| committer | jsing <> | 2023-02-16 04:42:20 +0000 |
| commit | 3170d87c6599656e7568dca509714cf70723f0d2 (patch) | |
| tree | d64538cc7fb7e35be6b722a5c08898e2a13ddebf /src | |
| parent | d5d57084c52a85f904031b46cae5e1c26448c38c (diff) | |
| download | openbsd-3170d87c6599656e7568dca509714cf70723f0d2.tar.gz openbsd-3170d87c6599656e7568dca509714cf70723f0d2.tar.bz2 openbsd-3170d87c6599656e7568dca509714cf70723f0d2.zip | |
Reimplement bn_add_words() and bn_sub_words() using bignum primitives.
This removes the effectively duplicate BN_LLONG version of bn_add_words()
and simplifies the code considerably.
ok tb@
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/bn/bn_add.c | 140 | ||||
| -rw-r--r-- | src/lib/libcrypto/bn/bn_internal.h | 59 |
2 files changed, 88 insertions, 111 deletions
diff --git a/src/lib/libcrypto/bn/bn_add.c b/src/lib/libcrypto/bn/bn_add.c index 8ae9bbe854..51b87104cf 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.22 2023/02/13 04:25:37 jsing Exp $ */ | 1 | /* $OpenBSD: bn_add.c,v 1.23 2023/02/16 04:42:20 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 | * |
| @@ -64,89 +64,31 @@ | |||
| 64 | 64 | ||
| 65 | #include "bn_arch.h" | 65 | #include "bn_arch.h" |
| 66 | #include "bn_local.h" | 66 | #include "bn_local.h" |
| 67 | #include "bn_internal.h" | ||
| 67 | 68 | ||
| 68 | BN_ULONG bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b); | 69 | BN_ULONG bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b); |
| 69 | BN_ULONG bn_sub(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); |
| 70 | 71 | ||
| 72 | /* | ||
| 73 | * 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. | ||
| 75 | */ | ||
| 71 | #ifndef HAVE_BN_ADD_WORDS | 76 | #ifndef HAVE_BN_ADD_WORDS |
| 72 | #ifdef BN_LLONG | ||
| 73 | BN_ULONG | 77 | BN_ULONG |
| 74 | bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | 78 | bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) |
| 75 | { | 79 | { |
| 76 | BN_ULLONG ll = 0; | 80 | BN_ULONG carry = 0; |
| 77 | 81 | ||
| 78 | assert(n >= 0); | 82 | assert(n >= 0); |
| 79 | if (n <= 0) | 83 | if (n <= 0) |
| 80 | return ((BN_ULONG)0); | 84 | return 0; |
| 81 | |||
| 82 | #ifndef OPENSSL_SMALL_FOOTPRINT | ||
| 83 | while (n & ~3) { | ||
| 84 | ll += (BN_ULLONG)a[0] + b[0]; | ||
| 85 | r[0] = (BN_ULONG)ll & BN_MASK2; | ||
| 86 | ll >>= BN_BITS2; | ||
| 87 | ll += (BN_ULLONG)a[1] + b[1]; | ||
| 88 | r[1] = (BN_ULONG)ll & BN_MASK2; | ||
| 89 | ll >>= BN_BITS2; | ||
| 90 | ll += (BN_ULLONG)a[2] + b[2]; | ||
| 91 | r[2] = (BN_ULONG)ll & BN_MASK2; | ||
| 92 | ll >>= BN_BITS2; | ||
| 93 | ll += (BN_ULLONG)a[3] + b[3]; | ||
| 94 | r[3] = (BN_ULONG)ll & BN_MASK2; | ||
| 95 | ll >>= BN_BITS2; | ||
| 96 | a += 4; | ||
| 97 | b += 4; | ||
| 98 | r += 4; | ||
| 99 | n -= 4; | ||
| 100 | } | ||
| 101 | #endif | ||
| 102 | while (n) { | ||
| 103 | ll += (BN_ULLONG)a[0] + b[0]; | ||
| 104 | r[0] = (BN_ULONG)ll & BN_MASK2; | ||
| 105 | ll >>= BN_BITS2; | ||
| 106 | a++; | ||
| 107 | b++; | ||
| 108 | r++; | ||
| 109 | n--; | ||
| 110 | } | ||
| 111 | return ((BN_ULONG)ll); | ||
| 112 | } | ||
| 113 | #else /* !BN_LLONG */ | ||
| 114 | BN_ULONG | ||
| 115 | bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | ||
| 116 | { | ||
| 117 | BN_ULONG c, l, t; | ||
| 118 | |||
| 119 | assert(n >= 0); | ||
| 120 | if (n <= 0) | ||
| 121 | return ((BN_ULONG)0); | ||
| 122 | 85 | ||
| 123 | c = 0; | ||
| 124 | #ifndef OPENSSL_SMALL_FOOTPRINT | 86 | #ifndef OPENSSL_SMALL_FOOTPRINT |
| 125 | while (n & ~3) { | 87 | while (n & ~3) { |
| 126 | t = a[0]; | 88 | bn_addw_addw(a[0], b[0], carry, &carry, &r[0]); |
| 127 | t = (t + c) & BN_MASK2; | 89 | bn_addw_addw(a[1], b[1], carry, &carry, &r[1]); |
| 128 | c = (t < c); | 90 | bn_addw_addw(a[2], b[2], carry, &carry, &r[2]); |
| 129 | l = (t + b[0]) & BN_MASK2; | 91 | bn_addw_addw(a[3], b[3], carry, &carry, &r[3]); |
| 130 | c += (l < t); | ||
| 131 | r[0] = l; | ||
| 132 | t = a[1]; | ||
| 133 | t = (t + c) & BN_MASK2; | ||
| 134 | c = (t < c); | ||
| 135 | l = (t + b[1]) & BN_MASK2; | ||
| 136 | c += (l < t); | ||
| 137 | r[1] = l; | ||
| 138 | t = a[2]; | ||
| 139 | t = (t + c) & BN_MASK2; | ||
| 140 | c = (t < c); | ||
| 141 | l = (t + b[2]) & BN_MASK2; | ||
| 142 | c += (l < t); | ||
| 143 | r[2] = l; | ||
| 144 | t = a[3]; | ||
| 145 | t = (t + c) & BN_MASK2; | ||
| 146 | c = (t < c); | ||
| 147 | l = (t + b[3]) & BN_MASK2; | ||
| 148 | c += (l < t); | ||
| 149 | r[3] = l; | ||
| 150 | a += 4; | 92 | a += 4; |
| 151 | b += 4; | 93 | b += 4; |
| 152 | r += 4; | 94 | r += 4; |
| @@ -154,55 +96,37 @@ bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | |||
| 154 | } | 96 | } |
| 155 | #endif | 97 | #endif |
| 156 | while (n) { | 98 | while (n) { |
| 157 | t = a[0]; | 99 | bn_addw_addw(a[0], b[0], carry, &carry, &r[0]); |
| 158 | t = (t + c) & BN_MASK2; | ||
| 159 | c = (t < c); | ||
| 160 | l = (t + b[0]) & BN_MASK2; | ||
| 161 | c += (l < t); | ||
| 162 | r[0] = l; | ||
| 163 | a++; | 100 | a++; |
| 164 | b++; | 101 | b++; |
| 165 | r++; | 102 | r++; |
| 166 | n--; | 103 | n--; |
| 167 | } | 104 | } |
| 168 | return ((BN_ULONG)c); | 105 | return carry; |
| 169 | } | 106 | } |
| 170 | #endif /* !BN_LLONG */ | ||
| 171 | #endif | 107 | #endif |
| 172 | 108 | ||
| 109 | /* | ||
| 110 | * 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 | ||
| 112 | * returned. | ||
| 113 | */ | ||
| 173 | #ifndef HAVE_BN_SUB_WORDS | 114 | #ifndef HAVE_BN_SUB_WORDS |
| 174 | BN_ULONG | 115 | BN_ULONG |
| 175 | bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | 116 | bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) |
| 176 | { | 117 | { |
| 177 | BN_ULONG t1, t2; | 118 | BN_ULONG borrow = 0; |
| 178 | int c = 0; | ||
| 179 | 119 | ||
| 180 | assert(n >= 0); | 120 | assert(n >= 0); |
| 181 | if (n <= 0) | 121 | if (n <= 0) |
| 182 | return ((BN_ULONG)0); | 122 | return 0; |
| 183 | 123 | ||
| 184 | #ifndef OPENSSL_SMALL_FOOTPRINT | 124 | #ifndef OPENSSL_SMALL_FOOTPRINT |
| 185 | while (n&~3) { | 125 | while (n & ~3) { |
| 186 | t1 = a[0]; | 126 | bn_subw_subw(a[0], b[0], borrow, &borrow, &r[0]); |
| 187 | t2 = b[0]; | 127 | bn_subw_subw(a[1], b[1], borrow, &borrow, &r[1]); |
| 188 | r[0] = (t1 - t2 - c) & BN_MASK2; | 128 | bn_subw_subw(a[2], b[2], borrow, &borrow, &r[2]); |
| 189 | if (t1 != t2) | 129 | bn_subw_subw(a[3], b[3], borrow, &borrow, &r[3]); |
| 190 | c = (t1 < t2); | ||
| 191 | t1 = a[1]; | ||
| 192 | t2 = b[1]; | ||
| 193 | r[1] = (t1 - t2 - c) & BN_MASK2; | ||
| 194 | if (t1 != t2) | ||
| 195 | c = (t1 < t2); | ||
| 196 | t1 = a[2]; | ||
| 197 | t2 = b[2]; | ||
| 198 | r[2] = (t1 - t2 - c) & BN_MASK2; | ||
| 199 | if (t1 != t2) | ||
| 200 | c = (t1 < t2); | ||
| 201 | t1 = a[3]; | ||
| 202 | t2 = b[3]; | ||
| 203 | r[3] = (t1 - t2 - c) & BN_MASK2; | ||
| 204 | if (t1 != t2) | ||
| 205 | c = (t1 < t2); | ||
| 206 | a += 4; | 130 | a += 4; |
| 207 | b += 4; | 131 | b += 4; |
| 208 | r += 4; | 132 | r += 4; |
| @@ -210,26 +134,22 @@ bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | |||
| 210 | } | 134 | } |
| 211 | #endif | 135 | #endif |
| 212 | while (n) { | 136 | while (n) { |
| 213 | t1 = a[0]; | 137 | bn_subw_subw(a[0], b[0], borrow, &borrow, &r[0]); |
| 214 | t2 = b[0]; | ||
| 215 | r[0] = (t1 - t2 - c) & BN_MASK2; | ||
| 216 | if (t1 != t2) | ||
| 217 | c = (t1 < t2); | ||
| 218 | a++; | 138 | a++; |
| 219 | b++; | 139 | b++; |
| 220 | r++; | 140 | r++; |
| 221 | n--; | 141 | n--; |
| 222 | } | 142 | } |
| 223 | return (c); | 143 | return borrow; |
| 224 | } | 144 | } |
| 225 | #endif | 145 | #endif |
| 226 | 146 | ||
| 227 | #ifndef HAVE_BN_ADD | ||
| 228 | /* | 147 | /* |
| 229 | * bn_add() computes a + b, storing the result in r (which may be the same as a | 148 | * bn_add() computes a + b, storing the result in r (which may be the same as a |
| 230 | * or b). The caller must ensure that r has been expanded to max(a->top, b->top) | 149 | * or b). The caller must ensure that r has been expanded to max(a->top, b->top) |
| 231 | * words. Any carry resulting from the addition is returned. | 150 | * words. Any carry resulting from the addition is returned. |
| 232 | */ | 151 | */ |
| 152 | #ifndef HAVE_BN_ADD | ||
| 233 | BN_ULONG | 153 | BN_ULONG |
| 234 | bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) | 154 | bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) |
| 235 | { | 155 | { |
| @@ -268,13 +188,13 @@ bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) | |||
| 268 | } | 188 | } |
| 269 | #endif | 189 | #endif |
| 270 | 190 | ||
| 271 | #ifndef HAVE_BN_SUB | ||
| 272 | /* | 191 | /* |
| 273 | * bn_sub() computes a - b, storing the result in r (which may be the same as a | 192 | * bn_sub() computes a - b, storing the result in r (which may be the same as a |
| 274 | * or b). The caller must ensure that the number of words in a is greater than | 193 | * or b). The caller must ensure that the number of words in a is greater than |
| 275 | * or equal to the number of words in b and that r has been expanded to | 194 | * or equal to the number of words in b and that r has been expanded to |
| 276 | * a->top words. Any borrow resulting from the subtraction is returned. | 195 | * a->top words. Any borrow resulting from the subtraction is returned. |
| 277 | */ | 196 | */ |
| 197 | #ifndef HAVE_BN_SUB | ||
| 278 | BN_ULONG | 198 | BN_ULONG |
| 279 | bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) | 199 | bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) |
| 280 | { | 200 | { |
diff --git a/src/lib/libcrypto/bn/bn_internal.h b/src/lib/libcrypto/bn/bn_internal.h index 12ea3641e6..1b5ab9c42c 100644 --- a/src/lib/libcrypto/bn/bn_internal.h +++ b/src/lib/libcrypto/bn/bn_internal.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: bn_internal.h,v 1.4 2023/02/15 04:46:49 tb Exp $ */ | 1 | /* $OpenBSD: bn_internal.h,v 1.5 2023/02/16 04:42:20 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2023 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -102,6 +102,63 @@ bn_addw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_r1, BN_ULONG *out_r0) | |||
| 102 | #endif | 102 | #endif |
| 103 | #endif | 103 | #endif |
| 104 | 104 | ||
| 105 | /* | ||
| 106 | * bn_addw_addw() computes (r1:r0) = a + b + c, where all inputs are single | ||
| 107 | * words, producing a double word result. | ||
| 108 | */ | ||
| 109 | #ifndef HAVE_BN_ADDW_ADDW | ||
| 110 | static inline void | ||
| 111 | bn_addw_addw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_r1, | ||
| 112 | BN_ULONG *out_r0) | ||
| 113 | { | ||
| 114 | BN_ULONG carry, r1, r0; | ||
| 115 | |||
| 116 | bn_addw(a, b, &r1, &r0); | ||
| 117 | bn_addw(r0, c, &carry, &r0); | ||
| 118 | r1 += carry; | ||
| 119 | |||
| 120 | *out_r1 = r1; | ||
| 121 | *out_r0 = r0; | ||
| 122 | } | ||
| 123 | #endif | ||
| 124 | |||
| 125 | /* | ||
| 126 | * bn_subw() computes r0 = a - b, where both inputs are single words, | ||
| 127 | * producing a single word result and borrow. | ||
| 128 | */ | ||
| 129 | #ifndef HAVE_BN_SUBW | ||
| 130 | static inline void | ||
| 131 | bn_subw(BN_ULONG a, BN_ULONG b, BN_ULONG *out_borrow, BN_ULONG *out_r0) | ||
| 132 | { | ||
| 133 | BN_ULONG borrow, r0; | ||
| 134 | |||
| 135 | r0 = a - b; | ||
| 136 | borrow = ((r0 | (b & ~a)) & (b | ~a)) >> (BN_BITS2 - 1); | ||
| 137 | |||
| 138 | *out_borrow = borrow; | ||
| 139 | *out_r0 = r0; | ||
| 140 | } | ||
| 141 | #endif | ||
| 142 | |||
| 143 | /* | ||
| 144 | * bn_subw_subw() computes r0 = a - b - c, where all inputs are single words, | ||
| 145 | * producing a single word result and borrow. | ||
| 146 | */ | ||
| 147 | #ifndef HAVE_BN_SUBW_SUBW | ||
| 148 | static inline void | ||
| 149 | bn_subw_subw(BN_ULONG a, BN_ULONG b, BN_ULONG c, BN_ULONG *out_borrow, | ||
| 150 | BN_ULONG *out_r0) | ||
| 151 | { | ||
| 152 | BN_ULONG b1, b2, r0; | ||
| 153 | |||
| 154 | bn_subw(a, b, &b1, &r0); | ||
| 155 | bn_subw(r0, c, &b2, &r0); | ||
| 156 | |||
| 157 | *out_borrow = b1 + b2; | ||
| 158 | *out_r0 = r0; | ||
| 159 | } | ||
| 160 | #endif | ||
| 161 | |||
| 105 | #ifndef HAVE_BN_UMUL_HILO | 162 | #ifndef HAVE_BN_UMUL_HILO |
| 106 | #ifdef BN_LLONG | 163 | #ifdef BN_LLONG |
| 107 | static inline void | 164 | static inline void |
