annotate src/jdk.crypto.ec/share/native/libsunec/impl/ecl-priv.h @ 17280:f09a6beb1e23

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