mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-20 12:12:41 -05:00

Use a conditional move of the same kind we use for the affine points in the storage type instead of multiplying with the infinity flag and adding. This results in fewer constructions to worry about for sidechannel behavior. It also might be faster: It doesn't appear to benchmark as slower for me at least; but I think the CMOV is faster than the mul_int + add, but slower than the set+add; making it a wash.
119 lines
5.9 KiB
C
119 lines
5.9 KiB
C
/**********************************************************************
|
|
* Copyright (c) 2013, 2014 Pieter Wuille *
|
|
* Distributed under the MIT software license, see the accompanying *
|
|
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
|
**********************************************************************/
|
|
|
|
#ifndef _SECP256K1_FIELD_
|
|
#define _SECP256K1_FIELD_
|
|
|
|
/** Field element module.
|
|
*
|
|
* Field elements can be represented in several ways, but code accessing
|
|
* it (and implementations) need to take certain properaties into account:
|
|
* - Each field element can be normalized or not.
|
|
* - Each field element has a magnitude, which represents how far away
|
|
* its representation is away from normalization. Normalized elements
|
|
* always have a magnitude of 1, but a magnitude of 1 doesn't imply
|
|
* normality.
|
|
*/
|
|
|
|
#if defined HAVE_CONFIG_H
|
|
#include "libsecp256k1-config.h"
|
|
#endif
|
|
|
|
#if defined(USE_FIELD_10X26)
|
|
#include "field_10x26.h"
|
|
#elif defined(USE_FIELD_5X52)
|
|
#include "field_5x52.h"
|
|
#else
|
|
#error "Please select field implementation"
|
|
#endif
|
|
|
|
/** Normalize a field element. */
|
|
static void secp256k1_fe_normalize(secp256k1_fe_t *r);
|
|
|
|
/** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */
|
|
static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r);
|
|
|
|
/** Normalize a field element, without constant-time guarantee. */
|
|
static void secp256k1_fe_normalize_var(secp256k1_fe_t *r);
|
|
|
|
/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field
|
|
* implementation may optionally normalize the input, but this should not be relied upon. */
|
|
static int secp256k1_fe_normalizes_to_zero(secp256k1_fe_t *r);
|
|
|
|
/** Verify whether a field element represents zero i.e. would normalize to a zero value. The field
|
|
* implementation may optionally normalize the input, but this should not be relied upon. */
|
|
static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe_t *r);
|
|
|
|
/** Set a field element equal to a small integer. Resulting field element is normalized. */
|
|
static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a);
|
|
|
|
/** Verify whether a field element is zero. Requires the input to be normalized. */
|
|
static int secp256k1_fe_is_zero(const secp256k1_fe_t *a);
|
|
|
|
/** Check the "oddness" of a field element. Requires the input to be normalized. */
|
|
static int secp256k1_fe_is_odd(const secp256k1_fe_t *a);
|
|
|
|
/** Compare two field elements. Requires magnitude-1 inputs. */
|
|
static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
|
|
|
|
/** Compare two field elements. Requires both inputs to be normalized */
|
|
static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
|
|
|
|
/** Set a field element equal to 32-byte big endian value. If succesful, the resulting field element is normalized. */
|
|
static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a);
|
|
|
|
/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
|
|
static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a);
|
|
|
|
/** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input
|
|
* as an argument. The magnitude of the output is one higher. */
|
|
static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m);
|
|
|
|
/** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that
|
|
* small integer. */
|
|
static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a);
|
|
|
|
/** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */
|
|
static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a);
|
|
|
|
/** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8.
|
|
* The output magnitude is 1 (but not guaranteed to be normalized). */
|
|
static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b);
|
|
|
|
/** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8.
|
|
* The output magnitude is 1 (but not guaranteed to be normalized). */
|
|
static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a);
|
|
|
|
/** Sets a field element to be the (modular) square root (if any exist) of another. Requires the
|
|
* input's magnitude to be at most 8. The output magnitude is 1 (but not guaranteed to be
|
|
* normalized). Return value indicates whether a square root was found. */
|
|
static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a);
|
|
|
|
/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be
|
|
* at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */
|
|
static void secp256k1_fe_inv(secp256k1_fe_t *r, const secp256k1_fe_t *a);
|
|
|
|
/** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */
|
|
static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a);
|
|
|
|
/** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be
|
|
* at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and
|
|
* outputs must not overlap in memory. */
|
|
static void secp256k1_fe_inv_all_var(size_t len, secp256k1_fe_t *r, const secp256k1_fe_t *a);
|
|
|
|
/** Convert a field element to the storage type. */
|
|
static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t*);
|
|
|
|
/** Convert a field element back from the storage type. */
|
|
static void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t*);
|
|
|
|
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
|
|
static void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag);
|
|
|
|
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
|
|
static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag);
|
|
|
|
#endif
|