summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/bn/bn_div.c64
1 files changed, 15 insertions, 49 deletions
diff --git a/src/lib/libcrypto/bn/bn_div.c b/src/lib/libcrypto/bn/bn_div.c
index e8f17fff03..acacfb1a8c 100644
--- a/src/lib/libcrypto/bn/bn_div.c
+++ b/src/lib/libcrypto/bn/bn_div.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_div.c,v 1.35 2023/01/28 16:58:24 jsing Exp $ */ 1/* $OpenBSD: bn_div.c,v 1.36 2023/01/31 06:08:23 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,6 +66,7 @@
66 66
67#include "bn_arch.h" 67#include "bn_arch.h"
68#include "bn_local.h" 68#include "bn_local.h"
69#include "bn_internal.h"
69 70
70BN_ULONG bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0); 71BN_ULONG bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0);
71 72
@@ -191,7 +192,7 @@ bn_div_rem_words(BN_ULONG h, BN_ULONG l, BN_ULONG d, BN_ULONG *out_q,
191BN_ULONG 192BN_ULONG
192bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0) 193bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0)
193{ 194{
194 BN_ULONG n0, n1, q; 195 BN_ULONG n0, n1, q, t2h, t2l;
195 BN_ULONG rem = 0; 196 BN_ULONG rem = 0;
196 197
197 n0 = m[0]; 198 n0 = m[0];
@@ -201,55 +202,20 @@ bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0)
201 return BN_MASK2; 202 return BN_MASK2;
202 203
203 /* n0 < d0 */ 204 /* n0 < d0 */
204 { 205 bn_div_rem_words(n0, n1, d0, &q, &rem);
205#ifdef BN_LLONG
206 BN_ULLONG t2;
207 206
208 bn_div_rem_words(n0, n1, d0, &q, &rem); 207 bn_umul_hilo(d1, q, &t2h, &t2l);
209 208
210 t2 = (BN_ULLONG)d1 * q; 209 for (;;) {
211 210 if (t2h < rem || (t2h == rem && t2l <= m[-2]))
212 for (;;) { 211 break;
213 if (t2 <= (((BN_ULLONG)rem << BN_BITS2) | m[-2])) 212 q--;
214 break; 213 rem += d0;
215 q--; 214 if (rem < d0)
216 rem += d0; 215 break; /* don't let rem overflow */
217 if (rem < d0) break; /* don't let rem overflow */ 216 if (t2l < d1)
218 t2 -= d1; 217 t2h--;
219 } 218 t2l -= d1;
220#else /* !BN_LLONG */
221 BN_ULONG t2l, t2h;
222
223 bn_div_rem_words(n0, n1, d0, &q, &rem);
224
225#if defined(BN_UMULT_LOHI)
226 BN_UMULT_LOHI(t2l, t2h, d1, q);
227#elif defined(BN_UMULT_HIGH)
228 t2l = d1 * q;
229 t2h = BN_UMULT_HIGH(d1, q);
230#else
231 {
232 BN_ULONG ql, qh;
233 t2l = LBITS(d1);
234 t2h = HBITS(d1);
235 ql = LBITS(q);
236 qh = HBITS(q);
237 mul64(t2l, t2h, ql, qh); /* t2 = (BN_ULLONG)d1 * q; */
238 }
239#endif
240
241 for (;;) {
242 if (t2h < rem || (t2h == rem && t2l <= m[-2]))
243 break;
244 q--;
245 rem += d0;
246 if (rem < d0)
247 break; /* don't let rem overflow */
248 if (t2l < d1)
249 t2h--;
250 t2l -= d1;
251 }
252#endif /* !BN_LLONG */
253 } 219 }
254 220
255 return q; 221 return q;