Skip to content

Commit fca4c3b

Browse files
apoelstrareal-or-random
authored andcommitted
generator: verify correctness of point when parsing
1 parent c50b218 commit fca4c3b

File tree

3 files changed

+41
-24
lines changed

3 files changed

+41
-24
lines changed

include/secp256k1_generator.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,12 @@ extern "C" {
1313
*
1414
* The exact representation of data inside is implementation defined and not
1515
* guaranteed to be portable between different platforms or versions. It is
16-
* however guaranteed to be 33 bytes in size, and can be safely copied/moved.
17-
* If you need to convert to a format suitable for storage or transmission, use
18-
* the secp256k1_generator_serialize_*.
19-
*
20-
* Furthermore, it is guaranteed to identical points will have identical
21-
* representation, so they can be memcmp'ed.
16+
* however guaranteed to be 64 bytes in size, and can be safely copied/moved.
17+
* If you need to convert to a format suitable for storage, transmission, or
18+
* comparison, use secp256k1_generator_serialize and secp256k1_generator_parse.
2219
*/
2320
typedef struct {
24-
unsigned char data[33];
21+
unsigned char data[64];
2522
} secp256k1_generator;
2623

2724
/** Parse a 33-byte generator byte sequence into a generator object.

src/modules/generator/main_impl.h

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,55 @@
1515
#include "scalar.h"
1616

1717
static void secp256k1_generator_load(secp256k1_ge* ge, const secp256k1_generator* gen) {
18-
secp256k1_fe fe;
19-
secp256k1_fe_set_b32(&fe, &gen->data[1]);
20-
secp256k1_ge_set_xquad(ge, &fe);
21-
if (gen->data[0] & 1) {
22-
secp256k1_ge_neg(ge, ge);
23-
}
18+
int succeed;
19+
succeed = secp256k1_fe_set_b32(&ge->x, &gen->data[0]);
20+
VERIFY_CHECK(succeed != 0);
21+
succeed = secp256k1_fe_set_b32(&ge->y, &gen->data[32]);
22+
VERIFY_CHECK(succeed != 0);
23+
ge->infinity = 0;
24+
(void) succeed;
2425
}
2526

26-
static void secp256k1_generator_save(secp256k1_generator* commit, secp256k1_ge* ge) {
27-
secp256k1_fe_normalize(&ge->x);
28-
secp256k1_fe_get_b32(&commit->data[1], &ge->x);
29-
commit->data[0] = 11 ^ secp256k1_fe_is_quad_var(&ge->y);
27+
static void secp256k1_generator_save(secp256k1_generator *gen, secp256k1_ge* ge) {
28+
VERIFY_CHECK(!secp256k1_ge_is_infinity(ge));
29+
secp256k1_fe_normalize_var(&ge->x);
30+
secp256k1_fe_normalize_var(&ge->y);
31+
secp256k1_fe_get_b32(&gen->data[0], &ge->x);
32+
secp256k1_fe_get_b32(&gen->data[32], &ge->y);
3033
}
3134

3235
int secp256k1_generator_parse(const secp256k1_context* ctx, secp256k1_generator* gen, const unsigned char *input) {
36+
secp256k1_fe x;
37+
secp256k1_ge ge;
38+
3339
VERIFY_CHECK(ctx != NULL);
3440
ARG_CHECK(gen != NULL);
3541
ARG_CHECK(input != NULL);
36-
if ((input[0] & 0xFE) != 10) {
42+
43+
if ((input[0] & 0xFE) != 10 ||
44+
!secp256k1_fe_set_b32(&x, &input[1]) ||
45+
!secp256k1_ge_set_xquad(&ge, &x)) {
3746
return 0;
3847
}
39-
memcpy(gen->data, input, sizeof(gen->data));
48+
if (input[0] & 1) {
49+
secp256k1_ge_neg(&ge, &ge);
50+
}
51+
secp256k1_generator_save(gen, &ge);
4052
return 1;
4153
}
4254

4355
int secp256k1_generator_serialize(const secp256k1_context* ctx, unsigned char *output, const secp256k1_generator* gen) {
56+
secp256k1_ge ge;
57+
4458
VERIFY_CHECK(ctx != NULL);
4559
ARG_CHECK(output != NULL);
4660
ARG_CHECK(gen != NULL);
47-
memcpy(output, gen->data, sizeof(gen->data));
61+
62+
secp256k1_generator_load(&ge, gen);
63+
64+
output[0] = 11 ^ secp256k1_fe_is_quad_var(&ge.y);
65+
secp256k1_fe_normalize_var(&ge.x);
66+
secp256k1_fe_get_b32(&output[1], &ge.x);
4867
return 1;
4968
}
5069

src/modules/rangeproof/main_impl.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@
1616
/** Alternative generator for secp256k1.
1717
* This is the sha256 of 'g' after DER encoding (without compression),
1818
* which happens to be a point on the curve.
19-
* sage: G2 = EllipticCurve ([F (0), F (7)]).lift_x(int(hashlib.sha256('0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'.decode('hex')).hexdigest(),16))
20-
* sage: '%x %x' % (11 - G2.xy()[1].is_square(), G2.xy()[0])
19+
* sage: G2 = EllipticCurve ([F (0), F (7)]).lift_x(F(int(hashlib.sha256('0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'.decode('hex')).hexdigest(),16)))
20+
* sage: '%x %x' % G2.xy()
2121
*/
2222
static const secp256k1_generator secp256k1_generator_h_internal = {{
23-
0x11,
2423
0x50, 0x92, 0x9b, 0x74, 0xc1, 0xa0, 0x49, 0x54, 0xb7, 0x8b, 0x4b, 0x60, 0x35, 0xe9, 0x7a, 0x5e,
25-
0x07, 0x8a, 0x5a, 0x0f, 0x28, 0xec, 0x96, 0xd5, 0x47, 0xbf, 0xee, 0x9a, 0xce, 0x80, 0x3a, 0xc0
24+
0x07, 0x8a, 0x5a, 0x0f, 0x28, 0xec, 0x96, 0xd5, 0x47, 0xbf, 0xee, 0x9a, 0xce, 0x80, 0x3a, 0xc0,
25+
0x31, 0xd3, 0xc6, 0x86, 0x39, 0x73, 0x92, 0x6e, 0x04, 0x9e, 0x63, 0x7c, 0xb1, 0xb5, 0xf4, 0x0a,
26+
0x36, 0xda, 0xc2, 0x8a, 0xf1, 0x76, 0x69, 0x68, 0xc3, 0x0c, 0x23, 0x13, 0xf3, 0xa3, 0x89, 0x04
2627
}};
2728

2829
const secp256k1_generator *secp256k1_generator_h = &secp256k1_generator_h_internal;

0 commit comments

Comments
 (0)