diff options
Diffstat (limited to 'src/lib/libcrypto/bn/bn_div.c')
-rw-r--r-- | src/lib/libcrypto/bn/bn_div.c | 84 |
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 | ||
69 | BN_ULONG bn_div_3_words(const BN_ULONG *m, BN_ULONG d1, BN_ULONG d0); | 70 | BN_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 | |||
75 | BN_ULONG | ||
76 | bn_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 :-( */ | ||
85 | BN_ULONG | ||
86 | bn_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) |