1 /* 2 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. 3 * Use is subject to license terms. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with this library; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* ********************************************************************* 25 * 26 * The Original Code is the elliptic curve math library. 27 * 28 * The Initial Developer of the Original Code is 29 * Sun Microsystems, Inc. 30 * Portions created by the Initial Developer are Copyright (C) 2003 31 * the Initial Developer. All Rights Reserved. 32 * 33 * Contributor(s): 34 * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories 35 * 36 *********************************************************************** */ 37 38 #include "mpi.h" 39 #include "mplogic.h" 40 #include "ecl.h" 41 #include "ecl-priv.h" 42 #ifndef _KERNEL 43 #include <stdlib.h> 44 #endif 45 46 /* Elliptic curve scalar-point multiplication. Computes R(x, y) = k * P(x, 47 * y). If x, y = NULL, then P is assumed to be the generator (base point) 48 * of the group of points on the elliptic curve. Input and output values 49 * are assumed to be NOT field-encoded. */ 50 mp_err 51 ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px, 52 const mp_int *py, mp_int *rx, mp_int *ry) 53 { 54 mp_err res = MP_OKAY; 55 mp_int kt; 56 57 ARGCHK((k != NULL) && (group != NULL), MP_BADARG); 58 MP_DIGITS(&kt) = 0; 59 60 /* want scalar to be less than or equal to group order */ 61 if (mp_cmp(k, &group->order) > 0) { 62 MP_CHECKOK(mp_init(&kt, FLAG(k))); 63 MP_CHECKOK(mp_mod(k, &group->order, &kt)); 64 } else { 65 MP_SIGN(&kt) = MP_ZPOS; 66 MP_USED(&kt) = MP_USED(k); 67 MP_ALLOC(&kt) = MP_ALLOC(k); 68 MP_DIGITS(&kt) = MP_DIGITS(k); 69 } 70 71 if ((px == NULL) || (py == NULL)) { 72 if (group->base_point_mul) { 73 MP_CHECKOK(group->base_point_mul(&kt, rx, ry, group)); 74 } else { 75 MP_CHECKOK(group-> 76 point_mul(&kt, &group->genx, &group->geny, rx, ry, 77 group)); 78 } 79 } else { 80 if (group->meth->field_enc) { 81 MP_CHECKOK(group->meth->field_enc(px, rx, group->meth)); 82 MP_CHECKOK(group->meth->field_enc(py, ry, group->meth)); 83 MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group)); 84 } else { 85 MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group)); 86 } 87 } 88 if (group->meth->field_dec) { 89 MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth)); 90 MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth)); 91 } 92 93 CLEANUP: 94 if (MP_DIGITS(&kt) != MP_DIGITS(k)) { 95 mp_clear(&kt); 96 } 97 return res; 98 } 99 100 /* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G + 101 * k2 * P(x, y), where G is the generator (base point) of the group of 102 * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL. 103 * Input and output values are assumed to be NOT field-encoded. */ 104 mp_err 105 ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px, 106 const mp_int *py, mp_int *rx, mp_int *ry, 107 const ECGroup *group) 108 { 109 mp_err res = MP_OKAY; 110 mp_int sx, sy; 111 112 ARGCHK(group != NULL, MP_BADARG); 113 ARGCHK(!((k1 == NULL) 114 && ((k2 == NULL) || (px == NULL) 115 || (py == NULL))), MP_BADARG); 116 117 /* if some arguments are not defined used ECPoint_mul */ 118 if (k1 == NULL) { 119 return ECPoint_mul(group, k2, px, py, rx, ry); 120 } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) { 121 return ECPoint_mul(group, k1, NULL, NULL, rx, ry); 122 } 123 124 MP_DIGITS(&sx) = 0; 125 MP_DIGITS(&sy) = 0; 126 MP_CHECKOK(mp_init(&sx, FLAG(k1))); 127 MP_CHECKOK(mp_init(&sy, FLAG(k1))); 128 129 MP_CHECKOK(ECPoint_mul(group, k1, NULL, NULL, &sx, &sy)); 130 MP_CHECKOK(ECPoint_mul(group, k2, px, py, rx, ry)); 131 132 if (group->meth->field_enc) { 133 MP_CHECKOK(group->meth->field_enc(&sx, &sx, group->meth)); 134 MP_CHECKOK(group->meth->field_enc(&sy, &sy, group->meth)); 135 MP_CHECKOK(group->meth->field_enc(rx, rx, group->meth)); 136 MP_CHECKOK(group->meth->field_enc(ry, ry, group->meth)); 137 } 138 139 MP_CHECKOK(group->point_add(&sx, &sy, rx, ry, rx, ry, group)); 140 141 if (group->meth->field_dec) { 142 MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth)); 143 MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth)); 144 } 145 146 CLEANUP: 147 mp_clear(&sx); 148 mp_clear(&sy); 149 return res; 150 } 151 152 /* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G + 153 * k2 * P(x, y), where G is the generator (base point) of the group of 154 * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL. 155 * Input and output values are assumed to be NOT field-encoded. Uses 156 * algorithm 15 (simultaneous multiple point multiplication) from Brown, 157 * Hankerson, Lopez, Menezes. Software Implementation of the NIST 158 * Elliptic Curves over Prime Fields. */ 159 mp_err 160 ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px, 161 const mp_int *py, mp_int *rx, mp_int *ry, 162 const ECGroup *group) 163 { 164 mp_err res = MP_OKAY; 165 mp_int precomp[4][4][2]; 166 const mp_int *a, *b; 167 int i, j; 168 int ai, bi, d; 169 170 ARGCHK(group != NULL, MP_BADARG); 171 ARGCHK(!((k1 == NULL) 172 && ((k2 == NULL) || (px == NULL) 173 || (py == NULL))), MP_BADARG); 174 175 /* if some arguments are not defined used ECPoint_mul */ 176 if (k1 == NULL) { 177 return ECPoint_mul(group, k2, px, py, rx, ry); 178 } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) { 179 return ECPoint_mul(group, k1, NULL, NULL, rx, ry); 180 } 181 182 /* initialize precomputation table */ 183 for (i = 0; i < 4; i++) { 184 for (j = 0; j < 4; j++) { 185 MP_DIGITS(&precomp[i][j][0]) = 0; 186 MP_DIGITS(&precomp[i][j][1]) = 0; 187 } 188 } 189 for (i = 0; i < 4; i++) { 190 for (j = 0; j < 4; j++) { 191 MP_CHECKOK( mp_init_size(&precomp[i][j][0], 192 ECL_MAX_FIELD_SIZE_DIGITS, FLAG(k1)) ); 193 MP_CHECKOK( mp_init_size(&precomp[i][j][1], 194 ECL_MAX_FIELD_SIZE_DIGITS, FLAG(k1)) ); 195 } 196 } 197 198 /* fill precomputation table */ 199 /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */ 200 if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) { 201 a = k2; 202 b = k1; 203 if (group->meth->field_enc) { 204 MP_CHECKOK(group->meth-> 205 field_enc(px, &precomp[1][0][0], group->meth)); 206 MP_CHECKOK(group->meth-> 207 field_enc(py, &precomp[1][0][1], group->meth)); 208 } else { 209 MP_CHECKOK(mp_copy(px, &precomp[1][0][0])); 210 MP_CHECKOK(mp_copy(py, &precomp[1][0][1])); 211 } 212 MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0])); 213 MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1])); 214 } else { 215 a = k1; 216 b = k2; 217 MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0])); 218 MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1])); 219 if (group->meth->field_enc) { 220 MP_CHECKOK(group->meth-> 221 field_enc(px, &precomp[0][1][0], group->meth)); 222 MP_CHECKOK(group->meth-> 223 field_enc(py, &precomp[0][1][1], group->meth)); 224 } else { 225 MP_CHECKOK(mp_copy(px, &precomp[0][1][0])); 226 MP_CHECKOK(mp_copy(py, &precomp[0][1][1])); 227 } 228 } 229 /* precompute [*][0][*] */ 230 mp_zero(&precomp[0][0][0]); 231 mp_zero(&precomp[0][0][1]); 232 MP_CHECKOK(group-> 233 point_dbl(&precomp[1][0][0], &precomp[1][0][1], 234 &precomp[2][0][0], &precomp[2][0][1], group)); 235 MP_CHECKOK(group-> 236 point_add(&precomp[1][0][0], &precomp[1][0][1], 237 &precomp[2][0][0], &precomp[2][0][1], 238 &precomp[3][0][0], &precomp[3][0][1], group)); 239 /* precompute [*][1][*] */ 240 for (i = 1; i < 4; i++) { 241 MP_CHECKOK(group-> 242 point_add(&precomp[0][1][0], &precomp[0][1][1], 243 &precomp[i][0][0], &precomp[i][0][1], 244 &precomp[i][1][0], &precomp[i][1][1], group)); 245 } 246 /* precompute [*][2][*] */ 247 MP_CHECKOK(group-> 248 point_dbl(&precomp[0][1][0], &precomp[0][1][1], 249 &precomp[0][2][0], &precomp[0][2][1], group)); 250 for (i = 1; i < 4; i++) { 251 MP_CHECKOK(group-> 252 point_add(&precomp[0][2][0], &precomp[0][2][1], 253 &precomp[i][0][0], &precomp[i][0][1], 254 &precomp[i][2][0], &precomp[i][2][1], group)); 255 } 256 /* precompute [*][3][*] */ 257 MP_CHECKOK(group-> 258 point_add(&precomp[0][1][0], &precomp[0][1][1], 259 &precomp[0][2][0], &precomp[0][2][1], 260 &precomp[0][3][0], &precomp[0][3][1], group)); 261 for (i = 1; i < 4; i++) { 262 MP_CHECKOK(group-> 263 point_add(&precomp[0][3][0], &precomp[0][3][1], 264 &precomp[i][0][0], &precomp[i][0][1], 265 &precomp[i][3][0], &precomp[i][3][1], group)); 266 } 267 268 d = (mpl_significant_bits(a) + 1) / 2; 269 270 /* R = inf */ 271 mp_zero(rx); 272 mp_zero(ry); 273 274 for (i = d - 1; i >= 0; i--) { 275 ai = MP_GET_BIT(a, 2 * i + 1); 276 ai <<= 1; 277 ai |= MP_GET_BIT(a, 2 * i); 278 bi = MP_GET_BIT(b, 2 * i + 1); 279 bi <<= 1; 280 bi |= MP_GET_BIT(b, 2 * i); 281 /* R = 2^2 * R */ 282 MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group)); 283 MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group)); 284 /* R = R + (ai * A + bi * B) */ 285 MP_CHECKOK(group-> 286 point_add(rx, ry, &precomp[ai][bi][0], 287 &precomp[ai][bi][1], rx, ry, group)); 288 } 289 290 if (group->meth->field_dec) { 291 MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth)); 292 MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth)); 293 } 294 295 CLEANUP: 296 for (i = 0; i < 4; i++) { 297 for (j = 0; j < 4; j++) { 298 mp_clear(&precomp[i][j][0]); 299 mp_clear(&precomp[i][j][1]); 300 } 301 } 302 return res; 303 } 304 305 /* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G + 306 * k2 * P(x, y), where G is the generator (base point) of the group of 307 * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL. 308 * Input and output values are assumed to be NOT field-encoded. */ 309 mp_err 310 ECPoints_mul(const ECGroup *group, const mp_int *k1, const mp_int *k2, 311 const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry) 312 { 313 mp_err res = MP_OKAY; 314 mp_int k1t, k2t; 315 const mp_int *k1p, *k2p; 316 317 MP_DIGITS(&k1t) = 0; 318 MP_DIGITS(&k2t) = 0; 319 320 ARGCHK(group != NULL, MP_BADARG); 321 322 /* want scalar to be less than or equal to group order */ 323 if (k1 != NULL) { 324 if (mp_cmp(k1, &group->order) >= 0) { 325 MP_CHECKOK(mp_init(&k1t, FLAG(k1))); 326 MP_CHECKOK(mp_mod(k1, &group->order, &k1t)); 327 k1p = &k1t; 328 } else { 329 k1p = k1; 330 } 331 } else { 332 k1p = k1; 333 } 334 if (k2 != NULL) { 335 if (mp_cmp(k2, &group->order) >= 0) { 336 MP_CHECKOK(mp_init(&k2t, FLAG(k2))); 337 MP_CHECKOK(mp_mod(k2, &group->order, &k2t)); 338 k2p = &k2t; 339 } else { 340 k2p = k2; 341 } 342 } else { 343 k2p = k2; 344 } 345 346 /* if points_mul is defined, then use it */ 347 if (group->points_mul) { 348 res = group->points_mul(k1p, k2p, px, py, rx, ry, group); 349 } else { 350 res = ec_pts_mul_simul_w2(k1p, k2p, px, py, rx, ry, group); 351 } 352 353 CLEANUP: 354 mp_clear(&k1t); 355 mp_clear(&k2t); 356 return res; 357 }