Home | History | Annotate | Download | only in ec
      1 /* Copyright (c) 2018, Google Inc.
      2  *
      3  * Permission to use, copy, modify, and/or distribute this software for any
      4  * purpose with or without fee is hereby granted, provided that the above
      5  * copyright notice and this permission notice appear in all copies.
      6  *
      7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
     12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
     13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
     14 
     15 #include <openssl/ec.h>
     16 #include <openssl/err.h>
     17 #include <openssl/mem.h>
     18 
     19 #include "internal.h"
     20 #include "../bn/internal.h"
     21 #include "../../internal.h"
     22 
     23 
     24 int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
     25                         const BIGNUM *in) {
     26   if (!bn_copy_words(out->words, group->order.width, in) ||
     27       !bn_less_than_words(out->words, group->order.d, group->order.width)) {
     28     OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
     29     return 0;
     30   }
     31   return 1;
     32 }
     33 
     34 int ec_scalar_equal_vartime(const EC_GROUP *group, const EC_SCALAR *a,
     35                             const EC_SCALAR *b) {
     36   return OPENSSL_memcmp(a->words, b->words,
     37                         group->order.width * sizeof(BN_ULONG)) == 0;
     38 }
     39 
     40 int ec_scalar_is_zero(const EC_GROUP *group, const EC_SCALAR *a) {
     41   BN_ULONG mask = 0;
     42   for (int i = 0; i < group->order.width; i++) {
     43     mask |= a->words[i];
     44   }
     45   return mask == 0;
     46 }
     47 
     48 int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out,
     49                              const uint8_t additional_data[32]) {
     50   return bn_rand_range_words(out->words, 1, group->order.d, group->order.width,
     51                              additional_data);
     52 }
     53 
     54 void ec_scalar_add(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a,
     55                    const EC_SCALAR *b) {
     56   const BIGNUM *order = &group->order;
     57   BN_ULONG tmp[EC_MAX_WORDS];
     58   bn_mod_add_words(r->words, a->words, b->words, order->d, tmp, order->width);
     59   OPENSSL_cleanse(tmp, sizeof(tmp));
     60 }
     61 
     62 void ec_scalar_to_montgomery(const EC_GROUP *group, EC_SCALAR *r,
     63                              const EC_SCALAR *a) {
     64   const BIGNUM *order = &group->order;
     65   bn_to_montgomery_small(r->words, a->words, order->width, group->order_mont);
     66 }
     67 
     68 void ec_scalar_from_montgomery(const EC_GROUP *group, EC_SCALAR *r,
     69                                const EC_SCALAR *a) {
     70   const BIGNUM *order = &group->order;
     71   bn_from_montgomery_small(r->words, a->words, order->width, group->order_mont);
     72 }
     73 
     74 void ec_scalar_mul_montgomery(const EC_GROUP *group, EC_SCALAR *r,
     75                               const EC_SCALAR *a, const EC_SCALAR *b) {
     76   const BIGNUM *order = &group->order;
     77   bn_mod_mul_montgomery_small(r->words, a->words, b->words, order->width,
     78                               group->order_mont);
     79 }
     80 
     81 void ec_simple_scalar_inv_montgomery(const EC_GROUP *group, EC_SCALAR *r,
     82                                      const EC_SCALAR *a) {
     83   const BIGNUM *order = &group->order;
     84   bn_mod_inverse_prime_mont_small(r->words, a->words, order->width,
     85                                   group->order_mont);
     86 }
     87 
     88 void ec_scalar_inv_montgomery(const EC_GROUP *group, EC_SCALAR *r,
     89                               const EC_SCALAR *a) {
     90   group->meth->scalar_inv_montgomery(group, r, a);
     91 }
     92 
     93 int ec_scalar_inv_montgomery_vartime(const EC_GROUP *group, EC_SCALAR *r,
     94                                      const EC_SCALAR *a) {
     95   return group->meth->scalar_inv_montgomery_vartime(group, r, a);
     96 }
     97