11#include < node.h>
22#include < nan.h>
33#include < secp256k1.h>
4- #include < util.h>
5- #include < field_impl.h>
6- #include < scalar_impl.h>
7- #include < group_impl.h>
8- #include < ecmult_const_impl.h>
9- #include < ecmult_gen_impl.h>
4+ #include < secp256k1_ecdh.h>
105
116#include " messages.h"
127#include " util.h"
138
149extern secp256k1_context* secp256k1ctx;
1510
16- // from bitcoin/secp256k1
17- #define ARG_CHECK (cond ) do { \
18- if (EXPECT (!(cond), 0 )) { \
19- secp256k1_callback_call (&ctx->illegal_callback , #cond); \
20- return 0 ; \
21- } \
22- } while (0 )
23-
24- static void default_illegal_callback_fn (const char * str, void * data) {
25- (void )data;
26- fprintf (stderr, " [libsecp256k1] illegal argument: %s\n " , str);
27- abort ();
28- }
29-
30- static const secp256k1_callback default_illegal_callback = {
31- default_illegal_callback_fn,
32- NULL
33- };
34-
35- static void default_error_callback_fn (const char * str, void * data) {
36- (void )data;
37- fprintf (stderr, " [libsecp256k1] internal consistency check failed: %s\n " , str);
38- abort ();
39- }
40-
41- static const secp256k1_callback default_error_callback = {
42- default_error_callback_fn,
43- NULL
44- };
45-
46- struct secp256k1_context_struct {
47- secp256k1_ecmult_context ecmult_ctx;
48- secp256k1_ecmult_gen_context ecmult_gen_ctx;
49- secp256k1_callback illegal_callback;
50- secp256k1_callback error_callback;
51- };
52-
53- int secp256k1_pubkey_load (const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) {
54- if (sizeof (secp256k1_ge_storage) == 64 ) {
55- /* When the secp256k1_ge_storage type is exactly 64 byte, use its
56- * representation inside secp256k1_pubkey, as conversion is very fast.
57- * Note that secp256k1_pubkey_save must use the same representation. */
58- secp256k1_ge_storage s;
59- memcpy (&s, &pubkey->data [0 ], 64 );
60- secp256k1_ge_from_storage (ge, &s);
61- } else {
62- /* Otherwise, fall back to 32-byte big endian for X and Y. */
63- secp256k1_fe x, y;
64- secp256k1_fe_set_b32 (&x, pubkey->data );
65- secp256k1_fe_set_b32 (&y, pubkey->data + 32 );
66- secp256k1_ge_set_xy (ge, &x, &y);
67- }
68- ARG_CHECK (!secp256k1_fe_is_zero (&ge->x ));
69- return 1 ;
70- }
71-
72- void secp256k1_pubkey_save (secp256k1_pubkey* pubkey, secp256k1_ge* ge) {
73- if (sizeof (secp256k1_ge_storage) == 64 ) {
74- secp256k1_ge_storage s;
75- secp256k1_ge_to_storage (&s, ge);
76- memcpy (&pubkey->data [0 ], &s, 64 );
77- } else {
78- VERIFY_CHECK (!secp256k1_ge_is_infinity (ge));
79- secp256k1_fe_normalize_var (&ge->x );
80- secp256k1_fe_normalize_var (&ge->y );
81- secp256k1_fe_get_b32 (pubkey->data , &ge->x );
82- secp256k1_fe_get_b32 (pubkey->data + 32 , &ge->y );
83- }
84- }
85-
86- // bindings
8711NAN_METHOD (ecdh) {
8812 Nan::HandleScope scope;
8913
@@ -103,40 +27,20 @@ NAN_METHOD(ecdh) {
10327 return Nan::ThrowError (EC_PUBLIC_KEY_PARSE_FAIL);
10428 }
10529
106- secp256k1_scalar s;
107- int overflow = 0 ;
108- secp256k1_scalar_set_b32 (&s, private_key, &overflow);
109- if (overflow || secp256k1_scalar_is_zero (&s)) {
110- secp256k1_scalar_clear (&s);
30+ unsigned char output[32 ];
31+ if (secp256k1_ecdh (secp256k1ctx, &output[0 ], &public_key, private_key, secp256k1_ecdh_hash_function_sha256, NULL ) == 0 ) {
11132 return Nan::ThrowError (ECDH_FAIL);
11233 }
11334
114- secp256k1_ge pt;
115- secp256k1_gej res;
116- unsigned char y[1 ];
117- unsigned char x[32 ];
118- secp256k1_sha256_t sha;
119- unsigned char output[32 ];
120-
121- secp256k1_pubkey_load (secp256k1ctx, &pt, &public_key);
122- secp256k1_ecmult_const (&res, &pt, &s);
123- secp256k1_scalar_clear (&s);
124-
125- secp256k1_ge_set_gej (&pt, &res);
126- secp256k1_fe_normalize (&pt.y );
127- secp256k1_fe_normalize (&pt.x );
128-
129- y[0 ] = 0x02 | secp256k1_fe_is_odd (&pt.y );
130- secp256k1_fe_get_b32 (&x[0 ], &pt.x );
131-
132- secp256k1_sha256_initialize (&sha);
133- secp256k1_sha256_write (&sha, y, sizeof (y));
134- secp256k1_sha256_write (&sha, x, sizeof (x));
135- secp256k1_sha256_finalize (&sha, &output[0 ]);
136-
13735 info.GetReturnValue ().Set (COPY_BUFFER (&output[0 ], 32 ));
13836}
13937
38+ int ecdh_hash_function_unsafe (unsigned char *output, const unsigned char *x, const unsigned char *y, void *data) {
39+ memcpy (output, x, 32 );
40+ memcpy (output + 32 , y, 32 );
41+ return 1 ;
42+ }
43+
14044NAN_METHOD (ecdhUnsafe) {
14145 Nan::HandleScope scope;
14246
@@ -159,26 +63,12 @@ NAN_METHOD(ecdhUnsafe) {
15963 unsigned int flags = SECP256K1_EC_COMPRESSED;
16064 UPDATE_COMPRESSED_VALUE (flags, info[2 ], SECP256K1_EC_COMPRESSED, SECP256K1_EC_UNCOMPRESSED);
16165
162- secp256k1_scalar s;
163- int overflow = 0 ;
164- secp256k1_scalar_set_b32 (&s, private_key, &overflow);
165- if (overflow || secp256k1_scalar_is_zero (&s)) {
166- secp256k1_scalar_clear (&s);
66+ if (secp256k1_ecdh (secp256k1ctx, &public_key.data [0 ], &public_key, private_key, ecdh_hash_function_unsafe, NULL ) == 0 ) {
16767 return Nan::ThrowError (ECDH_FAIL);
16868 }
16969
170- secp256k1_ge pt;
171- secp256k1_gej res;
17270 unsigned char output[65 ];
173- size_t output_length = 65 ;
174-
175- secp256k1_pubkey_load (secp256k1ctx, &pt, &public_key);
176- secp256k1_ecmult_const (&res, &pt, &s);
177- secp256k1_scalar_clear (&s);
178-
179- secp256k1_ge_set_gej (&pt, &res);
180- secp256k1_pubkey_save (&public_key, &pt);
181-
71+ size_t output_length = flags == SECP256K1_EC_COMPRESSED ? 33 : 65 ;
18272 secp256k1_ec_pubkey_serialize (secp256k1ctx, &output[0 ], &output_length, &public_key, flags);
18373 info.GetReturnValue ().Set (COPY_BUFFER (&output[0 ], output_length));
18474}
0 commit comments