1 /* $OpenBSD: bn_nist.c,v 1.18 2016/07/18 01:04:52 bcook Exp $ */
3 * Written by Nils Larsch for the OpenSSL project
5 /* ====================================================================
6 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * openssl-core@openssl.org.
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
34 * 6. Redistributions of any form whatsoever must retain the following
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
59 #include <machine/endian.h>
66 #define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2
67 #define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2
68 #define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2
69 #define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2
70 #define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2
72 /* pre-computed tables are "carry-less" values of modulus*(i+1) */
74 static const BN_ULONG _nist_p_192
[][BN_NIST_192_TOP
] = {
75 {0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFEULL
, 0xFFFFFFFFFFFFFFFFULL
},
76 {0xFFFFFFFFFFFFFFFEULL
, 0xFFFFFFFFFFFFFFFDULL
, 0xFFFFFFFFFFFFFFFFULL
},
77 {0xFFFFFFFFFFFFFFFDULL
, 0xFFFFFFFFFFFFFFFCULL
, 0xFFFFFFFFFFFFFFFFULL
}
79 static const BN_ULONG _nist_p_192_sqr
[] = {
80 0x0000000000000001ULL
, 0x0000000000000002ULL
, 0x0000000000000001ULL
,
81 0xFFFFFFFFFFFFFFFEULL
, 0xFFFFFFFFFFFFFFFDULL
, 0xFFFFFFFFFFFFFFFFULL
83 static const BN_ULONG _nist_p_224
[][BN_NIST_224_TOP
] = {
85 0x0000000000000001ULL
, 0xFFFFFFFF00000000ULL
,
86 0xFFFFFFFFFFFFFFFFULL
, 0x00000000FFFFFFFFULL
89 0x0000000000000002ULL
, 0xFFFFFFFE00000000ULL
,
90 0xFFFFFFFFFFFFFFFFULL
, 0x00000001FFFFFFFFULL
91 } /* this one is "carry-full" */
93 static const BN_ULONG _nist_p_224_sqr
[] = {
94 0x0000000000000001ULL
, 0xFFFFFFFE00000000ULL
,
95 0xFFFFFFFFFFFFFFFFULL
, 0x0000000200000000ULL
,
96 0x0000000000000000ULL
, 0xFFFFFFFFFFFFFFFEULL
,
99 static const BN_ULONG _nist_p_256
[][BN_NIST_256_TOP
] = {
101 0xFFFFFFFFFFFFFFFFULL
, 0x00000000FFFFFFFFULL
,
102 0x0000000000000000ULL
, 0xFFFFFFFF00000001ULL
105 0xFFFFFFFFFFFFFFFEULL
, 0x00000001FFFFFFFFULL
,
106 0x0000000000000000ULL
, 0xFFFFFFFE00000002ULL
109 0xFFFFFFFFFFFFFFFDULL
, 0x00000002FFFFFFFFULL
,
110 0x0000000000000000ULL
, 0xFFFFFFFD00000003ULL
113 0xFFFFFFFFFFFFFFFCULL
, 0x00000003FFFFFFFFULL
,
114 0x0000000000000000ULL
, 0xFFFFFFFC00000004ULL
117 0xFFFFFFFFFFFFFFFBULL
, 0x00000004FFFFFFFFULL
,
118 0x0000000000000000ULL
, 0xFFFFFFFB00000005ULL
121 static const BN_ULONG _nist_p_256_sqr
[] = {
122 0x0000000000000001ULL
, 0xFFFFFFFE00000000ULL
,
123 0xFFFFFFFFFFFFFFFFULL
, 0x00000001FFFFFFFEULL
,
124 0x00000001FFFFFFFEULL
, 0x00000001FFFFFFFEULL
,
125 0xFFFFFFFE00000001ULL
, 0xFFFFFFFE00000002ULL
127 static const BN_ULONG _nist_p_384
[][BN_NIST_384_TOP
] = {
129 0x00000000FFFFFFFFULL
, 0xFFFFFFFF00000000ULL
,
130 0xFFFFFFFFFFFFFFFEULL
, 0xFFFFFFFFFFFFFFFFULL
,
131 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
134 0x00000001FFFFFFFEULL
, 0xFFFFFFFE00000000ULL
,
135 0xFFFFFFFFFFFFFFFDULL
, 0xFFFFFFFFFFFFFFFFULL
,
136 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
139 0x00000002FFFFFFFDULL
, 0xFFFFFFFD00000000ULL
,
140 0xFFFFFFFFFFFFFFFCULL
, 0xFFFFFFFFFFFFFFFFULL
,
141 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
144 0x00000003FFFFFFFCULL
, 0xFFFFFFFC00000000ULL
,
145 0xFFFFFFFFFFFFFFFBULL
, 0xFFFFFFFFFFFFFFFFULL
,
146 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
149 0x00000004FFFFFFFBULL
, 0xFFFFFFFB00000000ULL
,
150 0xFFFFFFFFFFFFFFFAULL
, 0xFFFFFFFFFFFFFFFFULL
,
151 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
154 static const BN_ULONG _nist_p_384_sqr
[] = {
155 0xFFFFFFFE00000001ULL
, 0x0000000200000000ULL
, 0xFFFFFFFE00000000ULL
,
156 0x0000000200000000ULL
, 0x0000000000000001ULL
, 0x0000000000000000ULL
,
157 0x00000001FFFFFFFEULL
, 0xFFFFFFFE00000000ULL
, 0xFFFFFFFFFFFFFFFDULL
,
158 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
160 static const BN_ULONG _nist_p_521
[] = {
161 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
,
162 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
,
163 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
, 0x00000000000001FFULL
165 static const BN_ULONG _nist_p_521_sqr
[] = {
166 0x0000000000000001ULL
, 0x0000000000000000ULL
, 0x0000000000000000ULL
,
167 0x0000000000000000ULL
, 0x0000000000000000ULL
, 0x0000000000000000ULL
,
168 0x0000000000000000ULL
, 0x0000000000000000ULL
, 0xFFFFFFFFFFFFFC00ULL
,
169 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
,
170 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
, 0xFFFFFFFFFFFFFFFFULL
,
171 0xFFFFFFFFFFFFFFFFULL
, 0x000000000003FFFFULL
174 static const BN_ULONG _nist_p_192
[][BN_NIST_192_TOP
] = {
176 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
177 0xFFFFFFFF, 0xFFFFFFFF
180 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF,
181 0xFFFFFFFF, 0xFFFFFFFF
184 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF,
185 0xFFFFFFFF, 0xFFFFFFFF
188 static const BN_ULONG _nist_p_192_sqr
[] = {
189 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000,
190 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
192 static const BN_ULONG _nist_p_224
[][BN_NIST_224_TOP
] = {
194 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF,
195 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
198 0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE,
199 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
202 static const BN_ULONG _nist_p_224_sqr
[] = {
203 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
204 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000002,
205 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
206 0xFFFFFFFF, 0xFFFFFFFF
208 static const BN_ULONG _nist_p_256
[][BN_NIST_256_TOP
] = {
210 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
211 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF
214 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001,
215 0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE
218 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002,
219 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD
222 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
223 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC
226 0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004,
227 0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB
230 static const BN_ULONG _nist_p_256_sqr
[] = {
231 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
232 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001,
233 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001,
234 0x00000001, 0xFFFFFFFE, 0x00000002, 0xFFFFFFFE
236 static const BN_ULONG _nist_p_384
[][BN_NIST_384_TOP
] = {
238 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF,
239 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
240 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
243 0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE,
244 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
245 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
248 0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD,
249 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
250 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
253 0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC,
254 0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
255 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
258 0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB,
259 0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
260 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
263 static const BN_ULONG _nist_p_384_sqr
[] = {
264 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
265 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
266 0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
267 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
269 static const BN_ULONG _nist_p_521
[] = {
270 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
271 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
272 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
273 0xFFFFFFFF, 0x000001FF
275 static const BN_ULONG _nist_p_521_sqr
[] = {
276 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
277 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
278 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFC00, 0xFFFFFFFF,
279 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
280 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
281 0xFFFFFFFF, 0xFFFFFFFF, 0x0003FFFF
284 #error "unsupported BN_BITS2"
287 static const BIGNUM _bignum_nist_p_192
= {
288 (BN_ULONG
*)_nist_p_192
[0],
295 static const BIGNUM _bignum_nist_p_224
= {
296 (BN_ULONG
*)_nist_p_224
[0],
303 static const BIGNUM _bignum_nist_p_256
= {
304 (BN_ULONG
*)_nist_p_256
[0],
311 static const BIGNUM _bignum_nist_p_384
= {
312 (BN_ULONG
*)_nist_p_384
[0],
319 static const BIGNUM _bignum_nist_p_521
= {
320 (BN_ULONG
*)_nist_p_521
,
329 BN_get0_nist_prime_192(void)
331 return &_bignum_nist_p_192
;
335 BN_get0_nist_prime_224(void)
337 return &_bignum_nist_p_224
;
341 BN_get0_nist_prime_256(void)
343 return &_bignum_nist_p_256
;
347 BN_get0_nist_prime_384(void)
349 return &_bignum_nist_p_384
;
353 BN_get0_nist_prime_521(void)
355 return &_bignum_nist_p_521
;
359 nist_cp_bn_0(BN_ULONG
*dst
, const BN_ULONG
*src
, int top
, int max
)
364 OPENSSL_assert(top
<= max
);
366 for (i
= 0; i
< top
; i
++)
372 static void nist_cp_bn(BN_ULONG
*dst
, const BN_ULONG
*src
, int top
)
376 for (i
= 0; i
< top
; i
++)
381 #define bn_cp_64(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0;
382 #define bn_64_set_0(to, n) (to)[n] = (BN_ULONG)0;
384 * two following macros are implemented under assumption that they
385 * are called in a sequence with *ascending* n, i.e. as they are...
387 #define bn_cp_32_naked(to, n, from, m) (((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\
388 :(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
389 #define bn_32_set_0(to, n) (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
390 #define bn_cp_32(to,n,from,m) ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
391 # if BYTE_ORDER == LITTLE_ENDIAN
393 # define NIST_INT64 long
395 # define NIST_INT64 long long
399 #define bn_cp_64(to, n, from, m) \
401 bn_cp_32(to, (n)*2, from, (m)*2); \
402 bn_cp_32(to, (n)*2+1, from, (m)*2+1); \
404 #define bn_64_set_0(to, n) \
406 bn_32_set_0(to, (n)*2); \
407 bn_32_set_0(to, (n)*2+1); \
409 #define bn_cp_32(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0;
410 #define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0;
411 # if defined(BN_LLONG)
412 # define NIST_INT64 long long
414 #endif /* BN_BITS2 != 64 */
416 #define nist_set_192(to, from, a1, a2, a3) \
418 bn_cp_64(to, 0, from, (a3) - 3) \
419 bn_cp_64(to, 1, from, (a2) - 3) \
420 bn_cp_64(to, 2, from, (a1) - 3) \
424 BN_nist_mod_192(BIGNUM
*r
, const BIGNUM
*a
, const BIGNUM
*field
, BN_CTX
*ctx
)
428 BN_ULONG
*r_d
, *a_d
= a
->d
;
430 BN_ULONG bn
[BN_NIST_192_TOP
];
431 unsigned int ui
[BN_NIST_192_TOP
*
432 sizeof(BN_ULONG
) / sizeof(unsigned int)];
434 BN_ULONG c_d
[BN_NIST_192_TOP
], *res
;
436 static const BIGNUM _bignum_nist_p_192_sqr
= {
437 (BN_ULONG
*)_nist_p_192_sqr
,
438 sizeof(_nist_p_192_sqr
) / sizeof(_nist_p_192_sqr
[0]),
439 sizeof(_nist_p_192_sqr
) / sizeof(_nist_p_192_sqr
[0]),
444 field
= &_bignum_nist_p_192
; /* just to make sure */
446 if (BN_is_negative(a
) || BN_ucmp(a
, &_bignum_nist_p_192_sqr
) >= 0)
447 return BN_nnmod(r
, a
, field
, ctx
);
449 i
= BN_ucmp(field
, a
);
454 return (r
== a
) ? 1 : (BN_copy(r
, a
) != NULL
);
457 if (!bn_wexpand(r
, BN_NIST_192_TOP
))
460 nist_cp_bn(r_d
, a_d
, BN_NIST_192_TOP
);
464 nist_cp_bn_0(buf
.bn
, a_d
+ BN_NIST_192_TOP
, top
- BN_NIST_192_TOP
,
467 #if defined(NIST_INT64)
469 NIST_INT64 acc
; /* accumulator */
470 unsigned int *rp
= (unsigned int *)r_d
;
471 const unsigned int *bp
= (const unsigned int *)buf
.ui
;
474 acc
+= bp
[3 * 2 - 6];
475 acc
+= bp
[5 * 2 - 6];
476 rp
[0] = (unsigned int)acc
;
480 acc
+= bp
[3 * 2 - 5];
481 acc
+= bp
[5 * 2 - 5];
482 rp
[1] = (unsigned int)acc
;
486 acc
+= bp
[3 * 2 - 6];
487 acc
+= bp
[4 * 2 - 6];
488 acc
+= bp
[5 * 2 - 6];
489 rp
[2] = (unsigned int)acc
;
493 acc
+= bp
[3 * 2 - 5];
494 acc
+= bp
[4 * 2 - 5];
495 acc
+= bp
[5 * 2 - 5];
496 rp
[3] = (unsigned int)acc
;
500 acc
+= bp
[4 * 2 - 6];
501 acc
+= bp
[5 * 2 - 6];
502 rp
[4] = (unsigned int)acc
;
506 acc
+= bp
[4 * 2 - 5];
507 acc
+= bp
[5 * 2 - 5];
508 rp
[5] = (unsigned int)acc
;
510 carry
= (int)(acc
>> 32);
514 BN_ULONG t_d
[BN_NIST_192_TOP
] = {0};
516 nist_set_192(t_d
, buf
.bn
, 0, 3, 3);
517 carry
= (int)bn_add_words(r_d
, r_d
, t_d
, BN_NIST_192_TOP
);
518 nist_set_192(t_d
, buf
.bn
, 4, 4, 0);
519 carry
+= (int)bn_add_words(r_d
, r_d
, t_d
, BN_NIST_192_TOP
);
520 nist_set_192(t_d
, buf
.bn
, 5, 5, 5)
521 carry
+= (int)bn_add_words(r_d
, r_d
, t_d
, BN_NIST_192_TOP
);
525 carry
= (int)bn_sub_words(r_d
, r_d
, _nist_p_192
[carry
- 1],
531 * we need 'if (carry==0 || result>=modulus) result-=modulus;'
532 * as comparison implies subtraction, we can write
533 * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;'
534 * this is what happens below, but without explicit if:-) a.
536 mask
= 0 - (uintptr_t)bn_sub_words(c_d
, r_d
, _nist_p_192
[0],
538 mask
&= 0 - (uintptr_t)carry
;
540 res
= (BN_ULONG
*)(((uintptr_t)res
& ~mask
) | ((uintptr_t)r_d
& mask
));
541 nist_cp_bn(r_d
, res
, BN_NIST_192_TOP
);
542 r
->top
= BN_NIST_192_TOP
;
548 typedef BN_ULONG (*bn_addsub_f
)(BN_ULONG
*, const BN_ULONG
*,
549 const BN_ULONG
*, int);
551 #define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
553 bn_cp_32(to, 0, from, (a7) - 7) \
554 bn_cp_32(to, 1, from, (a6) - 7) \
555 bn_cp_32(to, 2, from, (a5) - 7) \
556 bn_cp_32(to, 3, from, (a4) - 7) \
557 bn_cp_32(to, 4, from, (a3) - 7) \
558 bn_cp_32(to, 5, from, (a2) - 7) \
559 bn_cp_32(to, 6, from, (a1) - 7) \
563 BN_nist_mod_224(BIGNUM
*r
, const BIGNUM
*a
, const BIGNUM
*field
, BN_CTX
*ctx
)
567 BN_ULONG
*r_d
, *a_d
= a
->d
;
569 BN_ULONG bn
[BN_NIST_224_TOP
];
570 unsigned int ui
[BN_NIST_224_TOP
*
571 sizeof(BN_ULONG
) / sizeof(unsigned int)];
573 BN_ULONG c_d
[BN_NIST_224_TOP
], *res
;
579 static const BIGNUM _bignum_nist_p_224_sqr
= {
580 (BN_ULONG
*)_nist_p_224_sqr
,
581 sizeof(_nist_p_224_sqr
) / sizeof(_nist_p_224_sqr
[0]),
582 sizeof(_nist_p_224_sqr
) / sizeof(_nist_p_224_sqr
[0]),
587 field
= &_bignum_nist_p_224
; /* just to make sure */
589 if (BN_is_negative(a
) || BN_ucmp(a
, &_bignum_nist_p_224_sqr
) >= 0)
590 return BN_nnmod(r
, a
, field
, ctx
);
592 i
= BN_ucmp(field
, a
);
597 return (r
== a
) ? 1 : (BN_copy(r
, a
) != NULL
);
600 if (!bn_wexpand(r
, BN_NIST_224_TOP
))
603 nist_cp_bn(r_d
, a_d
, BN_NIST_224_TOP
);
607 memset(&buf
, 0, sizeof(buf
));
610 /* copy upper 256 bits of 448 bit number ... */
611 nist_cp_bn_0(c_d
, a_d
+ (BN_NIST_224_TOP
- 1),
612 top
- (BN_NIST_224_TOP
- 1), BN_NIST_224_TOP
);
613 /* ... and right shift by 32 to obtain upper 224 bits */
614 nist_set_224(buf
.bn
, c_d
, 14, 13, 12, 11, 10, 9, 8);
615 /* truncate lower part to 224 bits too */
616 r_d
[BN_NIST_224_TOP
- 1] &= BN_MASK2l
;
618 nist_cp_bn_0(buf
.bn
, a_d
+ BN_NIST_224_TOP
,
619 top
- BN_NIST_224_TOP
, BN_NIST_224_TOP
);
622 #if defined(NIST_INT64) && BN_BITS2!=64
624 NIST_INT64 acc
; /* accumulator */
625 unsigned int *rp
= (unsigned int *)r_d
;
626 const unsigned int *bp
= (const unsigned int *)buf
.ui
;
631 rp
[0] = (unsigned int)acc
;
637 rp
[1] = (unsigned int)acc
;
643 rp
[2] = (unsigned int)acc
;
650 rp
[3] = (unsigned int)acc
;
657 rp
[4] = (unsigned int)acc
;
664 rp
[5] = (unsigned int)acc
;
670 rp
[6] = (unsigned int)acc
;
672 carry
= (int)(acc
>> 32);
679 BN_ULONG t_d
[BN_NIST_224_TOP
] = {0};
681 nist_set_224(t_d
, buf
.bn
, 10, 9, 8, 7, 0, 0, 0);
682 carry
= (int)bn_add_words(r_d
, r_d
, t_d
, BN_NIST_224_TOP
);
683 nist_set_224(t_d
, buf
.bn
, 0, 13, 12, 11, 0, 0, 0);
684 carry
+= (int)bn_add_words(r_d
, r_d
, t_d
, BN_NIST_224_TOP
);
685 nist_set_224(t_d
, buf
.bn
, 13, 12, 11, 10, 9, 8, 7);
686 carry
-= (int)bn_sub_words(r_d
, r_d
, t_d
, BN_NIST_224_TOP
);
687 nist_set_224(t_d
, buf
.bn
, 0, 0, 0, 0, 13, 12, 11);
688 carry
-= (int)bn_sub_words(r_d
, r_d
, t_d
, BN_NIST_224_TOP
);
691 carry
= (int)(r_d
[BN_NIST_224_TOP
- 1] >> 32);
697 carry
= (int)bn_sub_words(r_d
, r_d
, _nist_p_224
[carry
- 1],
700 carry
= (int)(~(r_d
[BN_NIST_224_TOP
- 1] >> 32)) & 1;
702 } else if (carry
< 0) {
703 /* it's a bit more complicated logic in this case.
704 * if bn_add_words yields no carry, then result
705 * has to be adjusted by unconditionally *adding*
706 * the modulus. but if it does, then result has
707 * to be compared to the modulus and conditionally
708 * adjusted by *subtracting* the latter. */
709 carry
= (int)bn_add_words(r_d
, r_d
, _nist_p_224
[-carry
- 1],
711 mask
= 0 - (uintptr_t)carry
;
712 u
.p
= ((uintptr_t)bn_sub_words
& mask
) |
713 ((uintptr_t)bn_add_words
& ~mask
);
717 /* otherwise it's effectively same as in BN_nist_mod_192... */
718 mask
= 0 - (uintptr_t)(*u
.f
)(c_d
, r_d
, _nist_p_224
[0], BN_NIST_224_TOP
);
719 mask
&= 0 - (uintptr_t)carry
;
721 res
= (BN_ULONG
*)(((uintptr_t)res
& ~mask
) | ((uintptr_t)r_d
& mask
));
722 nist_cp_bn(r_d
, res
, BN_NIST_224_TOP
);
723 r
->top
= BN_NIST_224_TOP
;
729 #define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
731 bn_cp_32(to, 0, from, (a8) - 8) \
732 bn_cp_32(to, 1, from, (a7) - 8) \
733 bn_cp_32(to, 2, from, (a6) - 8) \
734 bn_cp_32(to, 3, from, (a5) - 8) \
735 bn_cp_32(to, 4, from, (a4) - 8) \
736 bn_cp_32(to, 5, from, (a3) - 8) \
737 bn_cp_32(to, 6, from, (a2) - 8) \
738 bn_cp_32(to, 7, from, (a1) - 8) \
742 BN_nist_mod_256(BIGNUM
*r
, const BIGNUM
*a
, const BIGNUM
*field
, BN_CTX
*ctx
)
746 BN_ULONG
*a_d
= a
->d
, *r_d
;
748 BN_ULONG bn
[BN_NIST_256_TOP
];
749 unsigned int ui
[BN_NIST_256_TOP
*
750 sizeof(BN_ULONG
) / sizeof(unsigned int)];
752 BN_ULONG c_d
[BN_NIST_256_TOP
] = {0}, *res
;
758 static const BIGNUM _bignum_nist_p_256_sqr
= {
759 (BN_ULONG
*)_nist_p_256_sqr
,
760 sizeof(_nist_p_256_sqr
) / sizeof(_nist_p_256_sqr
[0]),
761 sizeof(_nist_p_256_sqr
) / sizeof(_nist_p_256_sqr
[0]),
766 field
= &_bignum_nist_p_256
; /* just to make sure */
768 if (BN_is_negative(a
) || BN_ucmp(a
, &_bignum_nist_p_256_sqr
) >= 0)
769 return BN_nnmod(r
, a
, field
, ctx
);
771 i
= BN_ucmp(field
, a
);
776 return (r
== a
) ? 1 : (BN_copy(r
, a
) != NULL
);
779 if (!bn_wexpand(r
, BN_NIST_256_TOP
))
782 nist_cp_bn(r_d
, a_d
, BN_NIST_256_TOP
);
786 nist_cp_bn_0(buf
.bn
, a_d
+ BN_NIST_256_TOP
,
787 top
- BN_NIST_256_TOP
, BN_NIST_256_TOP
);
789 #if defined(NIST_INT64)
791 NIST_INT64 acc
; /* accumulator */
792 unsigned int *rp
= (unsigned int *)r_d
;
793 const unsigned int *bp
= (const unsigned int *)buf
.ui
;
802 rp
[0] = (unsigned int)acc
;
812 rp
[1] = (unsigned int)acc
;
821 rp
[2] = (unsigned int)acc
;
833 rp
[3] = (unsigned int)acc
;
844 rp
[4] = (unsigned int)acc
;
855 rp
[5] = (unsigned int)acc
;
867 rp
[6] = (unsigned int)acc
;
879 rp
[7] = (unsigned int)acc
;
881 carry
= (int)(acc
>> 32);
885 BN_ULONG t_d
[BN_NIST_256_TOP
] = {0};
888 nist_set_256(t_d
, buf
.bn
, 15, 14, 13, 12, 11, 0, 0, 0);
890 nist_set_256(c_d
, buf
.bn
, 0, 15, 14, 13, 12, 0, 0, 0);
891 carry
= (int)bn_add_words(t_d
, t_d
, c_d
, BN_NIST_256_TOP
);
897 for (i
= BN_NIST_256_TOP
; i
!= 0; --i
) {
899 *(ap
++) = ((t
<< 1) | c
) & BN_MASK2
;
900 c
= (t
& BN_TBIT
) ? 1 : 0;
905 carry
+= (int)bn_add_words(r_d
, r_d
, t_d
, BN_NIST_256_TOP
);
907 nist_set_256(t_d
, buf
.bn
, 15, 14, 0, 0, 0, 10, 9, 8);
908 carry
+= (int)bn_add_words(r_d
, r_d
, t_d
, BN_NIST_256_TOP
);
910 nist_set_256(t_d
, buf
.bn
, 8, 13, 15, 14, 13, 11, 10, 9);
911 carry
+= (int)bn_add_words(r_d
, r_d
, t_d
, BN_NIST_256_TOP
);
913 nist_set_256(t_d
, buf
.bn
, 10, 8, 0, 0, 0, 13, 12, 11);
914 carry
-= (int)bn_sub_words(r_d
, r_d
, t_d
, BN_NIST_256_TOP
);
916 nist_set_256(t_d
, buf
.bn
, 11, 9, 0, 0, 15, 14, 13, 12);
917 carry
-= (int)bn_sub_words(r_d
, r_d
, t_d
, BN_NIST_256_TOP
);
919 nist_set_256(t_d
, buf
.bn
, 12, 0, 10, 9, 8, 15, 14, 13);
920 carry
-= (int)bn_sub_words(r_d
, r_d
, t_d
, BN_NIST_256_TOP
);
922 nist_set_256(t_d
, buf
.bn
, 13, 0, 11, 10, 9, 0, 15, 14);
923 carry
-= (int)bn_sub_words(r_d
, r_d
, t_d
, BN_NIST_256_TOP
);
927 /* see BN_nist_mod_224 for explanation */
930 carry
= (int)bn_sub_words(r_d
, r_d
, _nist_p_256
[carry
- 1],
932 else if (carry
< 0) {
933 carry
= (int)bn_add_words(r_d
, r_d
, _nist_p_256
[-carry
- 1],
935 mask
= 0 - (uintptr_t)carry
;
936 u
.p
= ((uintptr_t)bn_sub_words
& mask
) |
937 ((uintptr_t)bn_add_words
& ~mask
);
941 mask
= 0 - (uintptr_t)(*u
.f
)(c_d
, r_d
, _nist_p_256
[0], BN_NIST_256_TOP
);
942 mask
&= 0 - (uintptr_t)carry
;
944 res
= (BN_ULONG
*)(((uintptr_t)res
& ~mask
) | ((uintptr_t)r_d
& mask
));
945 nist_cp_bn(r_d
, res
, BN_NIST_256_TOP
);
946 r
->top
= BN_NIST_256_TOP
;
952 #define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
954 bn_cp_32(to, 0, from, (a12) - 12) \
955 bn_cp_32(to, 1, from, (a11) - 12) \
956 bn_cp_32(to, 2, from, (a10) - 12) \
957 bn_cp_32(to, 3, from, (a9) - 12) \
958 bn_cp_32(to, 4, from, (a8) - 12) \
959 bn_cp_32(to, 5, from, (a7) - 12) \
960 bn_cp_32(to, 6, from, (a6) - 12) \
961 bn_cp_32(to, 7, from, (a5) - 12) \
962 bn_cp_32(to, 8, from, (a4) - 12) \
963 bn_cp_32(to, 9, from, (a3) - 12) \
964 bn_cp_32(to, 10, from, (a2) - 12) \
965 bn_cp_32(to, 11, from, (a1) - 12) \
969 BN_nist_mod_384(BIGNUM
*r
, const BIGNUM
*a
, const BIGNUM
*field
, BN_CTX
*ctx
)
973 BN_ULONG
*r_d
, *a_d
= a
->d
;
975 BN_ULONG bn
[BN_NIST_384_TOP
];
976 unsigned int ui
[BN_NIST_384_TOP
*
977 sizeof(BN_ULONG
) / sizeof(unsigned int)];
979 BN_ULONG c_d
[BN_NIST_384_TOP
], *res
;
985 static const BIGNUM _bignum_nist_p_384_sqr
= {
986 (BN_ULONG
*)_nist_p_384_sqr
,
987 sizeof(_nist_p_384_sqr
) / sizeof(_nist_p_384_sqr
[0]),
988 sizeof(_nist_p_384_sqr
) / sizeof(_nist_p_384_sqr
[0]),
993 field
= &_bignum_nist_p_384
; /* just to make sure */
995 if (BN_is_negative(a
) || BN_ucmp(a
, &_bignum_nist_p_384_sqr
) >= 0)
996 return BN_nnmod(r
, a
, field
, ctx
);
998 i
= BN_ucmp(field
, a
);
1003 return (r
== a
) ? 1 : (BN_copy(r
, a
) != NULL
);
1006 if (!bn_wexpand(r
, BN_NIST_384_TOP
))
1009 nist_cp_bn(r_d
, a_d
, BN_NIST_384_TOP
);
1013 nist_cp_bn_0(buf
.bn
, a_d
+ BN_NIST_384_TOP
,
1014 top
- BN_NIST_384_TOP
, BN_NIST_384_TOP
);
1016 #if defined(NIST_INT64)
1018 NIST_INT64 acc
; /* accumulator */
1019 unsigned int *rp
= (unsigned int *)r_d
;
1020 const unsigned int *bp
= (const unsigned int *)buf
.ui
;
1027 rp
[0] = (unsigned int)acc
;
1036 rp
[1] = (unsigned int)acc
;
1044 rp
[2] = (unsigned int)acc
;
1055 rp
[3] = (unsigned int)acc
;
1069 rp
[4] = (unsigned int)acc
;
1081 rp
[5] = (unsigned int)acc
;
1092 rp
[6] = (unsigned int)acc
;
1101 rp
[7] = (unsigned int)acc
;
1109 rp
[8] = (unsigned int)acc
;
1117 rp
[9] = (unsigned int)acc
;
1125 rp
[10] = (unsigned int)acc
;
1133 rp
[11] = (unsigned int)acc
;
1135 carry
= (int)(acc
>> 32);
1139 BN_ULONG t_d
[BN_NIST_384_TOP
] = {0};
1142 nist_set_256(t_d
, buf
.bn
, 0, 0, 0, 0, 0, 23 - 4, 22 - 4,
1149 for (i
= 3; i
!= 0; --i
) {
1151 *(ap
++) = ((t
<< 1)|c
) & BN_MASK2
;
1152 c
= (t
& BN_TBIT
) ? 1 : 0;
1156 carry
= (int)bn_add_words(r_d
+ (128 / BN_BITS2
),
1157 r_d
+ (128 / BN_BITS2
), t_d
, BN_NIST_256_TOP
);
1159 carry
+= (int)bn_add_words(r_d
, r_d
, buf
.bn
, BN_NIST_384_TOP
);
1161 nist_set_384(t_d
, buf
.bn
, 20, 19, 18, 17, 16, 15, 14, 13, 12,
1163 carry
+= (int)bn_add_words(r_d
, r_d
, t_d
, BN_NIST_384_TOP
);
1165 nist_set_384(t_d
, buf
.bn
, 19, 18, 17, 16, 15, 14, 13, 12, 20,
1167 carry
+= (int)bn_add_words(r_d
, r_d
, t_d
, BN_NIST_384_TOP
);
1169 nist_set_384(t_d
, buf
.bn
, 0,0, 0,0, 23, 22, 21, 20, 0,0, 0, 0);
1170 carry
+= (int)bn_add_words(r_d
, r_d
, t_d
, BN_NIST_384_TOP
);
1172 nist_set_384(t_d
, buf
.bn
, 0,0, 0,0, 0,0, 23, 22, 21, 0,0, 20);
1173 carry
+= (int)bn_add_words(r_d
, r_d
, t_d
, BN_NIST_384_TOP
);
1175 nist_set_384(t_d
, buf
.bn
, 22, 21, 20, 19, 18, 17, 16, 15, 14,
1177 carry
-= (int)bn_sub_words(r_d
, r_d
, t_d
, BN_NIST_384_TOP
);
1179 nist_set_384(t_d
, buf
.bn
, 0,0, 0,0, 0,0, 0,23, 22, 21, 20, 0);
1180 carry
-= (int)bn_sub_words(r_d
, r_d
, t_d
, BN_NIST_384_TOP
);
1182 nist_set_384(t_d
, buf
.bn
, 0,0, 0,0, 0,0, 0,23, 23, 0,0, 0);
1183 carry
-= (int)bn_sub_words(r_d
, r_d
, t_d
, BN_NIST_384_TOP
);
1187 /* see BN_nist_mod_224 for explanation */
1190 carry
= (int)bn_sub_words(r_d
, r_d
, _nist_p_384
[carry
- 1],
1192 else if (carry
< 0) {
1193 carry
= (int)bn_add_words(r_d
, r_d
, _nist_p_384
[-carry
- 1],
1195 mask
= 0 - (uintptr_t)carry
;
1196 u
.p
= ((uintptr_t)bn_sub_words
& mask
) |
1197 ((uintptr_t)bn_add_words
& ~mask
);
1201 mask
= 0 - (uintptr_t)(*u
.f
)(c_d
, r_d
, _nist_p_384
[0], BN_NIST_384_TOP
);
1202 mask
&= 0 - (uintptr_t)carry
;
1204 res
= (BN_ULONG
*)(((uintptr_t)res
& ~mask
) | ((uintptr_t)r_d
& mask
));
1205 nist_cp_bn(r_d
, res
, BN_NIST_384_TOP
);
1206 r
->top
= BN_NIST_384_TOP
;
1212 #define BN_NIST_521_RSHIFT (521%BN_BITS2)
1213 #define BN_NIST_521_LSHIFT (BN_BITS2-BN_NIST_521_RSHIFT)
1214 #define BN_NIST_521_TOP_MASK ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
1217 BN_nist_mod_521(BIGNUM
*r
, const BIGNUM
*a
, const BIGNUM
*field
, BN_CTX
*ctx
)
1219 int top
= a
->top
, i
;
1220 BN_ULONG
*r_d
, *a_d
= a
->d
, t_d
[BN_NIST_521_TOP
], val
, tmp
, *res
;
1222 static const BIGNUM _bignum_nist_p_521_sqr
= {
1223 (BN_ULONG
*)_nist_p_521_sqr
,
1224 sizeof(_nist_p_521_sqr
) / sizeof(_nist_p_521_sqr
[0]),
1225 sizeof(_nist_p_521_sqr
) / sizeof(_nist_p_521_sqr
[0]),
1230 field
= &_bignum_nist_p_521
; /* just to make sure */
1232 if (BN_is_negative(a
) || BN_ucmp(a
, &_bignum_nist_p_521_sqr
) >= 0)
1233 return BN_nnmod(r
, a
, field
, ctx
);
1235 i
= BN_ucmp(field
, a
);
1240 return (r
== a
) ? 1 : (BN_copy(r
, a
) != NULL
);
1243 if (!bn_wexpand(r
, BN_NIST_521_TOP
))
1246 nist_cp_bn(r_d
, a_d
, BN_NIST_521_TOP
);
1250 /* upper 521 bits, copy ... */
1251 nist_cp_bn_0(t_d
, a_d
+ (BN_NIST_521_TOP
- 1),
1252 top
- (BN_NIST_521_TOP
- 1), BN_NIST_521_TOP
);
1253 /* ... and right shift */
1254 for (val
= t_d
[0], i
= 0; i
< BN_NIST_521_TOP
- 1; i
++) {
1255 tmp
= val
>> BN_NIST_521_RSHIFT
;
1257 t_d
[i
] = (tmp
| val
<< BN_NIST_521_LSHIFT
) & BN_MASK2
;
1259 t_d
[i
] = val
>> BN_NIST_521_RSHIFT
;
1260 /* lower 521 bits */
1261 r_d
[i
] &= BN_NIST_521_TOP_MASK
;
1263 bn_add_words(r_d
, r_d
, t_d
, BN_NIST_521_TOP
);
1264 mask
= 0 - (uintptr_t)bn_sub_words(t_d
, r_d
, _nist_p_521
,
1267 res
= (BN_ULONG
*)(((uintptr_t)res
& ~mask
) | ((uintptr_t)r_d
& mask
));
1268 nist_cp_bn(r_d
, res
, BN_NIST_521_TOP
);
1269 r
->top
= BN_NIST_521_TOP
;