1 /* 2 * Copyright (c) 2007, 2017, 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 * Last Modified Date from the Original Code: May 2017 37 *********************************************************************** */ 38 39 #include "mpi.h" 40 #include "mplogic.h" 41 #include "ecl.h" 42 #include "ecl-priv.h" 43 #ifndef _KERNEL 44 #include <stdlib.h> 45 #endif 46 47 /* Elliptic curve scalar-point multiplication. Computes R(x, y) = k * P(x, 48 * y). If x, y = NULL, then P is assumed to be the generator (base point) 49 * of the group of points on the elliptic curve. Input and output values 50 * are assumed to be NOT field-encoded. */ 51 mp_err 52 ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px, 53 const mp_int *py, mp_int *rx, mp_int *ry, 54 int timing) 55 { 56 mp_err res = MP_OKAY; 57 mp_int kt; 58 59 ARGCHK((k != NULL) && (group != NULL), MP_BADARG); 60 MP_DIGITS(&kt) = 0; 61 62 /* want scalar to be less than or equal to group order */ 63 if (mp_cmp(k, &group->order) > 0) { 64 MP_CHECKOK(mp_init(&kt, FLAG(k))); 65 MP_CHECKOK(mp_mod(k, &group->order, &kt)); 66 } else { 67 MP_SIGN(&kt) = MP_ZPOS; 68 MP_USED(&kt) = MP_USED(k); 69 MP_ALLOC(&kt) = MP_ALLOC(k); 70 MP_DIGITS(&kt) = MP_DIGITS(k); 71 } 72 73 if ((px == NULL) || (py == NULL)) { 74 if (group->base_point_mul) { 75 MP_CHECKOK(group->base_point_mul(&kt, rx, ry, group)); 76 } else { 77 kt.flag = (mp_sign)0; 78 MP_CHECKOK(group-> 79 point_mul(&kt, &group->genx, &group->geny, rx, ry, 80 group, timing)); 81 } 82 } else { 83 if (group->meth->field_enc) { 84 MP_CHECKOK(group->meth->field_enc(px, rx, group->meth)); 85 MP_CHECKOK(group->meth->field_enc(py, ry, group->meth)); 86 MP_CHECKOK(group->point_mul(&kt, rx, ry, rx, ry, group, timing)); 87 } else { 88 kt.flag = (mp_sign)0; 89 MP_CHECKOK(group->point_mul(&kt, px, py, rx, ry, group, timing)); 90 } 91 } 92 if (group->meth->field_dec) { 93 MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth)); 94 MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth)); 95 } 96 97 CLEANUP: 98 if (MP_DIGITS(&kt) != MP_DIGITS(k)) { 99 mp_clear(&kt); 100 } 101 return res; 102 } 103 104 /* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G + 105 * k2 * P(x, y), where G is the generator (base point) of the group of 106 * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL. 107 * Input and output values are assumed to be NOT field-encoded. */ 108 mp_err 109 ec_pts_mul_basic(const mp_int *k1, const mp_int *k2, const mp_int *px, 110 const mp_int *py, mp_int *rx, mp_int *ry, 111 const ECGroup *group, int timing) 112 { 113 mp_err res = MP_OKAY; 114 mp_int sx, sy; 115 116 ARGCHK(group != NULL, MP_BADARG); 117 ARGCHK(!((k1 == NULL) 118 && ((k2 == NULL) || (px == NULL) 119 || (py == NULL))), MP_BADARG); 120 121 /* if some arguments are not defined used ECPoint_mul */ 122 if (k1 == NULL) { 123 return ECPoint_mul(group, k2, px, py, rx, ry, timing); 124 } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) { 125 return ECPoint_mul(group, k1, NULL, NULL, rx, ry, timing); 126 } 127 128 MP_DIGITS(&sx) = 0; 129 MP_DIGITS(&sy) = 0; 130 MP_CHECKOK(mp_init(&sx, FLAG(k1))); 131 MP_CHECKOK(mp_init(&sy, FLAG(k1))); 132 133 MP_CHECKOK(ECPoint_mul(group, k1, NULL, NULL, &sx, &sy, timing)); 134 MP_CHECKOK(ECPoint_mul(group, k2, px, py, rx, ry, timing)); 135 136 if (group->meth->field_enc) { 137 MP_CHECKOK(group->meth->field_enc(&sx, &sx, group->meth)); 138 MP_CHECKOK(group->meth->field_enc(&sy, &sy, group->meth)); 139 MP_CHECKOK(group->meth->field_enc(rx, rx, group->meth)); 140 MP_CHECKOK(group->meth->field_enc(ry, ry, group->meth)); 141 } 142 143 MP_CHECKOK(group->point_add(&sx, &sy, rx, ry, rx, ry, group)); 144 145 if (group->meth->field_dec) { 146 MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth)); 147 MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth)); 148 } 149 150 CLEANUP: 151 mp_clear(&sx); 152 mp_clear(&sy); 153 return res; 154 } 155 156 /* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G + 157 * k2 * P(x, y), where G is the generator (base point) of the group of 158 * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL. 159 * Input and output values are assumed to be NOT field-encoded. Uses 160 * algorithm 15 (simultaneous multiple point multiplication) from Brown, 161 * Hankerson, Lopez, Menezes. Software Implementation of the NIST 162 * Elliptic Curves over Prime Fields. */ 163 mp_err 164 ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px, 165 const mp_int *py, mp_int *rx, mp_int *ry, 166 const ECGroup *group, int timing) 167 { 168 mp_err res = MP_OKAY; 169 mp_int precomp[4][4][2]; 170 const mp_int *a, *b; 171 int i, j; 172 int ai, bi, d; 173 174 ARGCHK(group != NULL, MP_BADARG); 175 ARGCHK(!((k1 == NULL) 176 && ((k2 == NULL) || (px == NULL) 177 || (py == NULL))), MP_BADARG); 178 179 /* if some arguments are not defined used ECPoint_mul */ 180 if (k1 == NULL) { 181 return ECPoint_mul(group, k2, px, py, rx, ry, timing); 182 } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) { 183 return ECPoint_mul(group, k1, NULL, NULL, rx, ry, timing); 184 } 185 186 /* initialize precomputation table */ 187 for (i = 0; i < 4; i++) { 188 for (j = 0; j < 4; j++) { 189 MP_DIGITS(&precomp[i][j][0]) = 0; 190 MP_DIGITS(&precomp[i][j][1]) = 0; 191 } 192 } 193 for (i = 0; i < 4; i++) { 194 for (j = 0; j < 4; j++) { 195 MP_CHECKOK( mp_init_size(&precomp[i][j][0], 196 ECL_MAX_FIELD_SIZE_DIGITS, FLAG(k1)) ); 197 MP_CHECKOK( mp_init_size(&precomp[i][j][1], 198 ECL_MAX_FIELD_SIZE_DIGITS, FLAG(k1)) ); 199 } 200 } 201 202 /* fill precomputation table */ 203 /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */ 204 if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) { 205 a = k2; 206 b = k1; 207 if (group->meth->field_enc) { 208 MP_CHECKOK(group->meth-> 209 field_enc(px, &precomp[1][0][0], group->meth)); 210 MP_CHECKOK(group->meth-> 211 field_enc(py, &precomp[1][0][1], group->meth)); 212 } else { 213 MP_CHECKOK(mp_copy(px, &precomp[1][0][0])); 214 MP_CHECKOK(mp_copy(py, &precomp[1][0][1])); 215 } 216 MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0])); 217 MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1])); 218 } else { 219 a = k1; 220 b = k2; 221 MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0])); 222 MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1])); 223 if (group->meth->field_enc) { 224 MP_CHECKOK(group->meth-> 225 field_enc(px, &precomp[0][1][0], group->meth)); 226 MP_CHECKOK(group->meth-> 227 field_enc(py, &precomp[0][1][1], group->meth)); 228 } else { 229 MP_CHECKOK(mp_copy(px, &precomp[0][1][0])); 230 MP_CHECKOK(mp_copy(py, &precomp[0][1][1])); 231 } 232 } 233 /* precompute [*][0][*] */ 234 mp_zero(&precomp[0][0][0]); 235 mp_zero(&precomp[0][0][1]); 236 MP_CHECKOK(group-> 237 point_dbl(&precomp[1][0][0], &precomp[1][0][1], 238 &precomp[2][0][0], &precomp[2][0][1], group)); 239 MP_CHECKOK(group-> 240 point_add(&precomp[1][0][0], &precomp[1][0][1], 241 &precomp[2][0][0], &precomp[2][0][1], 242 &precomp[3][0][0], &precomp[3][0][1], group)); 243 /* precompute [*][1][*] */ 244 for (i = 1; i < 4; i++) { 245 MP_CHECKOK(group-> 246 point_add(&precomp[0][1][0], &precomp[0][1][1], 247 &precomp[i][0][0], &precomp[i][0][1], 248 &precomp[i][1][0], &precomp[i][1][1], group)); 249 } 250 /* precompute [*][2][*] */ 251 MP_CHECKOK(group-> 252 point_dbl(&precomp[0][1][0], &precomp[0][1][1], 253 &precomp[0][2][0], &precomp[0][2][1], group)); 254 for (i = 1; i < 4; i++) { 255 MP_CHECKOK(group-> 256 point_add(&precomp[0][2][0], &precomp[0][2][1], 257 &precomp[i][0][0], &precomp[i][0][1], 258 &precomp[i][2][0], &precomp[i][2][1], group)); 259 } 260 /* precompute [*][3][*] */ 261 MP_CHECKOK(group-> 262 point_add(&precomp[0][1][0], &precomp[0][1][1], 263 &precomp[0][2][0], &precomp[0][2][1], 264 &precomp[0][3][0], &precomp[0][3][1], group)); 265 for (i = 1; i < 4; i++) { 266 MP_CHECKOK(group-> 267 point_add(&precomp[0][3][0], &precomp[0][3][1], 268 &precomp[i][0][0], &precomp[i][0][1], 269 &precomp[i][3][0], &precomp[i][3][1], group)); 270 } 271 272 d = (mpl_significant_bits(a) + 1) / 2; 273 274 /* R = inf */ 275 mp_zero(rx); 276 mp_zero(ry); 277 278 for (i = d - 1; i >= 0; i--) { 279 ai = MP_GET_BIT(a, 2 * i + 1); 280 ai <<= 1; 281 ai |= MP_GET_BIT(a, 2 * i); 282 bi = MP_GET_BIT(b, 2 * i + 1); 283 bi <<= 1; 284 bi |= MP_GET_BIT(b, 2 * i); 285 /* R = 2^2 * R */ 286 MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group)); 287 MP_CHECKOK(group->point_dbl(rx, ry, rx, ry, group)); 288 /* R = R + (ai * A + bi * B) */ 289 MP_CHECKOK(group-> 290 point_add(rx, ry, &precomp[ai][bi][0], 291 &precomp[ai][bi][1], rx, ry, group)); 292 } 293 294 if (group->meth->field_dec) { 295 MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth)); 296 MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth)); 297 } 298 299 CLEANUP: 300 for (i = 0; i < 4; i++) { 301 for (j = 0; j < 4; j++) { 302 mp_clear(&precomp[i][j][0]); 303 mp_clear(&precomp[i][j][1]); 304 } 305 } 306 return res; 307 } 308 309 /* Elliptic curve scalar-point multiplication. Computes R(x, y) = k1 * G + 310 * k2 * P(x, y), where G is the generator (base point) of the group of 311 * points on the elliptic curve. Allows k1 = NULL or { k2, P } = NULL. 312 * Input and output values are assumed to be NOT field-encoded. */ 313 mp_err 314 ECPoints_mul(const ECGroup *group, const mp_int *k1, const mp_int *k2, 315 const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry, 316 int timing) 317 { 318 mp_err res = MP_OKAY; 319 mp_int k1t, k2t; 320 const mp_int *k1p, *k2p; 321 322 MP_DIGITS(&k1t) = 0; 323 MP_DIGITS(&k2t) = 0; 324 325 ARGCHK(group != NULL, MP_BADARG); 326 327 /* want scalar to be less than or equal to group order */ 328 if (k1 != NULL) { 329 if (mp_cmp(k1, &group->order) >= 0) { 330 MP_CHECKOK(mp_init(&k1t, FLAG(k1))); 331 MP_CHECKOK(mp_mod(k1, &group->order, &k1t)); 332 k1p = &k1t; 333 } else { 334 k1p = k1; 335 } 336 } else { 337 k1p = k1; 338 } 339 if (k2 != NULL) { 340 if (mp_cmp(k2, &group->order) >= 0) { 341 MP_CHECKOK(mp_init(&k2t, FLAG(k2))); 342 MP_CHECKOK(mp_mod(k2, &group->order, &k2t)); 343 k2p = &k2t; 344 } else { 345 k2p = k2; 346 } 347 } else { 348 k2p = k2; 349 } 350 351 /* if points_mul is defined, then use it */ 352 if (group->points_mul) { 353 res = group->points_mul(k1p, k2p, px, py, rx, ry, group, timing); 354 } else { 355 res = ec_pts_mul_simul_w2(k1p, k2p, px, py, rx, ry, group, timing); 356 } 357 358 CLEANUP: 359 mp_clear(&k1t); 360 mp_clear(&k2t); 361 return res; 362 }