ecp_mont.c revision 656d9c7f52f88b3a3daccafa7655dec086c4756e
1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/ec/ecp_mont.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/*
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Originally written by Bodo Moeller for the OpenSSL project.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1998-2001 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 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Portions of this software developed by SUN MICROSYSTEMS, INC.,
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * and contributed to the OpenSSL project.
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h>
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "ec_lcl.h"
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst EC_METHOD *EC_GFp_mont_method(void)
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	static const EC_METHOD ret = {
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		NID_X9_62_prime_field,
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_mont_group_init,
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_mont_group_finish,
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_mont_group_clear_finish,
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_mont_group_copy,
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_mont_group_set_curve,
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_group_get_curve,
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_group_get_degree,
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_group_check_discriminant,
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_point_init,
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_point_finish,
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_point_clear_finish,
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_point_copy,
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_point_set_to_infinity,
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_set_Jprojective_coordinates_GFp,
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_get_Jprojective_coordinates_GFp,
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_point_set_affine_coordinates,
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_point_get_affine_coordinates,
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_set_compressed_coordinates,
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_point2oct,
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_oct2point,
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_add,
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_dbl,
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_invert,
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_is_at_infinity,
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_is_on_curve,
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_cmp,
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_make_affine,
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_simple_points_make_affine,
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		0 /* mul */,
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		0 /* precompute_mult */,
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		0 /* have_precompute_mult */,
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_mont_field_mul,
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_mont_field_sqr,
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		0 /* field_div */,
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_mont_field_encode,
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_mont_field_decode,
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ec_GFp_mont_field_set_to_one };
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return &ret;
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GFp_mont_group_init(EC_GROUP *group)
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ok;
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ok = ec_GFp_simple_group_init(group);
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	group->field_data1 = NULL;
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	group->field_data2 = NULL;
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ok;
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid ec_GFp_mont_group_finish(EC_GROUP *group)
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group->field_data1 != NULL)
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_MONT_CTX_free(group->field_data1);
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		group->field_data1 = NULL;
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group->field_data2 != NULL)
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(group->field_data2);
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		group->field_data2 = NULL;
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ec_GFp_simple_group_finish(group);
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid ec_GFp_mont_group_clear_finish(EC_GROUP *group)
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group->field_data1 != NULL)
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_MONT_CTX_free(group->field_data1);
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		group->field_data1 = NULL;
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group->field_data2 != NULL)
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_clear_free(group->field_data2);
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		group->field_data2 = NULL;
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ec_GFp_simple_group_clear_finish(group);
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (dest->field_data1 != NULL)
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_MONT_CTX_free(dest->field_data1);
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dest->field_data1 = NULL;
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (dest->field_data2 != NULL)
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_clear_free(dest->field_data2);
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dest->field_data2 = NULL;
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!ec_GFp_simple_group_copy(dest, src)) return 0;
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (src->field_data1 != NULL)
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dest->field_data1 = BN_MONT_CTX_new();
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (dest->field_data1 == NULL) return 0;
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) goto err;
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (src->field_data2 != NULL)
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dest->field_data2 = BN_dup(src->field_data2);
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (dest->field_data2 == NULL) goto err;
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err:
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (dest->field_data1 != NULL)
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_MONT_CTX_free(dest->field_data1);
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dest->field_data1 = NULL;
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 0;
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_CTX *new_ctx = NULL;
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BN_MONT_CTX *mont = NULL;
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIGNUM *one = NULL;
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret = 0;
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group->field_data1 != NULL)
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_MONT_CTX_free(group->field_data1);
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		group->field_data1 = NULL;
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group->field_data2 != NULL)
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(group->field_data2);
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		group->field_data2 = NULL;
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (ctx == NULL)
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ctx = new_ctx = BN_CTX_new();
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (ctx == NULL)
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	mont = BN_MONT_CTX_new();
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (mont == NULL) goto err;
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!BN_MONT_CTX_set(mont, p, ctx))
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	one = BN_new();
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (one == NULL) goto err;
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) goto err;
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	group->field_data1 = mont;
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	mont = NULL;
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	group->field_data2 = one;
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	one = NULL;
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!ret)
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_MONT_CTX_free(group->field_data1);
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		group->field_data1 = NULL;
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_free(group->field_data2);
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		group->field_data2 = NULL;
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project err:
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (new_ctx != NULL)
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_CTX_free(new_ctx);
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (mont != NULL)
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BN_MONT_CTX_free(mont);
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group->field_data1 == NULL)
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group->field_data1 == NULL)
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group->field_data1 == NULL)
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group->field_data1 == NULL)
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return BN_from_montgomery(r, a, group->field_data1, ctx);
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (group->field_data2 == NULL)
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 0;
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!BN_copy(r, group->field_data2)) return 0;
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
316