github.com/ethereum/go-ethereum@v1.16.1/crypto/secp256k1/libsecp256k1/src/ecmult_gen.h (about)

     1  /***********************************************************************
     2   * Copyright (c) Pieter Wuille, Peter Dettman                          *
     3   * Distributed under the MIT software license, see the accompanying    *
     4   * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
     5   ***********************************************************************/
     6  
     7  #ifndef SECP256K1_ECMULT_GEN_H
     8  #define SECP256K1_ECMULT_GEN_H
     9  
    10  #include "scalar.h"
    11  #include "group.h"
    12  
    13  
    14  /* Configuration parameters for the signed-digit multi-comb algorithm:
    15   *
    16   * - COMB_BLOCKS is the number of blocks the input is split into. Each
    17   *   has a corresponding table.
    18   * - COMB_TEETH is the number of bits simultaneously covered by one table.
    19   * - COMB_RANGE is the number of bits in supported scalars. For production
    20   *   purposes, only 256 is reasonable, but smaller numbers are supported for
    21   *   exhaustive test mode.
    22   *
    23   * The comb's spacing (COMB_SPACING), or the distance between the teeth,
    24   * is defined as ceil(COMB_RANGE / (COMB_BLOCKS * COMB_TEETH)). Each block covers
    25   * COMB_SPACING * COMB_TEETH consecutive bits in the input.
    26   *
    27   * The size of the precomputed table is COMB_BLOCKS * (1 << (COMB_TEETH - 1))
    28   * secp256k1_ge_storages.
    29   *
    30   * The number of point additions equals COMB_BLOCKS * COMB_SPACING. Each point
    31   * addition involves a cmov from (1 << (COMB_TEETH - 1)) table entries and a
    32   * conditional negation.
    33   *
    34   * The number of point doublings is COMB_SPACING - 1. */
    35  
    36  #if defined(EXHAUSTIVE_TEST_ORDER)
    37  /* We need to control these values for exhaustive tests because
    38   * the table cannot have infinities in them (secp256k1_ge_storage
    39   * doesn't support infinities) */
    40  #  undef COMB_BLOCKS
    41  #  undef COMB_TEETH
    42  #  if EXHAUSTIVE_TEST_ORDER == 7
    43  #    define COMB_RANGE 3
    44  #    define COMB_BLOCKS 1
    45  #    define COMB_TEETH 2
    46  #  elif EXHAUSTIVE_TEST_ORDER == 13
    47  #    define COMB_RANGE 4
    48  #    define COMB_BLOCKS 1
    49  #    define COMB_TEETH 2
    50  #  elif EXHAUSTIVE_TEST_ORDER == 199
    51  #    define COMB_RANGE 8
    52  #    define COMB_BLOCKS 2
    53  #    define COMB_TEETH 3
    54  #  else
    55  #    error "Unknown exhaustive test order"
    56  #  endif
    57  #  if (COMB_RANGE >= 32) || ((EXHAUSTIVE_TEST_ORDER >> (COMB_RANGE - 1)) != 1)
    58  #    error "COMB_RANGE != ceil(log2(EXHAUSTIVE_TEST_ORDER+1))"
    59  #  endif
    60  #else /* !defined(EXHAUSTIVE_TEST_ORDER) */
    61  #  define COMB_RANGE 256
    62  #endif /* defined(EXHAUSTIVE_TEST_ORDER) */
    63  
    64  /* Use (11, 6) as default configuration, which results in a 22 kB table. */
    65  #ifndef COMB_BLOCKS
    66  #  define COMB_BLOCKS 11
    67  #  ifdef DEBUG_CONFIG
    68  #    pragma message DEBUG_CONFIG_MSG("COMB_BLOCKS undefined, assuming default value")
    69  #  endif
    70  #endif
    71  #ifndef COMB_TEETH
    72  #  define COMB_TEETH 6
    73  #  ifdef DEBUG_CONFIG
    74  #    pragma message DEBUG_CONFIG_MSG("COMB_TEETH undefined, assuming default value")
    75  #  endif
    76  #endif
    77  /* Use ceil(COMB_RANGE / (COMB_BLOCKS * COMB_TEETH)) as COMB_SPACING. */
    78  #define COMB_SPACING CEIL_DIV(COMB_RANGE, COMB_BLOCKS * COMB_TEETH)
    79  
    80  /* Range checks on the parameters. */
    81  
    82  /* The remaining COMB_* parameters are derived values, don't modify these. */
    83  /* - The number of bits covered by all the blocks; must be at least COMB_RANGE. */
    84  #define COMB_BITS (COMB_BLOCKS * COMB_TEETH * COMB_SPACING)
    85  /* - The number of entries per table. */
    86  #define COMB_POINTS (1 << (COMB_TEETH - 1))
    87  
    88  /* Sanity checks. */
    89  #if !(1 <= COMB_BLOCKS && COMB_BLOCKS <= 256)
    90  #  error "COMB_BLOCKS must be in the range [1, 256]"
    91  #endif
    92  #if !(1 <= COMB_TEETH && COMB_TEETH <= 8)
    93  #  error "COMB_TEETH must be in the range [1, 8]"
    94  #endif
    95  #if COMB_BITS < COMB_RANGE
    96  #  error "COMB_BLOCKS * COMB_TEETH * COMB_SPACING is too low"
    97  #endif
    98  
    99  /* These last 2 checks are not strictly required, but prevent gratuitously inefficient
   100   * configurations. Note that they compare with 256 rather than COMB_RANGE, so they do
   101   * permit somewhat excessive values for the exhaustive test case, where testing with
   102   * suboptimal parameters may be desirable. */
   103  #if (COMB_BLOCKS - 1) * COMB_TEETH * COMB_SPACING >= 256
   104  #  error "COMB_BLOCKS can be reduced"
   105  #endif
   106  #if COMB_BLOCKS * (COMB_TEETH - 1) * COMB_SPACING >= 256
   107  #  error "COMB_TEETH can be reduced"
   108  #endif
   109  
   110  #ifdef DEBUG_CONFIG
   111  #  pragma message DEBUG_CONFIG_DEF(COMB_RANGE)
   112  #  pragma message DEBUG_CONFIG_DEF(COMB_BLOCKS)
   113  #  pragma message DEBUG_CONFIG_DEF(COMB_TEETH)
   114  #  pragma message DEBUG_CONFIG_DEF(COMB_SPACING)
   115  #endif
   116  
   117  typedef struct {
   118      /* Whether the context has been built. */
   119      int built;
   120  
   121      /* Values chosen such that
   122       *
   123       *   n*G == comb(n + scalar_offset, G/2) + ge_offset.
   124       *
   125       * This expression lets us use scalar blinding and optimize the comb precomputation. See
   126       * ecmult_gen_impl.h for more details. */
   127      secp256k1_scalar scalar_offset;
   128      secp256k1_ge ge_offset;
   129  
   130      /* Factor used for projective blinding. This value is used to rescale the Z
   131       * coordinate of the first table lookup. */
   132      secp256k1_fe proj_blind;
   133  } secp256k1_ecmult_gen_context;
   134  
   135  static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx);
   136  static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx);
   137  
   138  /** Multiply with the generator: R = a*G */
   139  static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a);
   140  
   141  static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32);
   142  
   143  #endif /* SECP256K1_ECMULT_GEN_H */