-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Signed-digit multi-comb for ecmult_gen #546
Changes from 1 commit
75d9e97
09ca146
e8beef9
183a7ff
e848342
4c8ff9b
9156619
91179c1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,68 @@ | |
#include "scalar.h" | ||
#include "group.h" | ||
|
||
#ifndef USE_ECMULT_STATIC_PRECOMPUTATION | ||
#define USE_COMB 1 | ||
#endif | ||
|
||
#if USE_COMB | ||
|
||
#if defined(EXHAUSTIVE_TEST_ORDER) | ||
|
||
/* We need to control these values for exhaustive tests because | ||
* the tables cannot have infinities in them (secp256k1_ge_storage | ||
* doesn't support infinities) */ | ||
# if EXHAUSTIVE_TEST_ORDER > 32 | ||
# define COMB_BLOCKS 52 | ||
# define COMB_TEETH 5 | ||
# elif EXHAUSTIVE_TEST_ORDER > 16 | ||
# define COMB_BLOCKS 64 | ||
# define COMB_TEETH 4 | ||
# elif EXHAUSTIVE_TEST_ORDER > 8 | ||
# define COMB_BLOCKS 86 | ||
# define COMB_TEETH 3 | ||
# elif EXHAUSTIVE_TEST_ORDER > 4 | ||
# define COMB_BLOCKS 128 | ||
# define COMB_TEETH 2 | ||
# else | ||
# define COMB_BLOCKS 256 | ||
# define COMB_TEETH 1 | ||
# endif | ||
|
||
# define COMB_SPACING 1 | ||
|
||
#else | ||
|
||
/* COMB_BLOCKS, COMB_TEETH, COMB_SPACING must all be positive and the product of the three (COMB_BITS) | ||
* must evaluate to a value in the range [256, 288]. The resulting memory usage for precomputation | ||
* will be COMB_POINTS_TOTAL * sizeof(secp256k1_ge_storage). */ | ||
#define COMB_BLOCKS 4 | ||
#define COMB_TEETH 5 | ||
#define COMB_SPACING 13 | ||
|
||
#endif | ||
|
||
/* The remaining COMB_* parameters are derived values, don't modify these. */ | ||
#define COMB_BITS (COMB_BLOCKS * COMB_TEETH * COMB_SPACING) | ||
#define COMB_GROUPED ((COMB_SPACING == 1) && ((32 % COMB_TEETH) == 0)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should drop There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In fact, once Given that this is a ridiculous thing to do I don't think we should try to support it, e.g. by using heap allocations rather than stack allocations in gen_context_build. We should just assume it doesn't happen and drop There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume you are misreading 32%T, which is 0 when T is a small power of 2. Still, practical values of COMB_TEETH probably peak at 8, and there is the stack concern as you say, so we should probably have the precompiler constrain it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right, I misread There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 4c8ff9b adds precompiler guards on the comb constants. |
||
#define COMB_OFFSET (COMB_BITS == 256) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add some documentation somewhere about what the offset does? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done: e8beef9 . There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great, thanks! |
||
#define COMB_POINTS (1 << (COMB_TEETH - 1)) | ||
#define COMB_POINTS_TOTAL (COMB_BLOCKS * COMB_POINTS) | ||
#define COMB_MASK (COMB_POINTS - 1) | ||
|
||
#endif | ||
|
||
typedef struct { | ||
#if USE_COMB | ||
/* Precomputation data for the signed-digit multi-comb algorithm as described in section 3.3 of: | ||
* "Fast and compact elliptic-curve cryptography", Mike Hamburg | ||
* (https://eprint.iacr.org/2012/309) | ||
*/ | ||
secp256k1_ge_storage (*prec)[COMB_BLOCKS][COMB_POINTS]; | ||
#if COMB_OFFSET | ||
secp256k1_ge offset; | ||
#endif | ||
#else | ||
/* For accelerating the computation of a*G: | ||
* To harden against timing attacks, use the following mechanism: | ||
* * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63. | ||
|
@@ -24,6 +85,7 @@ typedef struct { | |
* the intermediate sums while computing a*G. | ||
*/ | ||
secp256k1_ge_storage (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ | ||
#endif | ||
secp256k1_scalar blind; | ||
secp256k1_gej initial; | ||
} secp256k1_ecmult_gen_context; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should comment that
COMB_SPACING
should not exceed 32 or else thebit_pos
logic insecp256k1_ecmult_gen
stops working.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t see why, and all cases in the table above passed the tests before benchmarking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I think I forgot to
make clean
after recompiling again. The tests do pass now.But my reasoning was that you're only looking at one word of
recoded
at once, so if thebit_pos
index jumps forward by more than one word, eventuallybit_pos >> 5
will increment by more than one per iteration and you'll have skipped an entire word. But I'm re-reading the code with fresher eyes and now I see that this is exactly the intended behaviour.