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 }