Skip to content

Commit 85e224d

Browse files
committed
group: add ge_to_bytes and ge_from_bytes
1 parent 1988855 commit 85e224d

File tree

4 files changed

+50
-14
lines changed

4 files changed

+50
-14
lines changed

src/group.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ static void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_g
174174
/** Rescale a jacobian point by b which must be non-zero. Constant-time. */
175175
static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *b);
176176

177+
/** Convert a group element that is not infinity to a 64-byte array. The output
178+
* array is platform-dependent. */
179+
static void secp256k1_ge_to_bytes(unsigned char *buf, const secp256k1_ge *a);
180+
181+
/** Convert a 64-byte array into group element. This function assumes that the
182+
* provided buffer correctly encodes a group element. */
183+
static void secp256k1_ge_from_bytes(secp256k1_ge *r, const unsigned char *buf);
184+
177185
/** Determine if a point (which is assumed to be on the curve) is in the correct (sub)group of the curve.
178186
*
179187
* In normal mode, the used group is secp256k1, which has cofactor=1 meaning that every point on the curve is in the

src/group_impl.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#ifndef SECP256K1_GROUP_IMPL_H
88
#define SECP256K1_GROUP_IMPL_H
99

10+
#include <string.h>
11+
1012
#include "field.h"
1113
#include "group.h"
1214
#include "util.h"
@@ -941,4 +943,24 @@ static int secp256k1_ge_x_frac_on_curve_var(const secp256k1_fe *xn, const secp25
941943
return secp256k1_fe_is_square_var(&r);
942944
}
943945

946+
static void secp256k1_ge_to_bytes(unsigned char *buf, const secp256k1_ge *a) {
947+
secp256k1_ge_storage s;
948+
949+
/* We require that the secp256k1_ge_storage type is exactly 64 bytes.
950+
* This is formally not guaranteed by the C standard, but should hold on any
951+
* sane compiler in the real world. */
952+
STATIC_ASSERT(sizeof(secp256k1_ge_storage) == 64);
953+
VERIFY_CHECK(!secp256k1_ge_is_infinity(a));
954+
secp256k1_ge_to_storage(&s, a);
955+
memcpy(buf, &s, 64);
956+
}
957+
958+
static void secp256k1_ge_from_bytes(secp256k1_ge *r, const unsigned char *buf) {
959+
secp256k1_ge_storage s;
960+
961+
STATIC_ASSERT(sizeof(secp256k1_ge_storage) == 64);
962+
memcpy(&s, buf, 64);
963+
secp256k1_ge_from_storage(r, &s);
964+
}
965+
944966
#endif /* SECP256K1_GROUP_IMPL_H */

src/secp256k1.c

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -238,25 +238,13 @@ static SECP256K1_INLINE void secp256k1_declassify(const secp256k1_context* ctx,
238238
}
239239

240240
static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) {
241-
secp256k1_ge_storage s;
242-
243-
/* We require that the secp256k1_ge_storage type is exactly 64 bytes.
244-
* This is formally not guaranteed by the C standard, but should hold on any
245-
* sane compiler in the real world. */
246-
STATIC_ASSERT(sizeof(secp256k1_ge_storage) == 64);
247-
memcpy(&s, &pubkey->data[0], 64);
248-
secp256k1_ge_from_storage(ge, &s);
241+
secp256k1_ge_from_bytes(ge, pubkey->data);
249242
ARG_CHECK(!secp256k1_fe_is_zero(&ge->x));
250243
return 1;
251244
}
252245

253246
static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) {
254-
secp256k1_ge_storage s;
255-
256-
STATIC_ASSERT(sizeof(secp256k1_ge_storage) == 64);
257-
VERIFY_CHECK(!secp256k1_ge_is_infinity(ge));
258-
secp256k1_ge_to_storage(&s, ge);
259-
memcpy(&pubkey->data[0], &s, 64);
247+
secp256k1_ge_to_bytes(pubkey->data, ge);
260248
}
261249

262250
int secp256k1_ec_pubkey_parse(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, const unsigned char *input, size_t inputlen) {

src/tests.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3982,13 +3982,31 @@ static void test_add_neg_y_diff_x(void) {
39823982
CHECK(secp256k1_gej_eq_ge_var(&sumj, &res));
39833983
}
39843984

3985+
static void test_ge_bytes(void) {
3986+
int i;
3987+
3988+
for (i = 0; i < COUNT; i++) {
3989+
unsigned char buf[64];
3990+
secp256k1_ge p, q;
3991+
3992+
testutil_random_ge_test(&p);
3993+
3994+
if (!secp256k1_ge_is_infinity(&p)) {
3995+
secp256k1_ge_to_bytes(buf, &p);
3996+
secp256k1_ge_from_bytes(&q, buf);
3997+
CHECK(secp256k1_ge_eq_var(&p, &q));
3998+
}
3999+
}
4000+
}
4001+
39854002
static void run_ge(void) {
39864003
int i;
39874004
for (i = 0; i < COUNT * 32; i++) {
39884005
test_ge();
39894006
}
39904007
test_add_neg_y_diff_x();
39914008
test_intialized_inf();
4009+
test_ge_bytes();
39924010
}
39934011

39944012
static void test_gej_cmov(const secp256k1_gej *a, const secp256k1_gej *b) {

0 commit comments

Comments
 (0)