1
/* crypto/bn/bn_lcl.h */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
5
* This package is an SSL implementation written
6
* by Eric Young (eay@cryptsoft.com).
7
* The implementation was written so as to conform with Netscapes SSL.
9
* This library is free for commercial and non-commercial use as long as
10
* the following conditions are aheared to. The following conditions
11
* apply to all code found in this distribution, be it the RC4, RSA,
12
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
13
* included with this distribution is covered by the same copyright terms
14
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
16
* Copyright remains Eric Young's, and as such any Copyright notices in
17
* the code are not to be removed.
18
* If this package is used in a product, Eric Young should be given attribution
19
* as the author of the parts of the library used.
20
* This can be in the form of a textual message at program startup or
21
* in documentation (online or textual) provided with the package.
23
* Redistribution and use in source and binary forms, with or without
24
* modification, are permitted provided that the following conditions
26
* 1. Redistributions of source code must retain the copyright
27
* notice, this list of conditions and the following disclaimer.
28
* 2. Redistributions in binary form must reproduce the above copyright
29
* notice, this list of conditions and the following disclaimer in the
30
* documentation and/or other materials provided with the distribution.
31
* 3. All advertising materials mentioning features or use of this software
32
* must display the following acknowledgement:
33
* "This product includes cryptographic software written by
34
* Eric Young (eay@cryptsoft.com)"
35
* The word 'cryptographic' can be left out if the rouines from the library
36
* being used are not cryptographic related :-).
37
* 4. If you include any Windows specific code (or a derivative thereof) from
38
* the apps directory (application code) you must include an acknowledgement:
39
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
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
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.]
58
/* ====================================================================
59
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
61
* Redistribution and use in source and binary forms, with or without
62
* modification, are permitted provided that the following conditions
65
* 1. Redistributions of source code must retain the above copyright
66
* notice, this list of conditions and the following disclaimer.
68
* 2. Redistributions in binary form must reproduce the above copyright
69
* notice, this list of conditions and the following disclaimer in
70
* the documentation and/or other materials provided with the
73
* 3. All advertising materials mentioning features or use of this
74
* software must display the following acknowledgment:
75
* "This product includes software developed by the OpenSSL Project
76
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
78
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79
* endorse or promote products derived from this software without
80
* prior written permission. For written permission, please contact
81
* openssl-core@openssl.org.
83
* 5. Products derived from this software may not be called "OpenSSL"
84
* nor may "OpenSSL" appear in their names without prior written
85
* permission of the OpenSSL Project.
87
* 6. Redistributions of any form whatsoever must retain the following
89
* "This product includes software developed by the OpenSSL Project
90
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
92
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103
* OF THE POSSIBILITY OF SUCH DAMAGE.
104
* ====================================================================
106
* This product includes cryptographic software written by Eric Young
107
* (eay@cryptsoft.com). This product includes software written by Tim
108
* Hudson (tjh@cryptsoft.com).
112
#ifndef HEADER_BN_LCL_H
113
#define HEADER_BN_LCL_H
123
* BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
126
* For window size 'w' (w >= 2) and a random 'b' bits exponent,
127
* the number of multiplications is a constant plus on average
129
* 2^(w-1) + (b-w)/(w+1);
131
* here 2^(w-1) is for precomputing the table (we actually need
132
* entries only for windows that have the lowest bit set), and
133
* (b-w)/(w+1) is an approximation for the expected number of
134
* w-bit windows, not counting the first one.
139
* w = 5 if 671 > b > 239
140
* w = 4 if 239 > b > 79
141
* w = 3 if 79 > b > 23
144
* (with draws in between). Very small exponents are often selected
145
* with low Hamming weight, so we use w = 1 for b <= 23.
148
#define BN_window_bits_for_exponent_size(b) \
154
/* Old SSLeay/OpenSSL table.
155
* Maximum window size was 5, so this table differs for b==1024;
156
* but it coincides for other interesting values (b==160, b==512).
158
#define BN_window_bits_for_exponent_size(b) \
166
/* Pentium pro 16,16,16,32,64 */
167
/* Alpha 16,16,16,16.64 */
168
#define BN_MULL_SIZE_NORMAL (16) /* 32 */
169
#define BN_MUL_RECURSIVE_SIZE_NORMAL (16) /* 32 less than */
170
#define BN_SQR_RECURSIVE_SIZE_NORMAL (16) /* 32 */
171
#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
172
#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */
174
#if !defined(NO_ASM) && !defined(NO_INLINE_ASM) && !defined(PEDANTIC)
176
* BN_UMULT_HIGH section.
178
* No, I'm not trying to overwhelm you when stating that the
179
* product of N-bit numbers is 2*N bits wide:-) No, I don't expect
180
* you to be impressed when I say that if the compiler doesn't
181
* support 2*N integer type, then you have to replace every N*N
182
* multiplication with 4 (N/2)*(N/2) accompanied by some shifts
183
* and additions which unavoidably results in severe performance
184
* penalties. Of course provided that the hardware is capable of
185
* producing 2*N result... That's when you normally start
186
* considering assembler implementation. However! It should be
187
* pointed out that some CPUs (most notably Alpha, PowerPC and
188
* upcoming IA-64 family:-) provide *separate* instruction
189
* calculating the upper half of the product placing the result
190
* into a general purpose register. Now *if* the compiler supports
191
* inline assembler, then it's not impossible to implement the
192
* "bignum" routines (and have the compiler optimize 'em)
193
* exhibiting "native" performance in C. That's what BN_UMULT_HIGH
196
* <appro@fy.chalmers.se>
198
# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
201
# define BN_UMULT_HIGH(a,b) (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
202
# elif defined(__GNUC__)
203
# define BN_UMULT_HIGH(a,b) ({ \
204
register BN_ULONG ret; \
205
asm ("umulh %1,%2,%0" \
209
# endif /* compiler */
210
# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
211
# if defined(__GNUC__)
212
# define BN_UMULT_HIGH(a,b) ({ \
213
register BN_ULONG ret; \
214
asm ("mulhdu %0,%1,%2" \
218
# endif /* compiler */
222
/*************************************************************
223
* Using the long long type
225
#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
226
#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
228
/* This is used for internal error checking and is not normally used */
231
# define bn_check_top(a) assert ((a)->top >= 0 && (a)->top <= (a)->dmax);
233
# define bn_check_top(a)
236
/* This macro is to add extra stuff for development checking */
238
#define bn_set_max(r) ((r)->max=(r)->top,BN_set_flags((r),BN_FLG_STATIC_DATA))
240
#define bn_set_max(r)
243
/* These macros are used to 'take' a section of a bignum for read only use */
244
#define bn_set_low(r,a,n) \
246
(r)->top=((a)->top > (n))?(n):(a)->top; \
249
(r)->flags|=BN_FLG_STATIC_DATA; \
253
#define bn_set_high(r,a,n) \
255
if ((a)->top > (n)) \
257
(r)->top=(a)->top-n; \
258
(r)->d= &((a)->d[n]); \
263
(r)->flags|=BN_FLG_STATIC_DATA; \
268
#define mul_add(r,a,w,c) { \
270
t=(BN_ULLONG)w * (a) + (r) + (c); \
275
#define mul(r,a,w,c) { \
277
t=(BN_ULLONG)w * (a) + (c); \
282
#define sqr(r0,r1,a) { \
284
t=(BN_ULLONG)(a)*(a); \
289
#elif defined(BN_UMULT_HIGH)
290
#define mul_add(r,a,w,c) { \
291
BN_ULONG high,low,ret,tmp=(a); \
293
high= BN_UMULT_HIGH(w,tmp); \
296
(c) = (ret<(c))?1:0; \
299
(c) += (ret<low)?1:0; \
303
#define mul(r,a,w,c) { \
304
BN_ULONG high,low,ret,ta=(a); \
306
high= BN_UMULT_HIGH(w,ta); \
309
(c) += (ret<low)?1:0; \
313
#define sqr(r0,r1,a) { \
316
(r1) = BN_UMULT_HIGH(tmp,tmp); \
320
/*************************************************************
324
#define LBITS(a) ((a)&BN_MASK2l)
325
#define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l)
326
#define L2HBITS(a) ((BN_ULONG)((a)&BN_MASK2l)<<BN_BITS4)
328
#define LLBITS(a) ((a)&BN_MASKl)
329
#define LHBITS(a) (((a)>>BN_BITS2)&BN_MASKl)
330
#define LL2HBITS(a) ((BN_ULLONG)((a)&BN_MASKl)<<BN_BITS2)
332
#define mul64(l,h,bl,bh) \
334
BN_ULONG m,m1,lt,ht; \
342
m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS(1L); \
345
lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
350
#define sqr64(lo,ho,in) \
360
h+=(m&BN_MASK2h1)>>(BN_BITS4-1); \
361
m =(m&BN_MASK2l)<<(BN_BITS4+1); \
362
l=(l+m)&BN_MASK2; if (l < m) h++; \
367
#define mul_add(r,a,bl,bh,c) { \
373
mul64(l,h,(bl),(bh)); \
375
/* non-multiply part */ \
376
l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
378
l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
383
#define mul(r,a,bl,bh,c) { \
389
mul64(l,h,(bl),(bh)); \
391
/* non-multiply part */ \
392
l+=(c); if ((l&BN_MASK2) < (c)) h++; \
396
#endif /* !BN_LLONG */
398
void bn_mul_normal(BN_ULONG *r,BN_ULONG *a,int na,BN_ULONG *b,int nb);
399
void bn_mul_comba8(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
400
void bn_mul_comba4(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b);
401
void bn_sqr_normal(BN_ULONG *r, BN_ULONG *a, int n, BN_ULONG *tmp);
402
void bn_sqr_comba8(BN_ULONG *r,BN_ULONG *a);
403
void bn_sqr_comba4(BN_ULONG *r,BN_ULONG *a);
404
int bn_cmp_words(BN_ULONG *a,BN_ULONG *b,int n);
405
void bn_mul_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,BN_ULONG *t);
406
void bn_mul_part_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,
407
int tn, int n,BN_ULONG *t);
408
void bn_sqr_recursive(BN_ULONG *r,BN_ULONG *a, int n2, BN_ULONG *t);
409
void bn_mul_low_normal(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b, int n);
410
void bn_mul_low_recursive(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,int n2,
412
void bn_mul_high(BN_ULONG *r,BN_ULONG *a,BN_ULONG *b,BN_ULONG *l,int n2,