summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/bn/arch/amd64/bn_arch.c17
-rw-r--r--src/lib/libcrypto/bn/bn_add.c157
-rw-r--r--src/lib/libcrypto/bn/bn_local.h7
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
25BN_ULONG 25BN_ULONG
26bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) 26bn_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
34BN_ULONG 36BN_ULONG
35bn_add_words(BN_ULONG *rd, const BN_ULONG *ad, const BN_ULONG *bd, int n) 37bn_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
43BN_ULONG 45BN_ULONG
44bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) 46bn_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
69BN_ULONG bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b);
70BN_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
113BN_ULONG
114bn_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
153BN_ULONG 198BN_ULONG
154bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) 199bn_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. */
198BN_ULONG 219 bn_subw(0 - b[0], borrow, &borrow, &r[0]);
199bn_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
246BN_ULONG bn_add(BN_ULONG *r, int r_len, const BN_ULONG *a, int a_len,
247 const BN_ULONG *b, int b_len);
248BN_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
246void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb); 251void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb);
247void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); 252void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
248void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); 253void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);