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 }