aboutsummaryrefslogtreecommitdiff
path: root/src/secp256k1/src/ecmult_gen.h
blob: 43dd10c38d70b79bb2842c616baa90ffddb4aaa4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/***********************************************************************
 * Copyright (c) Pieter Wuille, Peter Dettman                          *
 * Distributed under the MIT software license, see the accompanying    *
 * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
 ***********************************************************************/

#ifndef SECP256K1_ECMULT_GEN_H
#define SECP256K1_ECMULT_GEN_H

#include "scalar.h"
#include "group.h"


/* Configuration parameters for the signed-digit multi-comb algorithm:
 *
 * - COMB_BLOCKS is the number of blocks the input is split into. Each
 *   has a corresponding table.
 * - COMB_TEETH is the number of bits simultaneously covered by one table.
 * - COMB_RANGE is the number of bits in supported scalars. For production
 *   purposes, only 256 is reasonable, but smaller numbers are supported for
 *   exhaustive test mode.
 *
 * The comb's spacing (COMB_SPACING), or the distance between the teeth,
 * is defined as ceil(COMB_RANGE / (COMB_BLOCKS * COMB_TEETH)). Each block covers
 * COMB_SPACING * COMB_TEETH consecutive bits in the input.
 *
 * The size of the precomputed table is COMB_BLOCKS * (1 << (COMB_TEETH - 1))
 * secp256k1_ge_storages.
 *
 * The number of point additions equals COMB_BLOCKS * COMB_SPACING. Each point
 * addition involves a cmov from (1 << (COMB_TEETH - 1)) table entries and a
 * conditional negation.
 *
 * The number of point doublings is COMB_SPACING - 1. */

#if defined(EXHAUSTIVE_TEST_ORDER)
/* We need to control these values for exhaustive tests because
 * the table cannot have infinities in them (secp256k1_ge_storage
 * doesn't support infinities) */
#  undef COMB_BLOCKS
#  undef COMB_TEETH
#  if EXHAUSTIVE_TEST_ORDER == 7
#    define COMB_RANGE 3
#    define COMB_BLOCKS 1
#    define COMB_TEETH 2
#  elif EXHAUSTIVE_TEST_ORDER == 13
#    define COMB_RANGE 4
#    define COMB_BLOCKS 1
#    define COMB_TEETH 2
#  elif EXHAUSTIVE_TEST_ORDER == 199
#    define COMB_RANGE 8
#    define COMB_BLOCKS 2
#    define COMB_TEETH 3
#  else
#    error "Unknown exhaustive test order"
#  endif
#  if (COMB_RANGE >= 32) || ((EXHAUSTIVE_TEST_ORDER >> (COMB_RANGE - 1)) != 1)
#    error "COMB_RANGE != ceil(log2(EXHAUSTIVE_TEST_ORDER+1))"
#  endif
#else /* !defined(EXHAUSTIVE_TEST_ORDER) */
#  define COMB_RANGE 256
#endif /* defined(EXHAUSTIVE_TEST_ORDER) */

/* Use (11, 6) as default configuration, which results in a 22 kB table. */
#ifndef COMB_BLOCKS
#  define COMB_BLOCKS 11
#  ifdef DEBUG_CONFIG
#    pragma message DEBUG_CONFIG_MSG("COMB_BLOCKS undefined, assuming default value")
#  endif
#endif
#ifndef COMB_TEETH
#  define COMB_TEETH 6
#  ifdef DEBUG_CONFIG
#    pragma message DEBUG_CONFIG_MSG("COMB_TEETH undefined, assuming default value")
#  endif
#endif
/* Use ceil(COMB_RANGE / (COMB_BLOCKS * COMB_TEETH)) as COMB_SPACING. */
#define COMB_SPACING CEIL_DIV(COMB_RANGE, COMB_BLOCKS * COMB_TEETH)

/* Range checks on the parameters. */

/* The remaining COMB_* parameters are derived values, don't modify these. */
/* - The number of bits covered by all the blocks; must be at least COMB_RANGE. */
#define COMB_BITS (COMB_BLOCKS * COMB_TEETH * COMB_SPACING)
/* - The number of entries per table. */
#define COMB_POINTS (1 << (COMB_TEETH - 1))

/* Sanity checks. */
#if !(1 <= COMB_BLOCKS && COMB_BLOCKS <= 256)
#  error "COMB_BLOCKS must be in the range [1, 256]"
#endif
#if !(1 <= COMB_TEETH && COMB_TEETH <= 8)
#  error "COMB_TEETH must be in the range [1, 8]"
#endif
#if COMB_BITS < COMB_RANGE
#  error "COMB_BLOCKS * COMB_TEETH * COMB_SPACING is too low"
#endif

/* These last 2 checks are not strictly required, but prevent gratuitously inefficient
 * configurations. Note that they compare with 256 rather than COMB_RANGE, so they do
 * permit somewhat excessive values for the exhaustive test case, where testing with
 * suboptimal parameters may be desirable. */
#if (COMB_BLOCKS - 1) * COMB_TEETH * COMB_SPACING >= 256
#  error "COMB_BLOCKS can be reduced"
#endif
#if COMB_BLOCKS * (COMB_TEETH - 1) * COMB_SPACING >= 256
#  error "COMB_TEETH can be reduced"
#endif

#ifdef DEBUG_CONFIG
#  pragma message DEBUG_CONFIG_DEF(COMB_RANGE)
#  pragma message DEBUG_CONFIG_DEF(COMB_BLOCKS)
#  pragma message DEBUG_CONFIG_DEF(COMB_TEETH)
#  pragma message DEBUG_CONFIG_DEF(COMB_SPACING)
#endif

typedef struct {
    /* Whether the context has been built. */
    int built;

    /* Values chosen such that
     *
     *   n*G == comb(n + scalar_offset, G/2) + ge_offset.
     *
     * This expression lets us use scalar blinding and optimize the comb precomputation. See
     * ecmult_gen_impl.h for more details. */
    secp256k1_scalar scalar_offset;
    secp256k1_ge ge_offset;

    /* Factor used for projective blinding. This value is used to rescale the Z
     * coordinate of the first table lookup. */
    secp256k1_fe proj_blind;
} secp256k1_ecmult_gen_context;

static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx);
static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx);

/** Multiply with the generator: R = a*G */
static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a);

static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32);

#endif /* SECP256K1_ECMULT_GEN_H */