41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59 #include <stdio.h>
60 #include <openssl/bn.h>
61 #include "cryptlib.h"
62 #include "bn_lcl.h"
63
64
65 /* The old slow way */
66 #if 0
67 int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
68 BN_CTX *ctx)
69 {
70 int i,nm,nd;
71 int ret = 0;
72 BIGNUM *D;
73
74 bn_check_top(m);
75 bn_check_top(d);
76 if (BN_is_zero(d))
77 {
78 BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
79 return(0);
80 }
81
82 if (BN_ucmp(m,d) < 0)
126 }
127
128 #else
129
130 #if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
131 && !defined(PEDANTIC) && !defined(BN_DIV3W)
132 # if defined(__GNUC__) && __GNUC__>=2
133 # if defined(__i386) || defined (__i386__)
134 /*
135 * There were two reasons for implementing this template:
136 * - GNU C generates a call to a function (__udivdi3 to be exact)
137 * in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
138 * understand why...);
139 * - divl doesn't only calculate quotient, but also leaves
140 * remainder in %edx which we can definitely use here:-)
141 *
142 * <appro@fy.chalmers.se>
143 */
144 #undef bn_div_words
145 # define bn_div_words(n0,n1,d0) \
146 ({ asm volatile ( \
147 "divl %4" \
148 : "=a"(q), "=d"(rem) \
149 : "a"(n1), "d"(n0), "g"(d0) \
150 : "cc"); \
151 q; \
152 })
153 # define REMAINDER_IS_ALREADY_CALCULATED
154 # elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
155 /*
156 * Same story here, but it's 128-bit by 64-bit division. Wow!
157 * <appro@fy.chalmers.se>
158 */
159 # undef bn_div_words
160 # define bn_div_words(n0,n1,d0) \
161 ({ asm volatile ( \
162 "divq %4" \
163 : "=a"(q), "=d"(rem) \
164 : "a"(n1), "d"(n0), "g"(d0) \
165 : "cc"); \
166 q; \
167 })
168 # define REMAINDER_IS_ALREADY_CALCULATED
169 # endif /* __<cpu> */
170 # endif /* __GNUC__ */
171 #endif /* OPENSSL_NO_ASM */
172
173
174 /* BN_div computes dv := num / divisor, rounding towards
175 * zero, and sets up rm such that dv*divisor + rm = num holds.
176 * Thus:
177 * dv->neg == num->neg ^ divisor->neg (unless the result is zero)
178 * rm->neg == num->neg (unless the remainder is zero)
179 * If 'dv' or 'rm' is NULL, the respective value is not returned.
180 */
181 int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59 #include <stdio.h>
60 #include <openssl/bn.h>
61 #include <cryptlib.h>
62 #include <bn_lcl.h>
63
64
65 /* The old slow way */
66 #if 0
67 int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
68 BN_CTX *ctx)
69 {
70 int i,nm,nd;
71 int ret = 0;
72 BIGNUM *D;
73
74 bn_check_top(m);
75 bn_check_top(d);
76 if (BN_is_zero(d))
77 {
78 BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO);
79 return(0);
80 }
81
82 if (BN_ucmp(m,d) < 0)
126 }
127
128 #else
129
130 #if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
131 && !defined(PEDANTIC) && !defined(BN_DIV3W)
132 # if defined(__GNUC__) && __GNUC__>=2
133 # if defined(__i386) || defined (__i386__)
134 /*
135 * There were two reasons for implementing this template:
136 * - GNU C generates a call to a function (__udivdi3 to be exact)
137 * in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
138 * understand why...);
139 * - divl doesn't only calculate quotient, but also leaves
140 * remainder in %edx which we can definitely use here:-)
141 *
142 * <appro@fy.chalmers.se>
143 */
144 #undef bn_div_words
145 # define bn_div_words(n0,n1,d0) \
146 ({ __asm volatile ( \
147 "divl %4" \
148 : "=a"(q), "=d"(rem) \
149 : "a"(n1), "d"(n0), "g"(d0) \
150 : "cc"); \
151 q; \
152 })
153 # define REMAINDER_IS_ALREADY_CALCULATED
154 # elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
155 /*
156 * Same story here, but it's 128-bit by 64-bit division. Wow!
157 * <appro@fy.chalmers.se>
158 */
159 # undef bn_div_words
160 # define bn_div_words(n0,n1,d0) \
161 ({ __asm volatile ( \
162 "divq %4" \
163 : "=a"(q), "=d"(rem) \
164 : "a"(n1), "d"(n0), "g"(d0) \
165 : "cc"); \
166 q; \
167 })
168 # define REMAINDER_IS_ALREADY_CALCULATED
169 # endif /* __<cpu> */
170 # endif /* __GNUC__ */
171 #endif /* OPENSSL_NO_ASM */
172
173
174 /* BN_div computes dv := num / divisor, rounding towards
175 * zero, and sets up rm such that dv*divisor + rm = num holds.
176 * Thus:
177 * dv->neg == num->neg ^ divisor->neg (unless the result is zero)
178 * rm->neg == num->neg (unless the remainder is zero)
179 * If 'dv' or 'rm' is NULL, the respective value is not returned.
180 */
181 int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|