boringssl/crypto/fipsmodule/ec/scalar.c
David Benjamin 7121fe24e9 Align ECDSA sign/verify scalar inversions.
We were still using the allocating scalar inversion for ECDSA verify
because previously it seemed to be faster. It appears to have flipped
now, though probably was always just a wash.

While I'm here, save a multiplication by swapping the inversion and
Montgomery reduction.

Did 200000 ECDSA P-256 signing operations in 10025749us (19948.6 ops/sec)
Did 66234 ECDSA P-256 verify operations in 10061123us (6583.2 ops/sec)

Did 202000 ECDSA P-256 signing operations in 10020846us (20158.0 ops/sec)
Did 68052 ECDSA P-256 verify operations in 10020592us (6791.2 ops/sec)

The actual motivation is to get rid of the unchecked EC_SCALAR function
and align sign/verify in preparation for the assembly scalar ops.

Change-Id: I1bd3a5719a67966dc8edaa43535a3864b69f76d0
Reviewed-on: https://boringssl-review.googlesource.com/27588
Reviewed-by: Adam Langley <alangley@gmail.com>
2018-04-24 16:00:12 +00:00

70 lines
2.8 KiB
C

/* Copyright (c) 2018, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/ec.h>
#include "internal.h"
#include "../bn/internal.h"
int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out,
const BIGNUM *in) {
if (!bn_copy_words(out->words, group->order.width, in) ||
!bn_less_than_words(out->words, group->order.d, group->order.width)) {
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR);
return 0;
}
return 1;
}
int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out,
const uint8_t additional_data[32]) {
return bn_rand_range_words(out->words, 1, group->order.d, group->order.width,
additional_data);
}
void ec_scalar_add(const EC_GROUP *group, EC_SCALAR *r, const EC_SCALAR *a,
const EC_SCALAR *b) {
const BIGNUM *order = &group->order;
BN_ULONG tmp[EC_MAX_SCALAR_WORDS];
bn_mod_add_words(r->words, a->words, b->words, order->d, tmp, order->width);
OPENSSL_cleanse(tmp, sizeof(tmp));
}
void ec_scalar_to_montgomery(const EC_GROUP *group, EC_SCALAR *r,
const EC_SCALAR *a) {
const BIGNUM *order = &group->order;
bn_to_montgomery_small(r->words, a->words, order->width, group->order_mont);
}
void ec_scalar_from_montgomery(const EC_GROUP *group, EC_SCALAR *r,
const EC_SCALAR *a) {
const BIGNUM *order = &group->order;
bn_from_montgomery_small(r->words, a->words, order->width, group->order_mont);
}
void ec_scalar_mul_montgomery(const EC_GROUP *group, EC_SCALAR *r,
const EC_SCALAR *a, const EC_SCALAR *b) {
const BIGNUM *order = &group->order;
bn_mod_mul_montgomery_small(r->words, a->words, b->words, order->width,
group->order_mont);
}
void ec_scalar_inv_montgomery(const EC_GROUP *group, EC_SCALAR *r,
const EC_SCALAR *a) {
const BIGNUM *order = &group->order;
bn_mod_inverse_prime_mont_small(r->words, a->words, order->width,
group->order_mont);
}