@qntx/nostr-native 0.0.0-stage → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/LICENSE-APACHE +201 -0
  2. package/LICENSE-MIT +21 -0
  3. package/NostrNative.podspec +37 -0
  4. package/README.md +30 -2
  5. package/android/CMakeLists.txt +38 -0
  6. package/android/build.gradle +136 -0
  7. package/android/gradle.properties +4 -0
  8. package/android/src/main/AndroidManifest.xml +2 -0
  9. package/android/src/main/cpp/cpp-adapter.cpp +7 -0
  10. package/android/src/main/java/com/margelo/nitro/nostrnative/NostrNativePackage.java +29 -0
  11. package/cpp/HybridNostrNative.cpp +52 -0
  12. package/cpp/HybridNostrNative.hpp +22 -0
  13. package/cpp/nostr_core.c +128 -0
  14. package/cpp/nostr_core.h +65 -0
  15. package/cpp/nostr_native.c +54 -0
  16. package/cpp/nostr_native.h +47 -0
  17. package/dist/index.d.mts +15 -0
  18. package/dist/index.mjs +26 -0
  19. package/dist/index.mjs.map +1 -0
  20. package/nitro.json +19 -0
  21. package/nitrogen/generated/.gitattributes +1 -0
  22. package/nitrogen/generated/android/NostrNative+autolinking.cmake +81 -0
  23. package/nitrogen/generated/android/NostrNative+autolinking.gradle +27 -0
  24. package/nitrogen/generated/android/NostrNativeOnLoad.cpp +49 -0
  25. package/nitrogen/generated/android/NostrNativeOnLoad.hpp +34 -0
  26. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nostrnative/NostrNativeOnLoad.kt +35 -0
  27. package/nitrogen/generated/ios/NostrNative+autolinking.rb +62 -0
  28. package/nitrogen/generated/ios/NostrNative-Swift-Cxx-Bridge.cpp +17 -0
  29. package/nitrogen/generated/ios/NostrNative-Swift-Cxx-Bridge.hpp +27 -0
  30. package/nitrogen/generated/ios/NostrNative-Swift-Cxx-Umbrella.hpp +38 -0
  31. package/nitrogen/generated/ios/NostrNativeAutolinking.mm +35 -0
  32. package/nitrogen/generated/ios/NostrNativeAutolinking.swift +16 -0
  33. package/nitrogen/generated/shared/c++/HybridNostrNativeSpec.cpp +23 -0
  34. package/nitrogen/generated/shared/c++/HybridNostrNativeSpec.hpp +64 -0
  35. package/package.json +86 -4
  36. package/react-native.config.js +12 -0
  37. package/vendor/secp256k1/COPYING +19 -0
  38. package/vendor/secp256k1/include/secp256k1.h +931 -0
  39. package/vendor/secp256k1/include/secp256k1_ecdh.h +63 -0
  40. package/vendor/secp256k1/include/secp256k1_ellswift.h +200 -0
  41. package/vendor/secp256k1/include/secp256k1_extrakeys.h +250 -0
  42. package/vendor/secp256k1/include/secp256k1_musig.h +588 -0
  43. package/vendor/secp256k1/include/secp256k1_preallocated.h +134 -0
  44. package/vendor/secp256k1/include/secp256k1_recovery.h +123 -0
  45. package/vendor/secp256k1/include/secp256k1_schnorrsig.h +179 -0
  46. package/vendor/secp256k1/include/secp256k1_silentpayments.h +396 -0
  47. package/vendor/secp256k1/src/assumptions.h +87 -0
  48. package/vendor/secp256k1/src/checkmem.h +117 -0
  49. package/vendor/secp256k1/src/ecdsa.h +21 -0
  50. package/vendor/secp256k1/src/ecdsa_impl.h +309 -0
  51. package/vendor/secp256k1/src/eckey.h +28 -0
  52. package/vendor/secp256k1/src/eckey_impl.h +94 -0
  53. package/vendor/secp256k1/src/ecmult.h +64 -0
  54. package/vendor/secp256k1/src/ecmult_compute_table.h +16 -0
  55. package/vendor/secp256k1/src/ecmult_compute_table_impl.h +49 -0
  56. package/vendor/secp256k1/src/ecmult_const.h +38 -0
  57. package/vendor/secp256k1/src/ecmult_const_impl.h +402 -0
  58. package/vendor/secp256k1/src/ecmult_gen.h +145 -0
  59. package/vendor/secp256k1/src/ecmult_gen_compute_table.h +14 -0
  60. package/vendor/secp256k1/src/ecmult_gen_compute_table_impl.h +108 -0
  61. package/vendor/secp256k1/src/ecmult_gen_impl.h +347 -0
  62. package/vendor/secp256k1/src/ecmult_impl.h +869 -0
  63. package/vendor/secp256k1/src/field.h +351 -0
  64. package/vendor/secp256k1/src/field_10x26.h +57 -0
  65. package/vendor/secp256k1/src/field_10x26_impl.h +1210 -0
  66. package/vendor/secp256k1/src/field_5x52.h +62 -0
  67. package/vendor/secp256k1/src/field_5x52_impl.h +496 -0
  68. package/vendor/secp256k1/src/field_5x52_int128_impl.h +274 -0
  69. package/vendor/secp256k1/src/field_impl.h +457 -0
  70. package/vendor/secp256k1/src/group.h +218 -0
  71. package/vendor/secp256k1/src/group_impl.h +1014 -0
  72. package/vendor/secp256k1/src/hash.h +56 -0
  73. package/vendor/secp256k1/src/hash_impl.h +397 -0
  74. package/vendor/secp256k1/src/hsort.h +33 -0
  75. package/vendor/secp256k1/src/hsort_impl.h +125 -0
  76. package/vendor/secp256k1/src/int128.h +90 -0
  77. package/vendor/secp256k1/src/int128_impl.h +18 -0
  78. package/vendor/secp256k1/src/int128_native.h +19 -0
  79. package/vendor/secp256k1/src/int128_native_impl.h +94 -0
  80. package/vendor/secp256k1/src/int128_struct.h +14 -0
  81. package/vendor/secp256k1/src/int128_struct_impl.h +205 -0
  82. package/vendor/secp256k1/src/modinv32.h +43 -0
  83. package/vendor/secp256k1/src/modinv32_impl.h +725 -0
  84. package/vendor/secp256k1/src/modinv64.h +47 -0
  85. package/vendor/secp256k1/src/modinv64_impl.h +780 -0
  86. package/vendor/secp256k1/src/modules/extrakeys/main_impl.h +292 -0
  87. package/vendor/secp256k1/src/modules/schnorrsig/main_impl.h +256 -0
  88. package/vendor/secp256k1/src/precomputed_ecmult.c +16456 -0
  89. package/vendor/secp256k1/src/precomputed_ecmult.h +40 -0
  90. package/vendor/secp256k1/src/precomputed_ecmult_gen.c +1779 -0
  91. package/vendor/secp256k1/src/precomputed_ecmult_gen.h +28 -0
  92. package/vendor/secp256k1/src/scalar.h +105 -0
  93. package/vendor/secp256k1/src/scalar_4x64.h +19 -0
  94. package/vendor/secp256k1/src/scalar_4x64_impl.h +1005 -0
  95. package/vendor/secp256k1/src/scalar_8x32.h +19 -0
  96. package/vendor/secp256k1/src/scalar_8x32_impl.h +820 -0
  97. package/vendor/secp256k1/src/scalar_impl.h +321 -0
  98. package/vendor/secp256k1/src/scalar_low.h +24 -0
  99. package/vendor/secp256k1/src/scalar_low_impl.h +217 -0
  100. package/vendor/secp256k1/src/scratch.h +44 -0
  101. package/vendor/secp256k1/src/scratch_impl.h +99 -0
  102. package/vendor/secp256k1/src/secp256k1.c +855 -0
  103. package/vendor/secp256k1/src/selftest.h +41 -0
  104. package/vendor/secp256k1/src/util.h +479 -0
  105. package/vendor/secp256k1/src/util_local_visibility.h +12 -0
  106. package/vendor/secp256k1/vendored.json +6 -0
@@ -0,0 +1,292 @@
1
+ /***********************************************************************
2
+ * Copyright (c) 2020 Jonas Nick *
3
+ * Distributed under the MIT software license, see the accompanying *
4
+ * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5
+ ***********************************************************************/
6
+
7
+ #ifndef SECP256K1_MODULE_EXTRAKEYS_MAIN_H
8
+ #define SECP256K1_MODULE_EXTRAKEYS_MAIN_H
9
+
10
+ #include "../../../include/secp256k1.h"
11
+ #include "../../../include/secp256k1_extrakeys.h"
12
+ #include "../../util.h"
13
+
14
+ static SECP256K1_INLINE int nostr_native_secp256k1_xonly_pubkey_load(const nostr_native_secp256k1_context* ctx, nostr_native_secp256k1_ge *ge, const nostr_native_secp256k1_xonly_pubkey *pubkey) {
15
+ return nostr_native_secp256k1_pubkey_load(ctx, ge, (const nostr_native_secp256k1_pubkey *) pubkey);
16
+ }
17
+
18
+ static SECP256K1_INLINE void nostr_native_secp256k1_xonly_pubkey_save(nostr_native_secp256k1_xonly_pubkey *pubkey, nostr_native_secp256k1_ge *ge) {
19
+ #ifdef VERIFY
20
+ /* ensure that the group element's Y coordinate is even, as per definition of x-only public keys */
21
+ nostr_native_secp256k1_fe y = ge->y;
22
+ nostr_native_secp256k1_fe_normalize_var(&y);
23
+ VERIFY_CHECK(!nostr_native_secp256k1_fe_is_odd(&y));
24
+ #endif
25
+
26
+ nostr_native_secp256k1_pubkey_save((nostr_native_secp256k1_pubkey *) pubkey, ge);
27
+ }
28
+
29
+ int nostr_native_secp256k1_xonly_pubkey_parse(const nostr_native_secp256k1_context* ctx, nostr_native_secp256k1_xonly_pubkey *pubkey, const unsigned char *input32) {
30
+ nostr_native_secp256k1_ge pk;
31
+ nostr_native_secp256k1_fe x;
32
+
33
+ VERIFY_CHECK(ctx != NULL);
34
+ ARG_CHECK(pubkey != NULL);
35
+ memset(pubkey, 0, sizeof(*pubkey));
36
+ ARG_CHECK(input32 != NULL);
37
+
38
+ if (!nostr_native_secp256k1_fe_set_b32_limit(&x, input32)) {
39
+ return 0;
40
+ }
41
+ if (!nostr_native_secp256k1_ge_set_xo_var(&pk, &x, 0)) {
42
+ return 0;
43
+ }
44
+ if (!nostr_native_secp256k1_ge_is_in_correct_subgroup(&pk)) {
45
+ return 0;
46
+ }
47
+ nostr_native_secp256k1_xonly_pubkey_save(pubkey, &pk);
48
+ return 1;
49
+ }
50
+
51
+ int nostr_native_secp256k1_xonly_pubkey_serialize(const nostr_native_secp256k1_context* ctx, unsigned char *output32, const nostr_native_secp256k1_xonly_pubkey *pubkey) {
52
+ nostr_native_secp256k1_ge pk;
53
+
54
+ VERIFY_CHECK(ctx != NULL);
55
+ ARG_CHECK(output32 != NULL);
56
+ memset(output32, 0, 32);
57
+ ARG_CHECK(pubkey != NULL);
58
+
59
+ if (!nostr_native_secp256k1_xonly_pubkey_load(ctx, &pk, pubkey)) {
60
+ return 0;
61
+ }
62
+ nostr_native_secp256k1_fe_get_b32(output32, &pk.x);
63
+ return 1;
64
+ }
65
+
66
+ int nostr_native_secp256k1_xonly_pubkey_cmp(const nostr_native_secp256k1_context* ctx, const nostr_native_secp256k1_xonly_pubkey* pk0, const nostr_native_secp256k1_xonly_pubkey* pk1) {
67
+ unsigned char out[2][32];
68
+ const nostr_native_secp256k1_xonly_pubkey* pk[2];
69
+ int i;
70
+
71
+ VERIFY_CHECK(ctx != NULL);
72
+ pk[0] = pk0; pk[1] = pk1;
73
+ for (i = 0; i < 2; i++) {
74
+ /* If the public key is NULL or invalid, xonly_pubkey_serialize will
75
+ * call the illegal_callback and return 0. In that case we will
76
+ * serialize the key as all zeros which is less than any valid public
77
+ * key. This results in consistent comparisons even if NULL or invalid
78
+ * pubkeys are involved and prevents edge cases such as sorting
79
+ * algorithms that use this function and do not terminate as a
80
+ * result. */
81
+ if (!nostr_native_secp256k1_xonly_pubkey_serialize(ctx, out[i], pk[i])) {
82
+ /* Note that xonly_pubkey_serialize should already set the output to
83
+ * zero in that case, but it's not guaranteed by the API, we can't
84
+ * test it and writing a VERIFY_CHECK is more complex than
85
+ * explicitly memsetting (again). */
86
+ memset(out[i], 0, sizeof(out[i]));
87
+ }
88
+ }
89
+ return nostr_native_secp256k1_memcmp_var(out[0], out[1], sizeof(out[1]));
90
+ }
91
+
92
+ /** Keeps a group element as is if it has an even Y and otherwise negates it.
93
+ * y_parity is set to 0 in the former case and to 1 in the latter case.
94
+ * Requires that the coordinates of r are normalized. */
95
+ static int nostr_native_secp256k1_extrakeys_ge_even_y(nostr_native_secp256k1_ge *r) {
96
+ int y_parity = 0;
97
+ VERIFY_CHECK(!nostr_native_secp256k1_ge_is_infinity(r));
98
+
99
+ if (nostr_native_secp256k1_fe_is_odd(&r->y)) {
100
+ nostr_native_secp256k1_fe_negate(&r->y, &r->y, 1);
101
+ y_parity = 1;
102
+ }
103
+ return y_parity;
104
+ }
105
+
106
+ int nostr_native_secp256k1_xonly_pubkey_from_pubkey(const nostr_native_secp256k1_context* ctx, nostr_native_secp256k1_xonly_pubkey *xonly_pubkey, int *pk_parity, const nostr_native_secp256k1_pubkey *pubkey) {
107
+ nostr_native_secp256k1_ge pk;
108
+ int tmp;
109
+
110
+ VERIFY_CHECK(ctx != NULL);
111
+ ARG_CHECK(xonly_pubkey != NULL);
112
+ ARG_CHECK(pubkey != NULL);
113
+
114
+ if (!nostr_native_secp256k1_pubkey_load(ctx, &pk, pubkey)) {
115
+ return 0;
116
+ }
117
+ tmp = nostr_native_secp256k1_extrakeys_ge_even_y(&pk);
118
+ if (pk_parity != NULL) {
119
+ *pk_parity = tmp;
120
+ }
121
+ nostr_native_secp256k1_xonly_pubkey_save(xonly_pubkey, &pk);
122
+ return 1;
123
+ }
124
+
125
+ int nostr_native_secp256k1_xonly_pubkey_tweak_add(const nostr_native_secp256k1_context* ctx, nostr_native_secp256k1_pubkey *output_pubkey, const nostr_native_secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) {
126
+ nostr_native_secp256k1_ge pk;
127
+
128
+ VERIFY_CHECK(ctx != NULL);
129
+ ARG_CHECK(output_pubkey != NULL);
130
+ memset(output_pubkey, 0, sizeof(*output_pubkey));
131
+ ARG_CHECK(internal_pubkey != NULL);
132
+ ARG_CHECK(tweak32 != NULL);
133
+
134
+ if (!nostr_native_secp256k1_xonly_pubkey_load(ctx, &pk, internal_pubkey)
135
+ || !nostr_native_secp256k1_ec_pubkey_tweak_add_helper(&pk, tweak32)) {
136
+ return 0;
137
+ }
138
+ nostr_native_secp256k1_pubkey_save(output_pubkey, &pk);
139
+ return 1;
140
+ }
141
+
142
+ int nostr_native_secp256k1_xonly_pubkey_tweak_add_check(const nostr_native_secp256k1_context* ctx, const unsigned char *tweaked_pubkey32, int tweaked_pk_parity, const nostr_native_secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) {
143
+ nostr_native_secp256k1_ge pk;
144
+ unsigned char pk_expected32[32];
145
+
146
+ VERIFY_CHECK(ctx != NULL);
147
+ ARG_CHECK(internal_pubkey != NULL);
148
+ ARG_CHECK(tweaked_pubkey32 != NULL);
149
+ ARG_CHECK(tweak32 != NULL);
150
+
151
+ if (!nostr_native_secp256k1_xonly_pubkey_load(ctx, &pk, internal_pubkey)
152
+ || !nostr_native_secp256k1_ec_pubkey_tweak_add_helper(&pk, tweak32)) {
153
+ return 0;
154
+ }
155
+ nostr_native_secp256k1_fe_normalize_var(&pk.x);
156
+ nostr_native_secp256k1_fe_normalize_var(&pk.y);
157
+ nostr_native_secp256k1_fe_get_b32(pk_expected32, &pk.x);
158
+
159
+ return nostr_native_secp256k1_memcmp_var(&pk_expected32, tweaked_pubkey32, 32) == 0
160
+ && nostr_native_secp256k1_fe_is_odd(&pk.y) == tweaked_pk_parity;
161
+ }
162
+
163
+ static void nostr_native_secp256k1_keypair_save(nostr_native_secp256k1_keypair *keypair, const nostr_native_secp256k1_scalar *sk, nostr_native_secp256k1_ge *pk) {
164
+ nostr_native_secp256k1_scalar_get_b32(&keypair->data[0], sk);
165
+ nostr_native_secp256k1_pubkey_save((nostr_native_secp256k1_pubkey *)&keypair->data[32], pk);
166
+ }
167
+
168
+
169
+ static int nostr_native_secp256k1_keypair_seckey_load(const nostr_native_secp256k1_context* ctx, nostr_native_secp256k1_scalar *sk, const nostr_native_secp256k1_keypair *keypair) {
170
+ int ret;
171
+
172
+ ret = nostr_native_secp256k1_scalar_set_b32_seckey(sk, &keypair->data[0]);
173
+ /* We can declassify ret here because sk is only zero if a keypair function
174
+ * failed (which zeroes the keypair) and its return value is ignored. */
175
+ nostr_native_secp256k1_declassify(ctx, &ret, sizeof(ret));
176
+ ARG_CHECK(ret);
177
+ return ret;
178
+ }
179
+
180
+ /* Load a keypair into pk and sk (if non-NULL). This function declassifies pk
181
+ * and ARG_CHECKs that the keypair is not invalid. It always initializes sk and
182
+ * pk with dummy values. */
183
+ static int nostr_native_secp256k1_keypair_load(const nostr_native_secp256k1_context* ctx, nostr_native_secp256k1_scalar *sk, nostr_native_secp256k1_ge *pk, const nostr_native_secp256k1_keypair *keypair) {
184
+ int ret;
185
+ const nostr_native_secp256k1_pubkey *pubkey = (const nostr_native_secp256k1_pubkey *)&keypair->data[32];
186
+
187
+ /* Need to declassify the pubkey because pubkey_load ARG_CHECKs if it's
188
+ * invalid. */
189
+ nostr_native_secp256k1_declassify(ctx, pubkey, sizeof(*pubkey));
190
+ ret = nostr_native_secp256k1_pubkey_load(ctx, pk, pubkey);
191
+ if (sk != NULL) {
192
+ ret = ret && nostr_native_secp256k1_keypair_seckey_load(ctx, sk, keypair);
193
+ }
194
+ if (!ret) {
195
+ *pk = nostr_native_secp256k1_ge_const_g;
196
+ if (sk != NULL) {
197
+ *sk = nostr_native_secp256k1_scalar_one;
198
+ }
199
+ }
200
+ return ret;
201
+ }
202
+
203
+ int nostr_native_secp256k1_keypair_create(const nostr_native_secp256k1_context* ctx, nostr_native_secp256k1_keypair *keypair, const unsigned char *seckey32) {
204
+ nostr_native_secp256k1_scalar sk;
205
+ nostr_native_secp256k1_ge pk;
206
+ int ret = 0;
207
+ VERIFY_CHECK(ctx != NULL);
208
+ ARG_CHECK(keypair != NULL);
209
+ memset(keypair, 0, sizeof(*keypair));
210
+ ARG_CHECK(nostr_native_secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
211
+ ARG_CHECK(seckey32 != NULL);
212
+
213
+ ret = nostr_native_secp256k1_ec_pubkey_create_helper(&ctx->ecmult_gen_ctx, &sk, &pk, seckey32);
214
+ nostr_native_secp256k1_keypair_save(keypair, &sk, &pk);
215
+ nostr_native_secp256k1_memczero(keypair, sizeof(*keypair), !ret);
216
+
217
+ nostr_native_secp256k1_scalar_clear(&sk);
218
+ return ret;
219
+ }
220
+
221
+ int nostr_native_secp256k1_keypair_sec(const nostr_native_secp256k1_context* ctx, unsigned char *seckey, const nostr_native_secp256k1_keypair *keypair) {
222
+ VERIFY_CHECK(ctx != NULL);
223
+ ARG_CHECK(seckey != NULL);
224
+ memset(seckey, 0, 32);
225
+ ARG_CHECK(keypair != NULL);
226
+
227
+ memcpy(seckey, &keypair->data[0], 32);
228
+ return 1;
229
+ }
230
+
231
+ int nostr_native_secp256k1_keypair_pub(const nostr_native_secp256k1_context* ctx, nostr_native_secp256k1_pubkey *pubkey, const nostr_native_secp256k1_keypair *keypair) {
232
+ VERIFY_CHECK(ctx != NULL);
233
+ ARG_CHECK(pubkey != NULL);
234
+ memset(pubkey, 0, sizeof(*pubkey));
235
+ ARG_CHECK(keypair != NULL);
236
+
237
+ memcpy(pubkey->data, &keypair->data[32], sizeof(*pubkey));
238
+ return 1;
239
+ }
240
+
241
+ int nostr_native_secp256k1_keypair_xonly_pub(const nostr_native_secp256k1_context* ctx, nostr_native_secp256k1_xonly_pubkey *pubkey, int *pk_parity, const nostr_native_secp256k1_keypair *keypair) {
242
+ nostr_native_secp256k1_ge pk;
243
+ int tmp;
244
+
245
+ VERIFY_CHECK(ctx != NULL);
246
+ ARG_CHECK(pubkey != NULL);
247
+ memset(pubkey, 0, sizeof(*pubkey));
248
+ ARG_CHECK(keypair != NULL);
249
+
250
+ if (!nostr_native_secp256k1_keypair_load(ctx, NULL, &pk, keypair)) {
251
+ return 0;
252
+ }
253
+ tmp = nostr_native_secp256k1_extrakeys_ge_even_y(&pk);
254
+ if (pk_parity != NULL) {
255
+ *pk_parity = tmp;
256
+ }
257
+ nostr_native_secp256k1_xonly_pubkey_save(pubkey, &pk);
258
+
259
+ return 1;
260
+ }
261
+
262
+ int nostr_native_secp256k1_keypair_xonly_tweak_add(const nostr_native_secp256k1_context* ctx, nostr_native_secp256k1_keypair *keypair, const unsigned char *tweak32) {
263
+ nostr_native_secp256k1_ge pk;
264
+ nostr_native_secp256k1_scalar sk;
265
+ int y_parity;
266
+ int ret;
267
+
268
+ VERIFY_CHECK(ctx != NULL);
269
+ ARG_CHECK(keypair != NULL);
270
+ ARG_CHECK(tweak32 != NULL);
271
+
272
+ ret = nostr_native_secp256k1_keypair_load(ctx, &sk, &pk, keypair);
273
+ memset(keypair, 0, sizeof(*keypair));
274
+
275
+ y_parity = nostr_native_secp256k1_extrakeys_ge_even_y(&pk);
276
+ if (y_parity == 1) {
277
+ nostr_native_secp256k1_scalar_negate(&sk, &sk);
278
+ }
279
+
280
+ ret &= nostr_native_secp256k1_ec_seckey_tweak_add_helper(&sk, tweak32);
281
+ ret &= nostr_native_secp256k1_ec_pubkey_tweak_add_helper(&pk, tweak32);
282
+
283
+ nostr_native_secp256k1_declassify(ctx, &ret, sizeof(ret));
284
+ if (ret) {
285
+ nostr_native_secp256k1_keypair_save(keypair, &sk, &pk);
286
+ }
287
+
288
+ nostr_native_secp256k1_scalar_clear(&sk);
289
+ return ret;
290
+ }
291
+
292
+ #endif
@@ -0,0 +1,256 @@
1
+ /***********************************************************************
2
+ * Copyright (c) 2018-2020 Andrew Poelstra, Jonas Nick *
3
+ * Distributed under the MIT software license, see the accompanying *
4
+ * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5
+ ***********************************************************************/
6
+
7
+ #ifndef SECP256K1_MODULE_SCHNORRSIG_MAIN_H
8
+ #define SECP256K1_MODULE_SCHNORRSIG_MAIN_H
9
+
10
+ #include "../../../include/secp256k1.h"
11
+ #include "../../../include/secp256k1_schnorrsig.h"
12
+ #include "../../hash.h"
13
+
14
+ /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
15
+ * SHA256 to SHA256("BIP0340/nonce")||SHA256("BIP0340/nonce"). */
16
+ static void nostr_native_secp256k1_nonce_function_bip340_sha256_tagged(nostr_native_secp256k1_sha256 *sha) {
17
+ static const uint32_t midstate[8] = {
18
+ 0x46615b35ul, 0xf4bfbff7ul, 0x9f8dc671ul, 0x83627ab3ul,
19
+ 0x60217180ul, 0x57358661ul, 0x21a29e54ul, 0x68b07b4cul
20
+ };
21
+ nostr_native_secp256k1_sha256_initialize_midstate(sha, 64, midstate);
22
+ }
23
+
24
+ /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
25
+ * SHA256 to SHA256("BIP0340/aux")||SHA256("BIP0340/aux"). */
26
+ static void nostr_native_secp256k1_nonce_function_bip340_sha256_tagged_aux(nostr_native_secp256k1_sha256 *sha) {
27
+ static const uint32_t midstate[8] = {
28
+ 0x24dd3219ul, 0x4eba7e70ul, 0xca0fabb9ul, 0x0fa3166dul,
29
+ 0x3afbe4b1ul, 0x4c44df97ul, 0x4aac2739ul, 0x249e850aul
30
+ };
31
+ nostr_native_secp256k1_sha256_initialize_midstate(sha, 64, midstate);
32
+ }
33
+
34
+ /* algo argument for nonce_function_bip340 to derive the nonce exactly as stated in BIP-340
35
+ * by using the correct tagged hash function. */
36
+ static const unsigned char bip340_algo[] = {'B', 'I', 'P', '0', '3', '4', '0', '/', 'n', 'o', 'n', 'c', 'e'};
37
+
38
+ static const unsigned char schnorrsig_extraparams_magic[4] = SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC;
39
+
40
+ static int nonce_function_bip340_impl(const nostr_native_secp256k1_hash_ctx *hash_ctx, unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) {
41
+ nostr_native_secp256k1_sha256 sha;
42
+ unsigned char masked_key[32];
43
+ int i;
44
+
45
+ if (algo == NULL) {
46
+ return 0;
47
+ }
48
+
49
+ if (data != NULL) {
50
+ nostr_native_secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha);
51
+ nostr_native_secp256k1_sha256_write(hash_ctx, &sha, data, 32);
52
+ nostr_native_secp256k1_sha256_finalize(hash_ctx, &sha, masked_key);
53
+ for (i = 0; i < 32; i++) {
54
+ masked_key[i] ^= key32[i];
55
+ }
56
+ } else {
57
+ /* Precomputed TaggedHash("BIP0340/aux", 0x0000...00); */
58
+ static const unsigned char ZERO_MASK[32] = {
59
+ 84, 241, 105, 207, 201, 226, 229, 114,
60
+ 116, 128, 68, 31, 144, 186, 37, 196,
61
+ 136, 244, 97, 199, 11, 94, 165, 220,
62
+ 170, 247, 175, 105, 39, 10, 165, 20
63
+ };
64
+ for (i = 0; i < 32; i++) {
65
+ masked_key[i] = key32[i] ^ ZERO_MASK[i];
66
+ }
67
+ }
68
+
69
+ /* Tag the hash with algo which is important to avoid nonce reuse across
70
+ * algorithms. If this nonce function is used in BIP-340 signing as defined
71
+ * in the spec, an optimized tagging implementation is used. */
72
+ if (algolen == sizeof(bip340_algo)
73
+ && nostr_native_secp256k1_memcmp_var(algo, bip340_algo, algolen) == 0) {
74
+ nostr_native_secp256k1_nonce_function_bip340_sha256_tagged(&sha);
75
+ } else {
76
+ nostr_native_secp256k1_sha256_initialize_tagged(hash_ctx, &sha, algo, algolen);
77
+ }
78
+
79
+ /* Hash masked-key||pk||msg using the tagged hash as per the spec */
80
+ nostr_native_secp256k1_sha256_write(hash_ctx, &sha, masked_key, 32);
81
+ nostr_native_secp256k1_sha256_write(hash_ctx, &sha, xonly_pk32, 32);
82
+ nostr_native_secp256k1_sha256_write(hash_ctx, &sha, msg, msglen);
83
+ nostr_native_secp256k1_sha256_finalize(hash_ctx, &sha, nonce32);
84
+ nostr_native_secp256k1_sha256_clear(&sha);
85
+ nostr_native_secp256k1_memclear_explicit(masked_key, sizeof(masked_key));
86
+
87
+ return 1;
88
+ }
89
+
90
+ static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) {
91
+ return nonce_function_bip340_impl(nostr_native_secp256k1_get_hash_context(nostr_native_secp256k1_context_static), nonce32, msg, msglen, key32, xonly_pk32, algo, algolen, data);
92
+ }
93
+
94
+ const nostr_native_secp256k1_nonce_function_hardened nostr_native_secp256k1_nonce_function_bip340 = nonce_function_bip340;
95
+
96
+ /* Initializes SHA256 with fixed midstate. This midstate was computed by applying
97
+ * SHA256 to SHA256("BIP0340/challenge")||SHA256("BIP0340/challenge"). */
98
+ static void nostr_native_secp256k1_schnorrsig_sha256_tagged(nostr_native_secp256k1_sha256 *sha) {
99
+ static const uint32_t midstate[8] = {
100
+ 0x9cecba11ul, 0x23925381ul, 0x11679112ul, 0xd1627e0ful,
101
+ 0x97c87550ul, 0x003cc765ul, 0x90f61164ul, 0x33e9b66aul
102
+ };
103
+ nostr_native_secp256k1_sha256_initialize_midstate(sha, 64, midstate);
104
+ }
105
+
106
+ static void nostr_native_secp256k1_schnorrsig_challenge(const nostr_native_secp256k1_hash_ctx *hash_ctx, nostr_native_secp256k1_scalar* e, const unsigned char *r32, const unsigned char *msg, size_t msglen, const unsigned char *pubkey32)
107
+ {
108
+ unsigned char buf[32];
109
+ nostr_native_secp256k1_sha256 sha;
110
+
111
+ /* tagged hash(r.x, pk.x, msg) */
112
+ nostr_native_secp256k1_schnorrsig_sha256_tagged(&sha);
113
+ nostr_native_secp256k1_sha256_write(hash_ctx, &sha, r32, 32);
114
+ nostr_native_secp256k1_sha256_write(hash_ctx, &sha, pubkey32, 32);
115
+ nostr_native_secp256k1_sha256_write(hash_ctx, &sha, msg, msglen);
116
+ nostr_native_secp256k1_sha256_finalize(hash_ctx, &sha, buf);
117
+ /* Set scalar e to the challenge hash modulo the curve order as per
118
+ * BIP340. */
119
+ nostr_native_secp256k1_scalar_set_b32(e, buf, NULL);
120
+ }
121
+
122
+ static int nostr_native_secp256k1_schnorrsig_sign_internal(const nostr_native_secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const nostr_native_secp256k1_keypair *keypair, nostr_native_secp256k1_nonce_function_hardened noncefp, void *ndata) {
123
+ nostr_native_secp256k1_scalar sk;
124
+ nostr_native_secp256k1_scalar e;
125
+ nostr_native_secp256k1_scalar k;
126
+ nostr_native_secp256k1_ge pk;
127
+ nostr_native_secp256k1_ge r;
128
+ unsigned char nonce32[32] = { 0 };
129
+ unsigned char pk_buf[32];
130
+ unsigned char seckey[32];
131
+ int ret = 1;
132
+
133
+ VERIFY_CHECK(ctx != NULL);
134
+ ARG_CHECK(nostr_native_secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
135
+ ARG_CHECK(sig64 != NULL);
136
+ ARG_CHECK(msg != NULL || msglen == 0);
137
+ ARG_CHECK(keypair != NULL);
138
+
139
+ ret &= nostr_native_secp256k1_keypair_load(ctx, &sk, &pk, keypair);
140
+ /* Because we are signing for a x-only pubkey, the secret key is negated
141
+ * before signing if the point corresponding to the secret key does not
142
+ * have an even Y. */
143
+ if (nostr_native_secp256k1_fe_is_odd(&pk.y)) {
144
+ nostr_native_secp256k1_scalar_negate(&sk, &sk);
145
+ }
146
+
147
+ nostr_native_secp256k1_scalar_get_b32(seckey, &sk);
148
+ nostr_native_secp256k1_fe_get_b32(pk_buf, &pk.x);
149
+
150
+ /* Compute nonce */
151
+ if (noncefp == NULL || noncefp == nostr_native_secp256k1_nonce_function_bip340) {
152
+ /* Use context-aware nonce function by default */
153
+ ret &= nonce_function_bip340_impl(nostr_native_secp256k1_get_hash_context(ctx), nonce32, msg, msglen, seckey, pk_buf, bip340_algo, sizeof(bip340_algo), ndata);
154
+ } else {
155
+ ret &= !!noncefp(nonce32, msg, msglen, seckey, pk_buf, bip340_algo, sizeof(bip340_algo), ndata);
156
+ }
157
+
158
+ nostr_native_secp256k1_scalar_set_b32(&k, nonce32, NULL);
159
+ ret &= !nostr_native_secp256k1_scalar_is_zero(&k);
160
+ nostr_native_secp256k1_scalar_cmov(&k, &nostr_native_secp256k1_scalar_one, !ret);
161
+
162
+ nostr_native_secp256k1_ecmult_gen_ge(&ctx->ecmult_gen_ctx, &r, &k);
163
+
164
+ /* We declassify r to allow using it as a branch point. This is fine
165
+ * because r is not a secret. */
166
+ nostr_native_secp256k1_declassify(ctx, &r, sizeof(r));
167
+ nostr_native_secp256k1_fe_normalize_var(&r.y);
168
+ if (nostr_native_secp256k1_fe_is_odd(&r.y)) {
169
+ nostr_native_secp256k1_scalar_negate(&k, &k);
170
+ }
171
+ nostr_native_secp256k1_fe_normalize_var(&r.x);
172
+ nostr_native_secp256k1_fe_get_b32(&sig64[0], &r.x);
173
+
174
+ nostr_native_secp256k1_schnorrsig_challenge(nostr_native_secp256k1_get_hash_context(ctx), &e, &sig64[0], msg, msglen, pk_buf);
175
+ nostr_native_secp256k1_scalar_mul(&e, &e, &sk);
176
+ nostr_native_secp256k1_scalar_add(&e, &e, &k);
177
+ nostr_native_secp256k1_scalar_get_b32(&sig64[32], &e);
178
+
179
+ nostr_native_secp256k1_memczero(sig64, 64, !ret);
180
+ nostr_native_secp256k1_scalar_clear(&k);
181
+ nostr_native_secp256k1_scalar_clear(&sk);
182
+ nostr_native_secp256k1_memclear_explicit(seckey, sizeof(seckey));
183
+ nostr_native_secp256k1_memclear_explicit(nonce32, sizeof(nonce32));
184
+
185
+ return ret;
186
+ }
187
+
188
+ int nostr_native_secp256k1_schnorrsig_sign32(const nostr_native_secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg32, const nostr_native_secp256k1_keypair *keypair, const unsigned char *aux_rand32) {
189
+ /* We cast away const from the passed aux_rand32 argument since we know the default nonce function does not modify it. */
190
+ return nostr_native_secp256k1_schnorrsig_sign_internal(ctx, sig64, msg32, 32, keypair, nostr_native_secp256k1_nonce_function_bip340, (unsigned char*)aux_rand32);
191
+ }
192
+
193
+ int nostr_native_secp256k1_schnorrsig_sign_custom(const nostr_native_secp256k1_context* ctx, unsigned char *sig64, const unsigned char *msg, size_t msglen, const nostr_native_secp256k1_keypair *keypair, nostr_native_secp256k1_schnorrsig_extraparams *extraparams) {
194
+ nostr_native_secp256k1_nonce_function_hardened noncefp = NULL;
195
+ void *ndata = NULL;
196
+ VERIFY_CHECK(ctx != NULL);
197
+
198
+ if (extraparams != NULL) {
199
+ ARG_CHECK(nostr_native_secp256k1_memcmp_var(extraparams->magic,
200
+ schnorrsig_extraparams_magic,
201
+ sizeof(extraparams->magic)) == 0);
202
+ noncefp = extraparams->noncefp;
203
+ ndata = extraparams->ndata;
204
+ }
205
+ return nostr_native_secp256k1_schnorrsig_sign_internal(ctx, sig64, msg, msglen, keypair, noncefp, ndata);
206
+ }
207
+
208
+ int nostr_native_secp256k1_schnorrsig_verify(const nostr_native_secp256k1_context* ctx, const unsigned char *sig64, const unsigned char *msg, size_t msglen, const nostr_native_secp256k1_xonly_pubkey *pubkey) {
209
+ nostr_native_secp256k1_scalar s;
210
+ nostr_native_secp256k1_scalar e;
211
+ nostr_native_secp256k1_gej rj;
212
+ nostr_native_secp256k1_ge pk;
213
+ nostr_native_secp256k1_gej pkj;
214
+ nostr_native_secp256k1_fe rx;
215
+ nostr_native_secp256k1_ge r;
216
+ unsigned char buf[32];
217
+ int overflow;
218
+
219
+ VERIFY_CHECK(ctx != NULL);
220
+ ARG_CHECK(sig64 != NULL);
221
+ ARG_CHECK(msg != NULL || msglen == 0);
222
+ ARG_CHECK(pubkey != NULL);
223
+
224
+ if (!nostr_native_secp256k1_fe_set_b32_limit(&rx, &sig64[0])) {
225
+ return 0;
226
+ }
227
+
228
+ nostr_native_secp256k1_scalar_set_b32(&s, &sig64[32], &overflow);
229
+ if (overflow) {
230
+ return 0;
231
+ }
232
+
233
+ if (!nostr_native_secp256k1_xonly_pubkey_load(ctx, &pk, pubkey)) {
234
+ return 0;
235
+ }
236
+
237
+ /* Compute e. */
238
+ nostr_native_secp256k1_fe_get_b32(buf, &pk.x);
239
+ nostr_native_secp256k1_schnorrsig_challenge(nostr_native_secp256k1_get_hash_context(ctx), &e, &sig64[0], msg, msglen, buf);
240
+
241
+ /* Compute rj = s*G + (-e)*pkj */
242
+ nostr_native_secp256k1_scalar_negate(&e, &e);
243
+ nostr_native_secp256k1_gej_set_ge(&pkj, &pk);
244
+ nostr_native_secp256k1_ecmult(&rj, &pkj, &e, &s);
245
+
246
+ nostr_native_secp256k1_ge_set_gej_var(&r, &rj);
247
+ if (nostr_native_secp256k1_ge_is_infinity(&r)) {
248
+ return 0;
249
+ }
250
+
251
+ nostr_native_secp256k1_fe_normalize_var(&r.y);
252
+ return !nostr_native_secp256k1_fe_is_odd(&r.y) &&
253
+ nostr_native_secp256k1_fe_equal(&rx, &r.x);
254
+ }
255
+
256
+ #endif