xref: /titanic_50/usr/src/common/crypto/ecc/ecl-priv.h (revision f9fbec18f5b458b560ecf45d3db8e8bd56bf6942)
1*f9fbec18Smcpowers /*
2*f9fbec18Smcpowers  * ***** BEGIN LICENSE BLOCK *****
3*f9fbec18Smcpowers  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4*f9fbec18Smcpowers  *
5*f9fbec18Smcpowers  * The contents of this file are subject to the Mozilla Public License Version
6*f9fbec18Smcpowers  * 1.1 (the "License"); you may not use this file except in compliance with
7*f9fbec18Smcpowers  * the License. You may obtain a copy of the License at
8*f9fbec18Smcpowers  * http://www.mozilla.org/MPL/
9*f9fbec18Smcpowers  *
10*f9fbec18Smcpowers  * Software distributed under the License is distributed on an "AS IS" basis,
11*f9fbec18Smcpowers  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12*f9fbec18Smcpowers  * for the specific language governing rights and limitations under the
13*f9fbec18Smcpowers  * License.
14*f9fbec18Smcpowers  *
15*f9fbec18Smcpowers  * The Original Code is the elliptic curve math library.
16*f9fbec18Smcpowers  *
17*f9fbec18Smcpowers  * The Initial Developer of the Original Code is
18*f9fbec18Smcpowers  * Sun Microsystems, Inc.
19*f9fbec18Smcpowers  * Portions created by the Initial Developer are Copyright (C) 2003
20*f9fbec18Smcpowers  * the Initial Developer. All Rights Reserved.
21*f9fbec18Smcpowers  *
22*f9fbec18Smcpowers  * Contributor(s):
23*f9fbec18Smcpowers  *   Stephen Fung <fungstep@hotmail.com> and
24*f9fbec18Smcpowers  *   Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
25*f9fbec18Smcpowers  *
26*f9fbec18Smcpowers  * Alternatively, the contents of this file may be used under the terms of
27*f9fbec18Smcpowers  * either the GNU General Public License Version 2 or later (the "GPL"), or
28*f9fbec18Smcpowers  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29*f9fbec18Smcpowers  * in which case the provisions of the GPL or the LGPL are applicable instead
30*f9fbec18Smcpowers  * of those above. If you wish to allow use of your version of this file only
31*f9fbec18Smcpowers  * under the terms of either the GPL or the LGPL, and not to allow others to
32*f9fbec18Smcpowers  * use your version of this file under the terms of the MPL, indicate your
33*f9fbec18Smcpowers  * decision by deleting the provisions above and replace them with the notice
34*f9fbec18Smcpowers  * and other provisions required by the GPL or the LGPL. If you do not delete
35*f9fbec18Smcpowers  * the provisions above, a recipient may use your version of this file under
36*f9fbec18Smcpowers  * the terms of any one of the MPL, the GPL or the LGPL.
37*f9fbec18Smcpowers  *
38*f9fbec18Smcpowers  * ***** END LICENSE BLOCK ***** */
39*f9fbec18Smcpowers /*
40*f9fbec18Smcpowers  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
41*f9fbec18Smcpowers  * Use is subject to license terms.
42*f9fbec18Smcpowers  *
43*f9fbec18Smcpowers  * Sun elects to use this software under the MPL license.
44*f9fbec18Smcpowers  */
45*f9fbec18Smcpowers 
46*f9fbec18Smcpowers #ifndef _ECL_PRIV_H
47*f9fbec18Smcpowers #define _ECL_PRIV_H
48*f9fbec18Smcpowers 
49*f9fbec18Smcpowers #pragma ident	"%Z%%M%	%I%	%E% SMI"
50*f9fbec18Smcpowers 
51*f9fbec18Smcpowers #include "ecl.h"
52*f9fbec18Smcpowers #include "mpi.h"
53*f9fbec18Smcpowers #include "mplogic.h"
54*f9fbec18Smcpowers 
55*f9fbec18Smcpowers /* MAX_FIELD_SIZE_DIGITS is the maximum size of field element supported */
56*f9fbec18Smcpowers /* the following needs to go away... */
57*f9fbec18Smcpowers #if defined(MP_USE_LONG_LONG_DIGIT) || defined(MP_USE_LONG_DIGIT)
58*f9fbec18Smcpowers #define ECL_SIXTY_FOUR_BIT
59*f9fbec18Smcpowers #else
60*f9fbec18Smcpowers #define ECL_THIRTY_TWO_BIT
61*f9fbec18Smcpowers #endif
62*f9fbec18Smcpowers 
63*f9fbec18Smcpowers #define ECL_CURVE_DIGITS(curve_size_in_bits) \
64*f9fbec18Smcpowers 	(((curve_size_in_bits)+(sizeof(mp_digit)*8-1))/(sizeof(mp_digit)*8))
65*f9fbec18Smcpowers #define ECL_BITS (sizeof(mp_digit)*8)
66*f9fbec18Smcpowers #define ECL_MAX_FIELD_SIZE_DIGITS (80/sizeof(mp_digit))
67*f9fbec18Smcpowers 
68*f9fbec18Smcpowers /* Gets the i'th bit in the binary representation of a. If i >= length(a),
69*f9fbec18Smcpowers  * then return 0. (The above behaviour differs from mpl_get_bit, which
70*f9fbec18Smcpowers  * causes an error if i >= length(a).) */
71*f9fbec18Smcpowers #define MP_GET_BIT(a, i) \
72*f9fbec18Smcpowers 	((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i))
73*f9fbec18Smcpowers 
74*f9fbec18Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
75*f9fbec18Smcpowers #define MP_ADD_CARRY(a1, a2, s, cin, cout)   \
76*f9fbec18Smcpowers     { mp_word w; \
77*f9fbec18Smcpowers     w = ((mp_word)(cin)) + (a1) + (a2); \
78*f9fbec18Smcpowers     s = ACCUM(w); \
79*f9fbec18Smcpowers     cout = CARRYOUT(w); }
80*f9fbec18Smcpowers 
81*f9fbec18Smcpowers #define MP_SUB_BORROW(a1, a2, s, bin, bout)   \
82*f9fbec18Smcpowers     { mp_word w; \
83*f9fbec18Smcpowers     w = ((mp_word)(a1)) - (a2) - (bin); \
84*f9fbec18Smcpowers     s = ACCUM(w); \
85*f9fbec18Smcpowers     bout = (w >> MP_DIGIT_BIT) & 1; }
86*f9fbec18Smcpowers 
87*f9fbec18Smcpowers #else
88*f9fbec18Smcpowers /* NOTE,
89*f9fbec18Smcpowers  * cin and cout could be the same variable.
90*f9fbec18Smcpowers  * bin and bout could be the same variable.
91*f9fbec18Smcpowers  * a1 or a2 and s could be the same variable.
92*f9fbec18Smcpowers  * don't trash those outputs until their respective inputs have
93*f9fbec18Smcpowers  * been read. */
94*f9fbec18Smcpowers #define MP_ADD_CARRY(a1, a2, s, cin, cout)   \
95*f9fbec18Smcpowers     { mp_digit tmp,sum; \
96*f9fbec18Smcpowers     tmp = (a1); \
97*f9fbec18Smcpowers     sum = tmp + (a2); \
98*f9fbec18Smcpowers     tmp = (sum < tmp);                     /* detect overflow */ \
99*f9fbec18Smcpowers     s = sum += (cin); \
100*f9fbec18Smcpowers     cout = tmp + (sum < (cin)); }
101*f9fbec18Smcpowers 
102*f9fbec18Smcpowers #define MP_SUB_BORROW(a1, a2, s, bin, bout)   \
103*f9fbec18Smcpowers     { mp_digit tmp; \
104*f9fbec18Smcpowers     tmp = (a1); \
105*f9fbec18Smcpowers     s = tmp - (a2); \
106*f9fbec18Smcpowers     tmp = (s > tmp);                    /* detect borrow */ \
107*f9fbec18Smcpowers     if ((bin) && !s--) tmp++;	\
108*f9fbec18Smcpowers     bout = tmp; }
109*f9fbec18Smcpowers #endif
110*f9fbec18Smcpowers 
111*f9fbec18Smcpowers 
112*f9fbec18Smcpowers struct GFMethodStr;
113*f9fbec18Smcpowers typedef struct GFMethodStr GFMethod;
114*f9fbec18Smcpowers struct GFMethodStr {
115*f9fbec18Smcpowers 	/* Indicates whether the structure was constructed from dynamic memory
116*f9fbec18Smcpowers 	 * or statically created. */
117*f9fbec18Smcpowers 	int constructed;
118*f9fbec18Smcpowers 	/* Irreducible that defines the field. For prime fields, this is the
119*f9fbec18Smcpowers 	 * prime p. For binary polynomial fields, this is the bitstring
120*f9fbec18Smcpowers 	 * representation of the irreducible polynomial. */
121*f9fbec18Smcpowers 	mp_int irr;
122*f9fbec18Smcpowers 	/* For prime fields, the value irr_arr[0] is the number of bits in the
123*f9fbec18Smcpowers 	 * field. For binary polynomial fields, the irreducible polynomial
124*f9fbec18Smcpowers 	 * f(t) is represented as an array of unsigned int[], where f(t) is
125*f9fbec18Smcpowers 	 * of the form: f(t) = t^p[0] + t^p[1] + ... + t^p[4] where m = p[0]
126*f9fbec18Smcpowers 	 * > p[1] > ... > p[4] = 0. */
127*f9fbec18Smcpowers 	unsigned int irr_arr[5];
128*f9fbec18Smcpowers 	/* Field arithmetic methods. All methods (except field_enc and
129*f9fbec18Smcpowers 	 * field_dec) are assumed to take field-encoded parameters and return
130*f9fbec18Smcpowers 	 * field-encoded values. All methods (except field_enc and field_dec)
131*f9fbec18Smcpowers 	 * are required to be implemented. */
132*f9fbec18Smcpowers 	mp_err (*field_add) (const mp_int *a, const mp_int *b, mp_int *r,
133*f9fbec18Smcpowers 						 const GFMethod *meth);
134*f9fbec18Smcpowers 	mp_err (*field_neg) (const mp_int *a, mp_int *r, const GFMethod *meth);
135*f9fbec18Smcpowers 	mp_err (*field_sub) (const mp_int *a, const mp_int *b, mp_int *r,
136*f9fbec18Smcpowers 						 const GFMethod *meth);
137*f9fbec18Smcpowers 	mp_err (*field_mod) (const mp_int *a, mp_int *r, const GFMethod *meth);
138*f9fbec18Smcpowers 	mp_err (*field_mul) (const mp_int *a, const mp_int *b, mp_int *r,
139*f9fbec18Smcpowers 						 const GFMethod *meth);
140*f9fbec18Smcpowers 	mp_err (*field_sqr) (const mp_int *a, mp_int *r, const GFMethod *meth);
141*f9fbec18Smcpowers 	mp_err (*field_div) (const mp_int *a, const mp_int *b, mp_int *r,
142*f9fbec18Smcpowers 						 const GFMethod *meth);
143*f9fbec18Smcpowers 	mp_err (*field_enc) (const mp_int *a, mp_int *r, const GFMethod *meth);
144*f9fbec18Smcpowers 	mp_err (*field_dec) (const mp_int *a, mp_int *r, const GFMethod *meth);
145*f9fbec18Smcpowers 	/* Extra storage for implementation-specific data.  Any memory
146*f9fbec18Smcpowers 	 * allocated to these extra fields will be cleared by extra_free. */
147*f9fbec18Smcpowers 	void *extra1;
148*f9fbec18Smcpowers 	void *extra2;
149*f9fbec18Smcpowers 	void (*extra_free) (GFMethod *meth);
150*f9fbec18Smcpowers };
151*f9fbec18Smcpowers 
152*f9fbec18Smcpowers /* Construct generic GFMethods. */
153*f9fbec18Smcpowers GFMethod *GFMethod_consGFp(const mp_int *irr);
154*f9fbec18Smcpowers GFMethod *GFMethod_consGFp_mont(const mp_int *irr);
155*f9fbec18Smcpowers GFMethod *GFMethod_consGF2m(const mp_int *irr,
156*f9fbec18Smcpowers 							const unsigned int irr_arr[5]);
157*f9fbec18Smcpowers /* Free the memory allocated (if any) to a GFMethod object. */
158*f9fbec18Smcpowers void GFMethod_free(GFMethod *meth);
159*f9fbec18Smcpowers 
160*f9fbec18Smcpowers struct ECGroupStr {
161*f9fbec18Smcpowers 	/* Indicates whether the structure was constructed from dynamic memory
162*f9fbec18Smcpowers 	 * or statically created. */
163*f9fbec18Smcpowers 	int constructed;
164*f9fbec18Smcpowers 	/* Field definition and arithmetic. */
165*f9fbec18Smcpowers 	GFMethod *meth;
166*f9fbec18Smcpowers 	/* Textual representation of curve name, if any. */
167*f9fbec18Smcpowers 	char *text;
168*f9fbec18Smcpowers #ifdef _KERNEL
169*f9fbec18Smcpowers 	int text_len;
170*f9fbec18Smcpowers #endif
171*f9fbec18Smcpowers 	/* Curve parameters, field-encoded. */
172*f9fbec18Smcpowers 	mp_int curvea, curveb;
173*f9fbec18Smcpowers 	/* x and y coordinates of the base point, field-encoded. */
174*f9fbec18Smcpowers 	mp_int genx, geny;
175*f9fbec18Smcpowers 	/* Order and cofactor of the base point. */
176*f9fbec18Smcpowers 	mp_int order;
177*f9fbec18Smcpowers 	int cofactor;
178*f9fbec18Smcpowers 	/* Point arithmetic methods. All methods are assumed to take
179*f9fbec18Smcpowers 	 * field-encoded parameters and return field-encoded values. All
180*f9fbec18Smcpowers 	 * methods (except base_point_mul and points_mul) are required to be
181*f9fbec18Smcpowers 	 * implemented. */
182*f9fbec18Smcpowers 	mp_err (*point_add) (const mp_int *px, const mp_int *py,
183*f9fbec18Smcpowers 						 const mp_int *qx, const mp_int *qy, mp_int *rx,
184*f9fbec18Smcpowers 						 mp_int *ry, const ECGroup *group);
185*f9fbec18Smcpowers 	mp_err (*point_sub) (const mp_int *px, const mp_int *py,
186*f9fbec18Smcpowers 						 const mp_int *qx, const mp_int *qy, mp_int *rx,
187*f9fbec18Smcpowers 						 mp_int *ry, const ECGroup *group);
188*f9fbec18Smcpowers 	mp_err (*point_dbl) (const mp_int *px, const mp_int *py, mp_int *rx,
189*f9fbec18Smcpowers 						 mp_int *ry, const ECGroup *group);
190*f9fbec18Smcpowers 	mp_err (*point_mul) (const mp_int *n, const mp_int *px,
191*f9fbec18Smcpowers 						 const mp_int *py, mp_int *rx, mp_int *ry,
192*f9fbec18Smcpowers 						 const ECGroup *group);
193*f9fbec18Smcpowers 	mp_err (*base_point_mul) (const mp_int *n, mp_int *rx, mp_int *ry,
194*f9fbec18Smcpowers 							  const ECGroup *group);
195*f9fbec18Smcpowers 	mp_err (*points_mul) (const mp_int *k1, const mp_int *k2,
196*f9fbec18Smcpowers 						  const mp_int *px, const mp_int *py, mp_int *rx,
197*f9fbec18Smcpowers 						  mp_int *ry, const ECGroup *group);
198*f9fbec18Smcpowers 	mp_err (*validate_point) (const mp_int *px, const mp_int *py, const ECGroup *group);
199*f9fbec18Smcpowers 	/* Extra storage for implementation-specific data.  Any memory
200*f9fbec18Smcpowers 	 * allocated to these extra fields will be cleared by extra_free. */
201*f9fbec18Smcpowers 	void *extra1;
202*f9fbec18Smcpowers 	void *extra2;
203*f9fbec18Smcpowers 	void (*extra_free) (ECGroup *group);
204*f9fbec18Smcpowers };
205*f9fbec18Smcpowers 
206*f9fbec18Smcpowers /* Wrapper functions for generic prime field arithmetic. */
207*f9fbec18Smcpowers mp_err ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r,
208*f9fbec18Smcpowers 				  const GFMethod *meth);
209*f9fbec18Smcpowers mp_err ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
210*f9fbec18Smcpowers mp_err ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r,
211*f9fbec18Smcpowers 				  const GFMethod *meth);
212*f9fbec18Smcpowers 
213*f9fbec18Smcpowers /* fixed length in-line adds. Count is in words */
214*f9fbec18Smcpowers mp_err ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r,
215*f9fbec18Smcpowers 				  const GFMethod *meth);
216*f9fbec18Smcpowers mp_err ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r,
217*f9fbec18Smcpowers 				  const GFMethod *meth);
218*f9fbec18Smcpowers mp_err ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r,
219*f9fbec18Smcpowers 				  const GFMethod *meth);
220*f9fbec18Smcpowers mp_err ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r,
221*f9fbec18Smcpowers 				  const GFMethod *meth);
222*f9fbec18Smcpowers mp_err ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r,
223*f9fbec18Smcpowers 				  const GFMethod *meth);
224*f9fbec18Smcpowers mp_err ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r,
225*f9fbec18Smcpowers 				  const GFMethod *meth);
226*f9fbec18Smcpowers mp_err ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r,
227*f9fbec18Smcpowers 				  const GFMethod *meth);
228*f9fbec18Smcpowers mp_err ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r,
229*f9fbec18Smcpowers 				  const GFMethod *meth);
230*f9fbec18Smcpowers 
231*f9fbec18Smcpowers mp_err ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
232*f9fbec18Smcpowers mp_err ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r,
233*f9fbec18Smcpowers 				  const GFMethod *meth);
234*f9fbec18Smcpowers mp_err ec_GFp_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
235*f9fbec18Smcpowers mp_err ec_GFp_div(const mp_int *a, const mp_int *b, mp_int *r,
236*f9fbec18Smcpowers 				  const GFMethod *meth);
237*f9fbec18Smcpowers /* Wrapper functions for generic binary polynomial field arithmetic. */
238*f9fbec18Smcpowers mp_err ec_GF2m_add(const mp_int *a, const mp_int *b, mp_int *r,
239*f9fbec18Smcpowers 				   const GFMethod *meth);
240*f9fbec18Smcpowers mp_err ec_GF2m_neg(const mp_int *a, mp_int *r, const GFMethod *meth);
241*f9fbec18Smcpowers mp_err ec_GF2m_mod(const mp_int *a, mp_int *r, const GFMethod *meth);
242*f9fbec18Smcpowers mp_err ec_GF2m_mul(const mp_int *a, const mp_int *b, mp_int *r,
243*f9fbec18Smcpowers 				   const GFMethod *meth);
244*f9fbec18Smcpowers mp_err ec_GF2m_sqr(const mp_int *a, mp_int *r, const GFMethod *meth);
245*f9fbec18Smcpowers mp_err ec_GF2m_div(const mp_int *a, const mp_int *b, mp_int *r,
246*f9fbec18Smcpowers 				   const GFMethod *meth);
247*f9fbec18Smcpowers 
248*f9fbec18Smcpowers /* Montgomery prime field arithmetic. */
249*f9fbec18Smcpowers mp_err ec_GFp_mul_mont(const mp_int *a, const mp_int *b, mp_int *r,
250*f9fbec18Smcpowers 					   const GFMethod *meth);
251*f9fbec18Smcpowers mp_err ec_GFp_sqr_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
252*f9fbec18Smcpowers mp_err ec_GFp_div_mont(const mp_int *a, const mp_int *b, mp_int *r,
253*f9fbec18Smcpowers 					   const GFMethod *meth);
254*f9fbec18Smcpowers mp_err ec_GFp_enc_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
255*f9fbec18Smcpowers mp_err ec_GFp_dec_mont(const mp_int *a, mp_int *r, const GFMethod *meth);
256*f9fbec18Smcpowers void ec_GFp_extra_free_mont(GFMethod *meth);
257*f9fbec18Smcpowers 
258*f9fbec18Smcpowers /* point multiplication */
259*f9fbec18Smcpowers mp_err ec_pts_mul_basic(const mp_int *k1, const mp_int *k2,
260*f9fbec18Smcpowers 						const mp_int *px, const mp_int *py, mp_int *rx,
261*f9fbec18Smcpowers 						mp_int *ry, const ECGroup *group);
262*f9fbec18Smcpowers mp_err ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2,
263*f9fbec18Smcpowers 						   const mp_int *px, const mp_int *py, mp_int *rx,
264*f9fbec18Smcpowers 						   mp_int *ry, const ECGroup *group);
265*f9fbec18Smcpowers 
266*f9fbec18Smcpowers /* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should
267*f9fbec18Smcpowers  * be an array of signed char's to output to, bitsize should be the number
268*f9fbec18Smcpowers  * of bits of out, in is the original scalar, and w is the window size.
269*f9fbec18Smcpowers  * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A.
270*f9fbec18Smcpowers  * Menezes, "Software implementation of elliptic curve cryptography over
271*f9fbec18Smcpowers  * binary fields", Proc. CHES 2000. */
272*f9fbec18Smcpowers mp_err ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in,
273*f9fbec18Smcpowers 					   int w);
274*f9fbec18Smcpowers 
275*f9fbec18Smcpowers /* Optimized field arithmetic */
276*f9fbec18Smcpowers mp_err ec_group_set_gfp192(ECGroup *group, ECCurveName);
277*f9fbec18Smcpowers mp_err ec_group_set_gfp224(ECGroup *group, ECCurveName);
278*f9fbec18Smcpowers mp_err ec_group_set_gfp256(ECGroup *group, ECCurveName);
279*f9fbec18Smcpowers mp_err ec_group_set_gfp384(ECGroup *group, ECCurveName);
280*f9fbec18Smcpowers mp_err ec_group_set_gfp521(ECGroup *group, ECCurveName);
281*f9fbec18Smcpowers mp_err ec_group_set_gf2m163(ECGroup *group, ECCurveName name);
282*f9fbec18Smcpowers mp_err ec_group_set_gf2m193(ECGroup *group, ECCurveName name);
283*f9fbec18Smcpowers mp_err ec_group_set_gf2m233(ECGroup *group, ECCurveName name);
284*f9fbec18Smcpowers 
285*f9fbec18Smcpowers /* Optimized floating-point arithmetic */
286*f9fbec18Smcpowers #ifdef ECL_USE_FP
287*f9fbec18Smcpowers mp_err ec_group_set_secp160r1_fp(ECGroup *group);
288*f9fbec18Smcpowers mp_err ec_group_set_nistp192_fp(ECGroup *group);
289*f9fbec18Smcpowers mp_err ec_group_set_nistp224_fp(ECGroup *group);
290*f9fbec18Smcpowers #endif
291*f9fbec18Smcpowers 
292*f9fbec18Smcpowers #endif /* _ECL_PRIV_H */
293