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