1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/bn/bn_nist.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Written by Nils Larsch for the OpenSSL project
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    openssl-core@openssl.org.
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "bn_lcl.h"
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
62e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define BN_NIST_192_TOP	(192+BN_BITS2-1)/BN_BITS2
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define BN_NIST_224_TOP	(224+BN_BITS2-1)/BN_BITS2
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define BN_NIST_256_TOP	(256+BN_BITS2-1)/BN_BITS2
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define BN_NIST_384_TOP	(384+BN_BITS2-1)/BN_BITS2
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define BN_NIST_521_TOP	(521+BN_BITS2-1)/BN_BITS2
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
69e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* pre-computed tables are "carry-less" values of modulus*(i+1) */
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if BN_BITS2 == 64
71e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
72e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFFULL},
73e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFFULL},
74e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFCULL,0xFFFFFFFFFFFFFFFFULL}
75e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
76e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_192_sqr[] = {
77e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x0000000000000001ULL,0x0000000000000002ULL,0x0000000000000001ULL,
78e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFFULL
79e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
80e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{0x0000000000000001ULL,0xFFFFFFFF00000000ULL,
82e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL},
83e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0x0000000000000002ULL,0xFFFFFFFE00000000ULL,
84e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFFFFFFFFFFULL,0x00000001FFFFFFFFULL} /* this one is "carry-full" */
85e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
86e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_224_sqr[] = {
87e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x0000000000000001ULL,0xFFFFFFFE00000000ULL,
88e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFFFFFFFFFFULL,0x0000000200000000ULL,
89e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x0000000000000000ULL,0xFFFFFFFFFFFFFFFEULL,
90e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFFFFFFFFFFULL
91e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
92e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL,
94e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0x0000000000000000ULL,0xFFFFFFFF00000001ULL},
95e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFFFFFFFFFEULL,0x00000001FFFFFFFFULL,
96e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0x0000000000000000ULL,0xFFFFFFFE00000002ULL},
97e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFFFFFFFFFDULL,0x00000002FFFFFFFFULL,
98e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0x0000000000000000ULL,0xFFFFFFFD00000003ULL},
99e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFFFFFFFFFCULL,0x00000003FFFFFFFFULL,
100e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0x0000000000000000ULL,0xFFFFFFFC00000004ULL},
101e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFFFFFFFFFBULL,0x00000004FFFFFFFFULL,
102e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0x0000000000000000ULL,0xFFFFFFFB00000005ULL},
103e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
104e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_256_sqr[] = {
105e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x0000000000000001ULL,0xFFFFFFFE00000000ULL,
106e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFFFFFFFFFFULL,0x00000001FFFFFFFEULL,
107e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x00000001FFFFFFFEULL,0x00000001FFFFFFFEULL,
108e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFE00000001ULL,0xFFFFFFFE00000002ULL
109e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
110e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
111e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0x00000000FFFFFFFFULL,0xFFFFFFFF00000000ULL,0xFFFFFFFFFFFFFFFEULL,
112e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
113e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0x00000001FFFFFFFEULL,0xFFFFFFFE00000000ULL,0xFFFFFFFFFFFFFFFDULL,
114e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
115e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0x00000002FFFFFFFDULL,0xFFFFFFFD00000000ULL,0xFFFFFFFFFFFFFFFCULL,
116e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
117e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0x00000003FFFFFFFCULL,0xFFFFFFFC00000000ULL,0xFFFFFFFFFFFFFFFBULL,
118e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
119e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0x00000004FFFFFFFBULL,0xFFFFFFFB00000000ULL,0xFFFFFFFFFFFFFFFAULL,
120e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
121e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
122e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_384_sqr[] = {
123e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFE00000001ULL,0x0000000200000000ULL,0xFFFFFFFE00000000ULL,
124e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x0000000200000000ULL,0x0000000000000001ULL,0x0000000000000000ULL,
125e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x00000001FFFFFFFEULL,0xFFFFFFFE00000000ULL,0xFFFFFFFFFFFFFFFDULL,
126e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL
127e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic const BN_ULONG _nist_p_521[] =
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	0x00000000000001FFULL};
134e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_521_sqr[] = {
135e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x0000000000000001ULL,0x0000000000000000ULL,0x0000000000000000ULL,
136e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x0000000000000000ULL,0x0000000000000000ULL,0x0000000000000000ULL,
137e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x0000000000000000ULL,0x0000000000000000ULL,0xFFFFFFFFFFFFFC00ULL,
138e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
139e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
140e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFFFFFFFFFFULL,0x000000000003FFFFULL
141e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#elif BN_BITS2 == 32
143e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
144e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
145e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
146e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}
147e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
148e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_192_sqr[] = {
149e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x00000001,0x00000000,0x00000002,0x00000000,0x00000001,0x00000000,
150e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF
151e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
152e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
153e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0x00000001,0x00000000,0x00000000,0xFFFFFFFF,
154e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
155e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0x00000002,0x00000000,0x00000000,0xFFFFFFFE,
156e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}
157e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
158e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_224_sqr[] = {
159e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x00000001,0x00000000,0x00000000,0xFFFFFFFE,
160e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000002,
161e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x00000000,0x00000000,0xFFFFFFFE,0xFFFFFFFF,
162e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFF,0xFFFFFFFF
163e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
164e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
165e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,
166e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0x00000000,0x00000000,0x00000001,0xFFFFFFFF},
167e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0x00000001,
168e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0x00000000,0x00000000,0x00000002,0xFFFFFFFE},
169e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0x00000002,
170e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0x00000000,0x00000000,0x00000003,0xFFFFFFFD},
171e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0x00000003,
172e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0x00000000,0x00000000,0x00000004,0xFFFFFFFC},
173e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFB,0xFFFFFFFF,0xFFFFFFFF,0x00000004,
174e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0x00000000,0x00000000,0x00000005,0xFFFFFFFB},
175e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
176e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_256_sqr[] = {
177e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x00000001,0x00000000,0x00000000,0xFFFFFFFE,
178e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0x00000001,
179e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFE,0x00000001,0xFFFFFFFE,0x00000001,
180e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x00000001,0xFFFFFFFE,0x00000002,0xFFFFFFFE
181e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
182e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
183e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,
184e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
185e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFE,0x00000001,0x00000000,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFF,
186e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
187e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFD,0x00000002,0x00000000,0xFFFFFFFD,0xFFFFFFFC,0xFFFFFFFF,
188e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
189e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFC,0x00000003,0x00000000,0xFFFFFFFC,0xFFFFFFFB,0xFFFFFFFF,
190e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
191e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{0xFFFFFFFB,0x00000004,0x00000000,0xFFFFFFFB,0xFFFFFFFA,0xFFFFFFFF,
192e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
193e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
194e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_384_sqr[] = {
195e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x00000001,0xFFFFFFFE,0x00000000,0x00000002,0x00000000,0xFFFFFFFE,
196e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x00000000,0x00000002,0x00000001,0x00000000,0x00000000,0x00000000,
197e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFE,0x00000001,0x00000000,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFF,
198e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF
199e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic const BN_ULONG _nist_p_521[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	0xFFFFFFFF,0x000001FF};
204e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BN_ULONG _nist_p_521_sqr[] = {
205e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
206e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
207e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFC00,0xFFFFFFFF,
208e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
209e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
210e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0xFFFFFFFF,0xFFFFFFFF,0x0003FFFF
211e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
212e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#else
213e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#error "unsupported BN_BITS2"
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
216e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
217e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BIGNUM _bignum_nist_p_192 =
218e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{
219e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	(BN_ULONG *)_nist_p_192[0],
220e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_NIST_192_TOP,
221e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_NIST_192_TOP,
222e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0,
223e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_FLG_STATIC_DATA
224e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
225e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
226e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BIGNUM _bignum_nist_p_224 =
227e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{
228e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	(BN_ULONG *)_nist_p_224[0],
229e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_NIST_224_TOP,
230e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_NIST_224_TOP,
231e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0,
232e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_FLG_STATIC_DATA
233e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
234e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
235e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BIGNUM _bignum_nist_p_256 =
236e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{
237e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	(BN_ULONG *)_nist_p_256[0],
238e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_NIST_256_TOP,
239e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_NIST_256_TOP,
240e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0,
241e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_FLG_STATIC_DATA
242e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
243e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
244e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BIGNUM _bignum_nist_p_384 =
245e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{
246e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	(BN_ULONG *)_nist_p_384[0],
247e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_NIST_384_TOP,
248e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_NIST_384_TOP,
249e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0,
250e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_FLG_STATIC_DATA
251e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
252e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
253e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugustatic const BIGNUM _bignum_nist_p_521 =
254e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{
255e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	(BN_ULONG *)_nist_p_521,
256e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_NIST_521_TOP,
257e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_NIST_521_TOP,
258e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	0,
259e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_FLG_STATIC_DATA
260e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	};
261e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
262e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst BIGNUM *BN_get0_nist_prime_192(void)
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
265e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	return &_bignum_nist_p_192;
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst BIGNUM *BN_get0_nist_prime_224(void)
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
270e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	return &_bignum_nist_p_224;
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst BIGNUM *BN_get0_nist_prime_256(void)
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
275e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	return &_bignum_nist_p_256;
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst BIGNUM *BN_get0_nist_prime_384(void)
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
280e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	return &_bignum_nist_p_384;
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst BIGNUM *BN_get0_nist_prime_521(void)
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
285e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	return &_bignum_nist_p_521;
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void nist_cp_bn_0(BN_ULONG *buf, BN_ULONG *a, int top, int max)
290e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
292e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
293e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
294e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#ifdef BN_DEBUG
295e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	OPENSSL_assert(top <= max);
296e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#endif
297e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	for (i = (top); i != 0; i--)
298e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		*_tmp1++ = *_tmp2++;
299e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	for (i = (max) - (top); i != 0; i--)
300e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		*_tmp1++ = (BN_ULONG) 0;
301e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	}
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top)
304e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	{
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
306e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
307e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	for (i = (top); i != 0; i--)
308e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		*_tmp1++ = *_tmp2++;
309e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	}
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if BN_BITS2 == 64
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define bn_cp_64(to, n, from, m)	(to)[n] = (m>=0)?((from)[m]):0;
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define bn_64_set_0(to, n)		(to)[n] = (BN_ULONG)0;
314e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/*
315e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * two following macros are implemented under assumption that they
316e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu * are called in a sequence with *ascending* n, i.e. as they are...
317e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu */
318e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#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))\
319e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu						:(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
320e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#define bn_32_set_0(to, n)		(((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
321e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#define bn_cp_32(to,n,from,m)		((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define bn_cp_64(to, n, from, m) \
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ \
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bn_cp_32(to, (n)*2, from, (m)*2); \
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bn_cp_32(to, (n)*2+1, from, (m)*2+1); \
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define bn_64_set_0(to, n) \
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ \
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bn_32_set_0(to, (n)*2); \
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bn_32_set_0(to, (n)*2+1); \
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if BN_BITS2 == 32
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define bn_cp_32(to, n, from, m)	(to)[n] = (m>=0)?((from)[m]):0;
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define bn_32_set_0(to, n)		(to)[n] = (BN_ULONG)0;
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif /* BN_BITS2 != 64 */
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define nist_set_192(to, from, a1, a2, a3) \
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ \
342e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_64(to, 0, from, (a3) - 3) \
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bn_cp_64(to, 1, from, (a2) - 3) \
344e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_64(to, 2, from, (a1) - 3) \
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_CTX *ctx)
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int      top = a->top, i;
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int      carry;
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	register BN_ULONG *r_d, *a_d = a->d;
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_ULONG t_d[BN_NIST_192_TOP],
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	         buf[BN_NIST_192_TOP],
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 c_d[BN_NIST_192_TOP],
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*res;
357ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	PTR_SIZE_INT mask;
358e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	static const BIGNUM _bignum_nist_p_192_sqr = {
359e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		(BN_ULONG *)_nist_p_192_sqr,
360e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		sizeof(_nist_p_192_sqr)/sizeof(_nist_p_192_sqr[0]),
361e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		sizeof(_nist_p_192_sqr)/sizeof(_nist_p_192_sqr[0]),
362e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		0,BN_FLG_STATIC_DATA };
363e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
364e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	field = &_bignum_nist_p_192; /* just to make sure */
365e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
366e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_192_sqr)>=0)
367e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		return BN_nnmod(r, a, field, ctx);
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	i = BN_ucmp(field, a);
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (i == 0)
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_zero(r);
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (i > 0)
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (r == a) ? 1 : (BN_copy(r ,a) != NULL);
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (r != a)
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!bn_wexpand(r, BN_NIST_192_TOP))
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		r_d = r->d;
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		nist_cp_bn(r_d, a_d, BN_NIST_192_TOP);
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		r_d = a_d;
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_cp_bn_0(buf, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, BN_NIST_192_TOP);
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_192(t_d, buf, 0, 3, 3);
391e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_192(t_d, buf, 4, 4, 0);
393e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_192(t_d, buf, 5, 5, 5)
395e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
397e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	if (carry > 0)
398e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry = (int)bn_sub_words(r_d,r_d,_nist_p_192[carry-1],BN_NIST_192_TOP);
399e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	else
400e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry = 1;
401e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
402e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	/*
403e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 * we need 'if (carry==0 || result>=modulus) result-=modulus;'
404e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 * as comparison implies subtraction, we can write
405e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;'
406e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 * this is what happens below, but without explicit if:-) a.
407e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	 */
408ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	mask  = 0-(PTR_SIZE_INT)bn_sub_words(c_d,r_d,_nist_p_192[0],BN_NIST_192_TOP);
409ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	mask &= 0-(PTR_SIZE_INT)carry;
410ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	res   = (BN_ULONG *)
411ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	 (((PTR_SIZE_INT)c_d&~mask) | ((PTR_SIZE_INT)r_d&mask));
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_cp_bn(r_d, res, BN_NIST_192_TOP);
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	r->top = BN_NIST_192_TOP;
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bn_correct_top(r);
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
419e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugutypedef BN_ULONG (*bn_addsub_f)(BN_ULONG *,const BN_ULONG *,const BN_ULONG *,int);
420e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ \
423e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 0, from, (a7) - 7) \
424e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 1, from, (a6) - 7) \
425e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 2, from, (a5) - 7) \
426e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 3, from, (a4) - 7) \
427e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 4, from, (a3) - 7) \
428e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 5, from, (a2) - 7) \
429e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 6, from, (a1) - 7) \
430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_CTX *ctx)
434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	top = a->top, i;
436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	carry;
437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_ULONG *r_d, *a_d = a->d;
438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_ULONG t_d[BN_NIST_224_TOP],
439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	         buf[BN_NIST_224_TOP],
440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 c_d[BN_NIST_224_TOP],
441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*res;
442ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	PTR_SIZE_INT mask;
443ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	union { bn_addsub_f f; PTR_SIZE_INT p; } u;
444e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	static const BIGNUM _bignum_nist_p_224_sqr = {
445e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		(BN_ULONG *)_nist_p_224_sqr,
446e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		sizeof(_nist_p_224_sqr)/sizeof(_nist_p_224_sqr[0]),
447e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		sizeof(_nist_p_224_sqr)/sizeof(_nist_p_224_sqr[0]),
448e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		0,BN_FLG_STATIC_DATA };
449e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
450e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
451e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	field = &_bignum_nist_p_224; /* just to make sure */
452e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
453e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_224_sqr)>=0)
454e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		return BN_nnmod(r, a, field, ctx);
455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	i = BN_ucmp(field, a);
457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (i == 0)
458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_zero(r);
460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (i > 0)
463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (r != a)
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!bn_wexpand(r, BN_NIST_224_TOP))
468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		r_d = r->d;
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		nist_cp_bn(r_d, a_d, BN_NIST_224_TOP);
471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		r_d = a_d;
474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
475e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#if BN_BITS2==64
476e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	/* copy upper 256 bits of 448 bit number ... */
477e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	nist_cp_bn_0(t_d, a_d + (BN_NIST_224_TOP-1), top - (BN_NIST_224_TOP-1), BN_NIST_224_TOP);
478e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	/* ... and right shift by 32 to obtain upper 224 bits */
479e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	nist_set_224(buf, t_d, 14, 13, 12, 11, 10, 9, 8);
480e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	/* truncate lower part to 224 bits too */
481e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	r_d[BN_NIST_224_TOP-1] &= BN_MASK2l;
482e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#else
483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_cp_bn_0(buf, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, BN_NIST_224_TOP);
484e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#endif
485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_224(t_d, buf, 10, 9, 8, 7, 0, 0, 0);
486e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_224(t_d, buf, 0, 13, 12, 11, 0, 0, 0);
488e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_224(t_d, buf, 13, 12, 11, 10, 9, 8, 7);
490e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_224(t_d, buf, 0, 0, 0, 0, 13, 12, 11);
492e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
494e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#if BN_BITS2==64
495e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry = (int)(r_d[BN_NIST_224_TOP-1]>>32);
496e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#endif
497e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	u.f = bn_sub_words;
498e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	if (carry > 0)
499e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		{
500e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry = (int)bn_sub_words(r_d,r_d,_nist_p_224[carry-1],BN_NIST_224_TOP);
501e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#if BN_BITS2==64
502e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry=(int)(~(r_d[BN_NIST_224_TOP-1]>>32))&1;
503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
504e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		}
505e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	else if (carry < 0)
506e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		{
507e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		/* it's a bit more comlicated logic in this case.
508e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		 * if bn_add_words yields no carry, then result
509e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		 * has to be adjusted by unconditionally *adding*
510e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		 * the modulus. but if it does, then result has
511e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		 * to be compared to the modulus and conditionally
512e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		 * adjusted by *subtracting* the latter. */
513e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry = (int)bn_add_words(r_d,r_d,_nist_p_224[-carry-1],BN_NIST_224_TOP);
514ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom		mask = 0-(PTR_SIZE_INT)carry;
515ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom		u.p = ((PTR_SIZE_INT)bn_sub_words&mask) |
516ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom		 ((PTR_SIZE_INT)bn_add_words&~mask);
517e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		}
518e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	else
519e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry = 1;
520e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
521e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	/* otherwise it's effectively same as in BN_nist_mod_192... */
522ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	mask  = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_224[0],BN_NIST_224_TOP);
523ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	mask &= 0-(PTR_SIZE_INT)carry;
524ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	res   = (BN_ULONG *)(((PTR_SIZE_INT)c_d&~mask) |
525ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	 ((PTR_SIZE_INT)r_d&mask));
526e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	nist_cp_bn(r_d, res, BN_NIST_224_TOP);
527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	r->top = BN_NIST_224_TOP;
528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bn_correct_top(r);
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ \
535e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 0, from, (a8) - 8) \
536e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 1, from, (a7) - 8) \
537e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 2, from, (a6) - 8) \
538e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 3, from, (a5) - 8) \
539e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 4, from, (a4) - 8) \
540e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 5, from, (a3) - 8) \
541e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 6, from, (a2) - 8) \
542e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 7, from, (a1) - 8) \
543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_CTX *ctx)
547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	i, top = a->top;
549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	carry = 0;
550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	register BN_ULONG *a_d = a->d, *r_d;
551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_ULONG t_d[BN_NIST_256_TOP],
552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	         buf[BN_NIST_256_TOP],
553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 c_d[BN_NIST_256_TOP],
554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*res;
555ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	PTR_SIZE_INT mask;
556ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	union { bn_addsub_f f; PTR_SIZE_INT p; } u;
557e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	static const BIGNUM _bignum_nist_p_256_sqr = {
558e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		(BN_ULONG *)_nist_p_256_sqr,
559e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		sizeof(_nist_p_256_sqr)/sizeof(_nist_p_256_sqr[0]),
560e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		sizeof(_nist_p_256_sqr)/sizeof(_nist_p_256_sqr[0]),
561e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		0,BN_FLG_STATIC_DATA };
562e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
563e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	field = &_bignum_nist_p_256; /* just to make sure */
564e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
565e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_256_sqr)>=0)
566e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		return BN_nnmod(r, a, field, ctx);
567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	i = BN_ucmp(field, a);
569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (i == 0)
570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_zero(r);
572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (i > 0)
575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (r != a)
578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!bn_wexpand(r, BN_NIST_256_TOP))
580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		r_d = r->d;
582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		nist_cp_bn(r_d, a_d, BN_NIST_256_TOP);
583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		r_d = a_d;
586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_cp_bn_0(buf, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP, BN_NIST_256_TOP);
588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*S1*/
590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_256(t_d, buf, 15, 14, 13, 12, 11, 0, 0, 0);
591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*S2*/
592e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	nist_set_256(c_d, buf, 0, 15, 14, 13, 12, 0, 0, 0);
593e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
594e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	/* left shift */
595e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		{
596e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		register BN_ULONG *ap,t,c;
597e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		ap = t_d;
598e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		c=0;
599e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		for (i = BN_NIST_256_TOP; i != 0; --i)
600e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			{
601e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			t= *ap;
602e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			*(ap++)=((t<<1)|c)&BN_MASK2;
603e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			c=(t & BN_TBIT)?1:0;
604e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			}
605e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry <<= 1;
606e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry  |= c;
607e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		}
608e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*S3*/
610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_256(t_d, buf, 15, 14, 0, 0, 0, 10, 9, 8);
611e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*S4*/
613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_256(t_d, buf, 8, 13, 15, 14, 13, 11, 10, 9);
614e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*D1*/
616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_256(t_d, buf, 10, 8, 0, 0, 0, 13, 12, 11);
617e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*D2*/
619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_256(t_d, buf, 11, 9, 0, 0, 15, 14, 13, 12);
620e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*D3*/
622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_256(t_d, buf, 12, 0, 10, 9, 8, 15, 14, 13);
623e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*D4*/
625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_256(t_d, buf, 13, 0, 11, 10, 9, 0, 15, 14);
626e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
628e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	/* see BN_nist_mod_224 for explanation */
629e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	u.f = bn_sub_words;
630e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	if (carry > 0)
631e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry = (int)bn_sub_words(r_d,r_d,_nist_p_256[carry-1],BN_NIST_256_TOP);
632e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	else if (carry < 0)
633e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		{
634e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry = (int)bn_add_words(r_d,r_d,_nist_p_256[-carry-1],BN_NIST_256_TOP);
635ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom		mask = 0-(PTR_SIZE_INT)carry;
636ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom		u.p = ((PTR_SIZE_INT)bn_sub_words&mask) |
637ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom		 ((PTR_SIZE_INT)bn_add_words&~mask);
638e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		}
639e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	else
640e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry = 1;
641e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
642ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	mask  = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_256[0],BN_NIST_256_TOP);
643ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	mask &= 0-(PTR_SIZE_INT)carry;
644ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	res   = (BN_ULONG *)(((PTR_SIZE_INT)c_d&~mask) |
645ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	 ((PTR_SIZE_INT)r_d&mask));
646e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	nist_cp_bn(r_d, res, BN_NIST_256_TOP);
647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	r->top = BN_NIST_256_TOP;
648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bn_correct_top(r);
649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
650656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{ \
655e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 0, from,  (a12) - 12) \
656e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 1, from,  (a11) - 12) \
657e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 2, from,  (a10) - 12) \
658e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 3, from,  (a9) - 12)  \
659e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 4, from,  (a8) - 12)  \
660e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 5, from,  (a7) - 12)  \
661e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 6, from,  (a6) - 12)  \
662e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 7, from,  (a5) - 12)  \
663e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 8, from,  (a4) - 12)  \
664e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 9, from,  (a3) - 12)  \
665e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 10, from, (a2) - 12)  \
666e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_cp_32(to, 11, from, (a1) - 12)  \
667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_CTX *ctx)
671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	i, top = a->top;
673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int	carry = 0;
674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	register BN_ULONG *r_d, *a_d = a->d;
675656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_ULONG t_d[BN_NIST_384_TOP],
676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	         buf[BN_NIST_384_TOP],
677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 c_d[BN_NIST_384_TOP],
678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*res;
679ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	PTR_SIZE_INT mask;
680ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	union { bn_addsub_f f; PTR_SIZE_INT p; } u;
681e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	static const BIGNUM _bignum_nist_p_384_sqr = {
682e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		(BN_ULONG *)_nist_p_384_sqr,
683e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		sizeof(_nist_p_384_sqr)/sizeof(_nist_p_384_sqr[0]),
684e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		sizeof(_nist_p_384_sqr)/sizeof(_nist_p_384_sqr[0]),
685e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		0,BN_FLG_STATIC_DATA };
686e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
687e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
688e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	field = &_bignum_nist_p_384; /* just to make sure */
689e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
690e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_384_sqr)>=0)
691e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		return BN_nnmod(r, a, field, ctx);
692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	i = BN_ucmp(field, a);
694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (i == 0)
695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_zero(r);
697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (i > 0)
700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (r != a)
703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!bn_wexpand(r, BN_NIST_384_TOP))
705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		r_d = r->d;
707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		nist_cp_bn(r_d, a_d, BN_NIST_384_TOP);
708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		r_d = a_d;
711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_cp_bn_0(buf, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP, BN_NIST_384_TOP);
713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*S1*/
715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_256(t_d, buf, 0, 0, 0, 0, 0, 23-4, 22-4, 21-4);
716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* left shift */
717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		register BN_ULONG *ap,t,c;
719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ap = t_d;
720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		c=0;
721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for (i = 3; i != 0; --i)
722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			t= *ap;
724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			*(ap++)=((t<<1)|c)&BN_MASK2;
725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			c=(t & BN_TBIT)?1:0;
726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
727656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*ap=c;
728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
729e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry = (int)bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2),
730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		t_d, BN_NIST_256_TOP);
731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*S2 */
732e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry += (int)bn_add_words(r_d, r_d, buf, BN_NIST_384_TOP);
733656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*S3*/
734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_384(t_d,buf,20,19,18,17,16,15,14,13,12,23,22,21);
735e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*S4*/
737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_384(t_d,buf,19,18,17,16,15,14,13,12,20,0,23,0);
738e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
739656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*S5*/
740656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_384(t_d, buf,0,0,0,0,23,22,21,20,0,0,0,0);
741e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
742656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*S6*/
743656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_384(t_d,buf,0,0,0,0,0,0,23,22,21,0,0,20);
744e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
745656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*D1*/
746656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_384(t_d,buf,22,21,20,19,18,17,16,15,14,13,12,23);
747e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
748656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*D2*/
749656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,22,21,20,0);
750e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
751656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/*D3*/
752656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,23,0,0,0);
753e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
754e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
755e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	/* see BN_nist_mod_224 for explanation */
756e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	u.f = bn_sub_words;
757e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	if (carry > 0)
758e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry = (int)bn_sub_words(r_d,r_d,_nist_p_384[carry-1],BN_NIST_384_TOP);
759e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	else if (carry < 0)
760e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		{
761e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry = (int)bn_add_words(r_d,r_d,_nist_p_384[-carry-1],BN_NIST_384_TOP);
762ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom		mask = 0-(PTR_SIZE_INT)carry;
763ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom		u.p = ((PTR_SIZE_INT)bn_sub_words&mask) |
764ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom		 ((PTR_SIZE_INT)bn_add_words&~mask);
765e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		}
766e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	else
767e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		carry = 1;
768656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
769ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	mask  = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_384[0],BN_NIST_384_TOP);
770ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	mask &= 0-(PTR_SIZE_INT)carry;
771ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	res   = (BN_ULONG *)(((PTR_SIZE_INT)c_d&~mask) |
772ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	 ((PTR_SIZE_INT)r_d&mask));
773656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nist_cp_bn(r_d, res, BN_NIST_384_TOP);
774656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	r->top = BN_NIST_384_TOP;
775656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bn_correct_top(r);
776656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
777656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
778656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
779656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
780e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#define BN_NIST_521_RSHIFT	(521%BN_BITS2)
781e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#define BN_NIST_521_LSHIFT	(BN_BITS2-BN_NIST_521_RSHIFT)
782e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#define BN_NIST_521_TOP_MASK	((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
783e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
784656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
785656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_CTX *ctx)
786656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
787e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	int	top = a->top, i;
788e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	BN_ULONG *r_d, *a_d = a->d,
789e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		 t_d[BN_NIST_521_TOP],
790e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		 val,tmp,*res;
791ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	PTR_SIZE_INT mask;
792e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	static const BIGNUM _bignum_nist_p_521_sqr = {
793e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		(BN_ULONG *)_nist_p_521_sqr,
794e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		sizeof(_nist_p_521_sqr)/sizeof(_nist_p_521_sqr[0]),
795e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		sizeof(_nist_p_521_sqr)/sizeof(_nist_p_521_sqr[0]),
796e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		0,BN_FLG_STATIC_DATA };
797656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
798e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	field = &_bignum_nist_p_521; /* just to make sure */
799656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
800e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_521_sqr)>=0)
801e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		return BN_nnmod(r, a, field, ctx);
802656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
803e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	i = BN_ucmp(field, a);
804e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	if (i == 0)
805e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		{
806e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		BN_zero(r);
807e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		return 1;
808e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		}
809e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	else if (i > 0)
810e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
811656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
812e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	if (r != a)
813e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		{
814e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		if (!bn_wexpand(r,BN_NIST_521_TOP))
815e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu			return 0;
816e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		r_d = r->d;
817e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		nist_cp_bn(r_d,a_d, BN_NIST_521_TOP);
818e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		}
819e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	else
820e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		r_d = a_d;
821656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
822e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	/* upper 521 bits, copy ... */
823e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	nist_cp_bn_0(t_d,a_d + (BN_NIST_521_TOP-1), top - (BN_NIST_521_TOP-1),BN_NIST_521_TOP);
824e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	/* ... and right shift */
825e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	for (val=t_d[0],i=0; i<BN_NIST_521_TOP-1; i++)
826656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
827e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		tmp = val>>BN_NIST_521_RSHIFT;
828e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		val = t_d[i+1];
829e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu		t_d[i] = (tmp | val<<BN_NIST_521_LSHIFT) & BN_MASK2;
830656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
831e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	t_d[i] = val>>BN_NIST_521_RSHIFT;
832e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	/* lower 521 bits */
833e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	r_d[i] &= BN_NIST_521_TOP_MASK;
834e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu
835e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	bn_add_words(r_d,r_d,t_d,BN_NIST_521_TOP);
836ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	mask = 0-(PTR_SIZE_INT)bn_sub_words(t_d,r_d,_nist_p_521,BN_NIST_521_TOP);
837ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	res  = (BN_ULONG *)(((PTR_SIZE_INT)t_d&~mask) |
838ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom	 ((PTR_SIZE_INT)r_d&mask));
839e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	nist_cp_bn(r_d,res,BN_NIST_521_TOP);
840e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	r->top = BN_NIST_521_TOP;
841656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	bn_correct_top(r);
842656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
843e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu	return 1;
844656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
845