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