summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bn/bn_div.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bn/bn_div.c')
-rw-r--r--src/lib/libcrypto/bn/bn_div.c84
1 files changed, 83 insertions, 1 deletions
diff --git a/src/lib/libcrypto/bn/bn_div.c b/src/lib/libcrypto/bn/bn_div.c
index df4b7517d7..8ec2e01831 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.32 2023/01/20 10:07:52 jsing Exp $ */ 1/* $OpenBSD: bn_div.c,v 1.33 2023/01/23 12:02:48 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 *
@@ -56,6 +56,7 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58 58
59#include <assert.h>
59#include <stdio.h> 60#include <stdio.h>
60 61
61#include <openssl/opensslconf.h> 62#include <openssl/opensslconf.h>
@@ -68,6 +69,87 @@
68 69
69BN_ULONG bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0); 70BN_ULONG bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0);
70 71
72#ifndef HAVE_BN_DIV_WORDS
73#if defined(BN_LLONG) && defined(BN_DIV2W)
74
75BN_ULONG
76bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
77{
78 return ((BN_ULONG)(((((BN_ULLONG)h) << BN_BITS2)|l)/(BN_ULLONG)d));
79}
80
81#else
82
83/* Divide h,l by d and return the result. */
84/* I need to test this some more :-( */
85BN_ULONG
86bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
87{
88 BN_ULONG dh, dl, q,ret = 0, th, tl, t;
89 int i, count = 2;
90
91 if (d == 0)
92 return (BN_MASK2);
93
94 i = BN_num_bits_word(d);
95 assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
96
97 i = BN_BITS2 - i;
98 if (h >= d)
99 h -= d;
100
101 if (i) {
102 d <<= i;
103 h = (h << i) | (l >> (BN_BITS2 - i));
104 l <<= i;
105 }
106 dh = (d & BN_MASK2h) >> BN_BITS4;
107 dl = (d & BN_MASK2l);
108 for (;;) {
109 if ((h >> BN_BITS4) == dh)
110 q = BN_MASK2l;
111 else
112 q = h / dh;
113
114 th = q * dh;
115 tl = dl * q;
116 for (;;) {
117 t = h - th;
118 if ((t & BN_MASK2h) ||
119 ((tl) <= (
120 (t << BN_BITS4) |
121 ((l & BN_MASK2h) >> BN_BITS4))))
122 break;
123 q--;
124 th -= dh;
125 tl -= dl;
126 }
127 t = (tl >> BN_BITS4);
128 tl = (tl << BN_BITS4) & BN_MASK2h;
129 th += t;
130
131 if (l < tl)
132 th++;
133 l -= tl;
134 if (h < th) {
135 h += d;
136 q--;
137 }
138 h -= th;
139
140 if (--count == 0)
141 break;
142
143 ret = q << BN_BITS4;
144 h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
145 l = (l & BN_MASK2l) << BN_BITS4;
146 }
147 ret |= q;
148 return (ret);
149}
150#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */
151#endif
152
71#ifndef HAVE_BN_DIV_3_WORDS 153#ifndef HAVE_BN_DIV_3_WORDS
72 154
73#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) 155#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)