diff options
-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); |