summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/bn/bn_add.c140
-rw-r--r--src/lib/libcrypto/bn/bn_internal.h59
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
68BN_ULONG bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b); 69BN_ULONG bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b);
69BN_ULONG bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b); 70BN_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
73BN_ULONG 77BN_ULONG
74bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) 78bn_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 */
114BN_ULONG
115bn_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
174BN_ULONG 115BN_ULONG
175bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) 116bn_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
233BN_ULONG 153BN_ULONG
234bn_add(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) 154bn_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
278BN_ULONG 198BN_ULONG
279bn_sub(BIGNUM *r, int rn, const BIGNUM *a, const BIGNUM *b) 199bn_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
110static inline void
111bn_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
130static inline void
131bn_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
148static inline void
149bn_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
107static inline void 164static inline void