cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
ecp_mont.c
Go to the documentation of this file.
1 /* crypto/ec/ecp_mont.c */
2 /*
3  * Originally written by Bodo Moeller for the OpenSSL project.
4  */
5 /* ====================================================================
6  * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  * software must display the following acknowledgment:
22  * "This product includes software developed by the OpenSSL Project
23  * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  * endorse or promote products derived from this software without
27  * prior written permission. For written permission, please contact
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  * nor may "OpenSSL" appear in their names without prior written
32  * permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  * acknowledgment:
36  * "This product includes software developed by the OpenSSL Project
37  * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * ([email protected]). This product includes software written by Tim
55  * Hudson ([email protected]).
56  *
57  */
58 /* ====================================================================
59  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60  * Portions of this software developed by SUN MICROSYSTEMS, INC.,
61  * and contributed to the OpenSSL project.
62  */
63 
64 #if defined( INC_ALL )
65  #include "ec_lcl.h"
66 #else
67  #include "bn/ec_lcl.h"
68 #endif /* Compiler-specific includes */
69 
70 #if defined( USE_ECDH ) || defined( USE_ECDSA )
71 
72 #if 0 /* pcg */
73 
74 const EC_METHOD *EC_GFp_mont_method(void)
75  {
76  static const EC_METHOD ret = {
77  NID_X9_62_prime_field,
106  0 /* mul */,
107  0 /* precompute_mult */,
108  0 /* have_precompute_mult */,
111  0 /* field_div */,
115 
116  return &ret;
117  }
118 #endif /* 0 */
119 
121  {
122  int ok;
123 
124  ok = ec_GFp_simple_group_init(group);
125  group->field_data1 = NULL;
126  group->field_data2 = NULL;
127  return ok;
128  }
129 
130 
132  {
133  if (group->field_data1 != NULL)
134  {
136  group->field_data1 = NULL;
137  }
138  if (group->field_data2 != NULL)
139  {
140  BN_free(group->field_data2);
141  group->field_data2 = NULL;
142  }
144  }
145 
146 
148  {
149  if (group->field_data1 != NULL)
150  {
152  group->field_data1 = NULL;
153  }
154  if (group->field_data2 != NULL)
155  {
156  BN_clear_free(group->field_data2);
157  group->field_data2 = NULL;
158  }
160  }
161 
162 
164  {
165  if (dest->field_data1 != NULL)
166  {
168  dest->field_data1 = NULL;
169  }
170  if (dest->field_data2 != NULL)
171  {
172  BN_clear_free(dest->field_data2);
173  dest->field_data2 = NULL;
174  }
175 
176  if (!ec_GFp_simple_group_copy(dest, src)) return 0;
177 
178  if (src->field_data1 != NULL)
179  {
180  dest->field_data1 = BN_MONT_CTX_new();
181  if (dest->field_data1 == NULL) return 0;
182  if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) goto err;
183  }
184  if (src->field_data2 != NULL)
185  {
186  dest->field_data2 = BN_dup(src->field_data2);
187  if (dest->field_data2 == NULL) goto err;
188  }
189 
190  return 1;
191 
192  err:
193  if (dest->field_data1 != NULL)
194  {
196  dest->field_data1 = NULL;
197  }
198  return 0;
199  }
200 
201 
202 int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
203  {
204  BN_CTX *new_ctx = NULL;
205  BN_MONT_CTX *mont = NULL;
206  BIGNUM *one = NULL;
207  int ret = 0;
208 
209  if (group->field_data1 != NULL)
210  {
212  group->field_data1 = NULL;
213  }
214  if (group->field_data2 != NULL)
215  {
216  BN_free(group->field_data2);
217  group->field_data2 = NULL;
218  }
219 
220  if (ctx == NULL)
221  {
222  ctx = new_ctx = BN_CTX_new();
223  if (ctx == NULL)
224  return 0;
225  }
226 
227  mont = BN_MONT_CTX_new();
228  if (mont == NULL) goto err;
229  if (!BN_MONT_CTX_set(mont, p, ctx))
230  {
232  goto err;
233  }
234  one = BN_new();
235  if (one == NULL) goto err;
236  if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) goto err;
237 
238  group->field_data1 = mont;
239  mont = NULL;
240  group->field_data2 = one;
241  one = NULL;
242 
243  ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
244 
245  if (!ret)
246  {
248  group->field_data1 = NULL;
249  BN_free(group->field_data2);
250  group->field_data2 = NULL;
251  }
252 
253  err:
254  if (new_ctx != NULL)
255  BN_CTX_free(new_ctx);
256  if (mont != NULL)
257  BN_MONT_CTX_free(mont);
258  return ret;
259  }
260 
261 
262 int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
263  {
264  if (group->field_data1 == NULL)
265  {
267  return 0;
268  }
269 
270  return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
271  }
272 
273 
274 int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
275  {
276  if (group->field_data1 == NULL)
277  {
279  return 0;
280  }
281 
282  return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
283  }
284 
285 
286 int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
287  {
288  if (group->field_data1 == NULL)
289  {
291  return 0;
292  }
293 
294  return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
295  }
296 
297 
298 int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
299  {
300  if (group->field_data1 == NULL)
301  {
303  return 0;
304  }
305 
306  return BN_from_montgomery(r, a, group->field_data1, ctx);
307  }
308 
309 
310 int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
311  {
312  if (group->field_data2 == NULL)
313  {
315  return 0;
316  }
317 
318  if (!BN_copy(r, group->field_data2)) return 0;
319  return 1;
320  }
321 
322 #endif /* USE_ECDH || USE_ECDSA */