@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,1014 @@
1
+ /***********************************************************************
2
+ * Copyright (c) 2013, 2014 Pieter Wuille *
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_GROUP_IMPL_H
8
+ #define SECP256K1_GROUP_IMPL_H
9
+
10
+ #include <string.h>
11
+
12
+ #include "field.h"
13
+ #include "group.h"
14
+ #include "util.h"
15
+
16
+ /* Begin of section generated by sage/gen_exhaustive_groups.sage. */
17
+ #define SECP256K1_G_ORDER_7 SECP256K1_GE_CONST(\
18
+ 0x66625d13, 0x317ffe44, 0x63d32cff, 0x1ca02b9b,\
19
+ 0xe5c6d070, 0x50b4b05e, 0x81cc30db, 0xf5166f0a,\
20
+ 0x1e60e897, 0xa7c00c7c, 0x2df53eb6, 0x98274ff4,\
21
+ 0x64252f42, 0x8ca44e17, 0x3b25418c, 0xff4ab0cf\
22
+ )
23
+ #define SECP256K1_G_ORDER_13 SECP256K1_GE_CONST(\
24
+ 0xa2482ff8, 0x4bf34edf, 0xa51262fd, 0xe57921db,\
25
+ 0xe0dd2cb7, 0xa5914790, 0xbc71631f, 0xc09704fb,\
26
+ 0x942536cb, 0xa3e49492, 0x3a701cc3, 0xee3e443f,\
27
+ 0xdf182aa9, 0x15b8aa6a, 0x166d3b19, 0xba84b045\
28
+ )
29
+ #define SECP256K1_G_ORDER_199 SECP256K1_GE_CONST(\
30
+ 0x7fb07b5c, 0xd07c3bda, 0x553902e2, 0x7a87ea2c,\
31
+ 0x35108a7f, 0x051f41e5, 0xb76abad5, 0x1f2703ad,\
32
+ 0x0a251539, 0x5b4c4438, 0x952a634f, 0xac10dd4d,\
33
+ 0x6d6f4745, 0x98990c27, 0x3a4f3116, 0xd32ff969\
34
+ )
35
+ /** Generator for secp256k1, value 'g' defined in
36
+ * "Standards for Efficient Cryptography" (SEC2) 2.7.1.
37
+ */
38
+ #define SECP256K1_G SECP256K1_GE_CONST(\
39
+ 0x79be667e, 0xf9dcbbac, 0x55a06295, 0xce870b07,\
40
+ 0x029bfcdb, 0x2dce28d9, 0x59f2815b, 0x16f81798,\
41
+ 0x483ada77, 0x26a3c465, 0x5da4fbfc, 0x0e1108a8,\
42
+ 0xfd17b448, 0xa6855419, 0x9c47d08f, 0xfb10d4b8\
43
+ )
44
+ /* These exhaustive group test orders and generators are chosen such that:
45
+ * - The field size is equal to that of secp256k1, so field code is the same.
46
+ * - The curve equation is of the form y^2=x^3+B for some small constant B.
47
+ * - The subgroup has a generator 2*P, where P.x is as small as possible.
48
+ * - The subgroup has size less than 1000 to permit exhaustive testing.
49
+ * - The subgroup admits an endomorphism of the form lambda*(x,y) == (beta*x,y).
50
+ */
51
+ #if defined(EXHAUSTIVE_TEST_ORDER)
52
+ # if EXHAUSTIVE_TEST_ORDER == 7
53
+
54
+ static const nostr_native_secp256k1_ge nostr_native_secp256k1_ge_const_g = SECP256K1_G_ORDER_7;
55
+ #define SECP256K1_B 6
56
+
57
+ # elif EXHAUSTIVE_TEST_ORDER == 13
58
+
59
+ static const nostr_native_secp256k1_ge nostr_native_secp256k1_ge_const_g = SECP256K1_G_ORDER_13;
60
+ #define SECP256K1_B 2
61
+
62
+ # elif EXHAUSTIVE_TEST_ORDER == 199
63
+
64
+ static const nostr_native_secp256k1_ge nostr_native_secp256k1_ge_const_g = SECP256K1_G_ORDER_199;
65
+ #define SECP256K1_B 4
66
+
67
+ # else
68
+ # error No known generator for the specified exhaustive test group order.
69
+ # endif
70
+ #else
71
+
72
+ static const nostr_native_secp256k1_ge nostr_native_secp256k1_ge_const_g = SECP256K1_G;
73
+ #define SECP256K1_B 7
74
+
75
+ #endif
76
+ /* End of section generated by sage/gen_exhaustive_groups.sage. */
77
+
78
+ static void nostr_native_secp256k1_ge_verify(const nostr_native_secp256k1_ge *a) {
79
+ SECP256K1_FE_VERIFY(&a->x);
80
+ SECP256K1_FE_VERIFY(&a->y);
81
+ SECP256K1_FE_VERIFY_MAGNITUDE(&a->x, SECP256K1_GE_X_MAGNITUDE_MAX);
82
+ SECP256K1_FE_VERIFY_MAGNITUDE(&a->y, SECP256K1_GE_Y_MAGNITUDE_MAX);
83
+ VERIFY_CHECK(a->infinity == 0 || a->infinity == 1);
84
+ (void)a;
85
+ }
86
+
87
+ static void nostr_native_secp256k1_gej_verify(const nostr_native_secp256k1_gej *a) {
88
+ SECP256K1_FE_VERIFY(&a->x);
89
+ SECP256K1_FE_VERIFY(&a->y);
90
+ SECP256K1_FE_VERIFY(&a->z);
91
+ SECP256K1_FE_VERIFY_MAGNITUDE(&a->x, SECP256K1_GEJ_X_MAGNITUDE_MAX);
92
+ SECP256K1_FE_VERIFY_MAGNITUDE(&a->y, SECP256K1_GEJ_Y_MAGNITUDE_MAX);
93
+ SECP256K1_FE_VERIFY_MAGNITUDE(&a->z, SECP256K1_GEJ_Z_MAGNITUDE_MAX);
94
+ VERIFY_CHECK(a->infinity == 0 || a->infinity == 1);
95
+ (void)a;
96
+ }
97
+
98
+ /* Set r to the affine coordinates of Jacobian point (a.x, a.y, 1/zi). */
99
+ static void nostr_native_secp256k1_ge_set_gej_zinv(nostr_native_secp256k1_ge *r, const nostr_native_secp256k1_gej *a, const nostr_native_secp256k1_fe *zi) {
100
+ nostr_native_secp256k1_fe zi2;
101
+ nostr_native_secp256k1_fe zi3;
102
+ SECP256K1_GEJ_VERIFY(a);
103
+ SECP256K1_FE_VERIFY(zi);
104
+ VERIFY_CHECK(!a->infinity);
105
+
106
+ nostr_native_secp256k1_fe_sqr(&zi2, zi);
107
+ nostr_native_secp256k1_fe_mul(&zi3, &zi2, zi);
108
+ nostr_native_secp256k1_fe_mul(&r->x, &a->x, &zi2);
109
+ nostr_native_secp256k1_fe_mul(&r->y, &a->y, &zi3);
110
+ r->infinity = a->infinity;
111
+
112
+ SECP256K1_GE_VERIFY(r);
113
+ }
114
+
115
+ /* Set r to the affine coordinates of Jacobian point (a.x, a.y, 1/zi). */
116
+ static void nostr_native_secp256k1_ge_set_ge_zinv(nostr_native_secp256k1_ge *r, const nostr_native_secp256k1_ge *a, const nostr_native_secp256k1_fe *zi) {
117
+ nostr_native_secp256k1_fe zi2;
118
+ nostr_native_secp256k1_fe zi3;
119
+ SECP256K1_GE_VERIFY(a);
120
+ SECP256K1_FE_VERIFY(zi);
121
+ VERIFY_CHECK(!a->infinity);
122
+
123
+ nostr_native_secp256k1_fe_sqr(&zi2, zi);
124
+ nostr_native_secp256k1_fe_mul(&zi3, &zi2, zi);
125
+ nostr_native_secp256k1_fe_mul(&r->x, &a->x, &zi2);
126
+ nostr_native_secp256k1_fe_mul(&r->y, &a->y, &zi3);
127
+ r->infinity = a->infinity;
128
+
129
+ SECP256K1_GE_VERIFY(r);
130
+ }
131
+
132
+ static void nostr_native_secp256k1_ge_set_xy(nostr_native_secp256k1_ge *r, const nostr_native_secp256k1_fe *x, const nostr_native_secp256k1_fe *y) {
133
+ SECP256K1_FE_VERIFY(x);
134
+ SECP256K1_FE_VERIFY(y);
135
+
136
+ r->infinity = 0;
137
+ r->x = *x;
138
+ r->y = *y;
139
+
140
+ SECP256K1_GE_VERIFY(r);
141
+ }
142
+
143
+ static int nostr_native_secp256k1_ge_is_infinity(const nostr_native_secp256k1_ge *a) {
144
+ SECP256K1_GE_VERIFY(a);
145
+
146
+ return a->infinity;
147
+ }
148
+
149
+ static void nostr_native_secp256k1_ge_neg(nostr_native_secp256k1_ge *r, const nostr_native_secp256k1_ge *a) {
150
+ SECP256K1_GE_VERIFY(a);
151
+
152
+ *r = *a;
153
+ nostr_native_secp256k1_fe_normalize_weak(&r->y);
154
+ nostr_native_secp256k1_fe_negate(&r->y, &r->y, 1);
155
+
156
+ SECP256K1_GE_VERIFY(r);
157
+ }
158
+
159
+ static void nostr_native_secp256k1_ge_set_gej(nostr_native_secp256k1_ge *r, nostr_native_secp256k1_gej *a) {
160
+ nostr_native_secp256k1_fe z2, z3;
161
+ SECP256K1_GEJ_VERIFY(a);
162
+
163
+ r->infinity = a->infinity;
164
+ nostr_native_secp256k1_fe_inv(&a->z, &a->z);
165
+ nostr_native_secp256k1_fe_sqr(&z2, &a->z);
166
+ nostr_native_secp256k1_fe_mul(&z3, &a->z, &z2);
167
+ nostr_native_secp256k1_fe_mul(&a->x, &a->x, &z2);
168
+ nostr_native_secp256k1_fe_mul(&a->y, &a->y, &z3);
169
+ nostr_native_secp256k1_fe_set_int(&a->z, 1);
170
+ r->x = a->x;
171
+ r->y = a->y;
172
+
173
+ SECP256K1_GEJ_VERIFY(a);
174
+ SECP256K1_GE_VERIFY(r);
175
+ }
176
+
177
+ static void nostr_native_secp256k1_ge_set_gej_var(nostr_native_secp256k1_ge *r, nostr_native_secp256k1_gej *a) {
178
+ nostr_native_secp256k1_fe z2, z3;
179
+ SECP256K1_GEJ_VERIFY(a);
180
+
181
+ if (nostr_native_secp256k1_gej_is_infinity(a)) {
182
+ nostr_native_secp256k1_ge_set_infinity(r);
183
+ return;
184
+ }
185
+ r->infinity = 0;
186
+ nostr_native_secp256k1_fe_inv_var(&a->z, &a->z);
187
+ nostr_native_secp256k1_fe_sqr(&z2, &a->z);
188
+ nostr_native_secp256k1_fe_mul(&z3, &a->z, &z2);
189
+ nostr_native_secp256k1_fe_mul(&a->x, &a->x, &z2);
190
+ nostr_native_secp256k1_fe_mul(&a->y, &a->y, &z3);
191
+ nostr_native_secp256k1_fe_set_int(&a->z, 1);
192
+ nostr_native_secp256k1_ge_set_xy(r, &a->x, &a->y);
193
+
194
+ SECP256K1_GEJ_VERIFY(a);
195
+ SECP256K1_GE_VERIFY(r);
196
+ }
197
+
198
+ static void nostr_native_secp256k1_ge_set_all_gej(nostr_native_secp256k1_ge *r, const nostr_native_secp256k1_gej *a, size_t len) {
199
+ nostr_native_secp256k1_fe u;
200
+ size_t i;
201
+ #ifdef VERIFY
202
+ for (i = 0; i < len; i++) {
203
+ SECP256K1_GEJ_VERIFY(&a[i]);
204
+ VERIFY_CHECK(!nostr_native_secp256k1_gej_is_infinity(&a[i]));
205
+ }
206
+ #endif
207
+
208
+ if (len == 0) {
209
+ return;
210
+ }
211
+
212
+ /* Use destination's x coordinates as scratch space */
213
+ r[0].x = a[0].z;
214
+ for (i = 1; i < len; i++) {
215
+ nostr_native_secp256k1_fe_mul(&r[i].x, &r[i - 1].x, &a[i].z);
216
+ }
217
+ nostr_native_secp256k1_fe_inv(&u, &r[len - 1].x);
218
+
219
+ for (i = len - 1; i > 0; i--) {
220
+ nostr_native_secp256k1_fe_mul(&r[i].x, &r[i - 1].x, &u);
221
+ nostr_native_secp256k1_fe_mul(&u, &u, &a[i].z);
222
+ }
223
+ r[0].x = u;
224
+
225
+ for (i = 0; i < len; i++) {
226
+ nostr_native_secp256k1_ge_set_gej_zinv(&r[i], &a[i], &r[i].x);
227
+ }
228
+
229
+ #ifdef VERIFY
230
+ for (i = 0; i < len; i++) {
231
+ SECP256K1_GE_VERIFY(&r[i]);
232
+ }
233
+ #endif
234
+ }
235
+
236
+ static void nostr_native_secp256k1_ge_set_all_gej_var(nostr_native_secp256k1_ge *r, const nostr_native_secp256k1_gej *a, size_t len) {
237
+ nostr_native_secp256k1_fe u;
238
+ size_t i;
239
+ size_t last_i = SIZE_MAX;
240
+ #ifdef VERIFY
241
+ for (i = 0; i < len; i++) {
242
+ SECP256K1_GEJ_VERIFY(&a[i]);
243
+ }
244
+ #endif
245
+
246
+ for (i = 0; i < len; i++) {
247
+ if (a[i].infinity) {
248
+ nostr_native_secp256k1_ge_set_infinity(&r[i]);
249
+ } else {
250
+ /* Use destination's x coordinates as scratch space */
251
+ if (last_i == SIZE_MAX) {
252
+ r[i].x = a[i].z;
253
+ } else {
254
+ nostr_native_secp256k1_fe_mul(&r[i].x, &r[last_i].x, &a[i].z);
255
+ }
256
+ last_i = i;
257
+ }
258
+ }
259
+ if (last_i == SIZE_MAX) {
260
+ return;
261
+ }
262
+ nostr_native_secp256k1_fe_inv_var(&u, &r[last_i].x);
263
+
264
+ i = last_i;
265
+ while (i > 0) {
266
+ i--;
267
+ if (!a[i].infinity) {
268
+ nostr_native_secp256k1_fe_mul(&r[last_i].x, &r[i].x, &u);
269
+ nostr_native_secp256k1_fe_mul(&u, &u, &a[last_i].z);
270
+ last_i = i;
271
+ }
272
+ }
273
+ VERIFY_CHECK(!a[last_i].infinity);
274
+ r[last_i].x = u;
275
+
276
+ for (i = 0; i < len; i++) {
277
+ if (!a[i].infinity) {
278
+ nostr_native_secp256k1_ge_set_gej_zinv(&r[i], &a[i], &r[i].x);
279
+ }
280
+ }
281
+
282
+ #ifdef VERIFY
283
+ for (i = 0; i < len; i++) {
284
+ SECP256K1_GE_VERIFY(&r[i]);
285
+ }
286
+ #endif
287
+ }
288
+
289
+ static void nostr_native_secp256k1_ge_table_set_globalz(size_t len, nostr_native_secp256k1_ge *a, const nostr_native_secp256k1_fe *zr) {
290
+ size_t i;
291
+ nostr_native_secp256k1_fe zs;
292
+ #ifdef VERIFY
293
+ for (i = 0; i < len; i++) {
294
+ SECP256K1_GE_VERIFY(&a[i]);
295
+ SECP256K1_FE_VERIFY(&zr[i]);
296
+ }
297
+ #endif
298
+
299
+ if (len > 0) {
300
+ i = len - 1;
301
+ /* Ensure all y values are in weak normal form for fast negation of points */
302
+ nostr_native_secp256k1_fe_normalize_weak(&a[i].y);
303
+ zs = zr[i];
304
+
305
+ /* Work our way backwards, using the z-ratios to scale the x/y values. */
306
+ while (i > 0) {
307
+ if (i != len - 1) {
308
+ nostr_native_secp256k1_fe_mul(&zs, &zs, &zr[i]);
309
+ }
310
+ i--;
311
+ nostr_native_secp256k1_ge_set_ge_zinv(&a[i], &a[i], &zs);
312
+ }
313
+ }
314
+
315
+ #ifdef VERIFY
316
+ for (i = 0; i < len; i++) {
317
+ SECP256K1_GE_VERIFY(&a[i]);
318
+ }
319
+ #endif
320
+ }
321
+
322
+ static void nostr_native_secp256k1_gej_set_infinity(nostr_native_secp256k1_gej *r) {
323
+ r->infinity = 1;
324
+ nostr_native_secp256k1_fe_set_int(&r->x, 0);
325
+ nostr_native_secp256k1_fe_set_int(&r->y, 0);
326
+ nostr_native_secp256k1_fe_set_int(&r->z, 0);
327
+
328
+ SECP256K1_GEJ_VERIFY(r);
329
+ }
330
+
331
+ static void nostr_native_secp256k1_ge_set_infinity(nostr_native_secp256k1_ge *r) {
332
+ r->infinity = 1;
333
+ nostr_native_secp256k1_fe_set_int(&r->x, 0);
334
+ nostr_native_secp256k1_fe_set_int(&r->y, 0);
335
+
336
+ SECP256K1_GE_VERIFY(r);
337
+ }
338
+
339
+ static void nostr_native_secp256k1_gej_clear(nostr_native_secp256k1_gej *r) {
340
+ nostr_native_secp256k1_memclear_explicit(r, sizeof(nostr_native_secp256k1_gej));
341
+ }
342
+
343
+ static void nostr_native_secp256k1_ge_clear(nostr_native_secp256k1_ge *r) {
344
+ nostr_native_secp256k1_memclear_explicit(r, sizeof(nostr_native_secp256k1_ge));
345
+ }
346
+
347
+ static int nostr_native_secp256k1_ge_set_xo_var(nostr_native_secp256k1_ge *r, const nostr_native_secp256k1_fe *x, int odd) {
348
+ nostr_native_secp256k1_fe x2, x3;
349
+ int ret;
350
+ SECP256K1_FE_VERIFY(x);
351
+
352
+ r->x = *x;
353
+ nostr_native_secp256k1_fe_sqr(&x2, x);
354
+ nostr_native_secp256k1_fe_mul(&x3, x, &x2);
355
+ r->infinity = 0;
356
+ nostr_native_secp256k1_fe_add_int(&x3, SECP256K1_B);
357
+ ret = nostr_native_secp256k1_fe_sqrt(&r->y, &x3);
358
+ nostr_native_secp256k1_fe_normalize_var(&r->y);
359
+ if (nostr_native_secp256k1_fe_is_odd(&r->y) != odd) {
360
+ nostr_native_secp256k1_fe_negate(&r->y, &r->y, 1);
361
+ }
362
+
363
+ SECP256K1_GE_VERIFY(r);
364
+ return ret;
365
+ }
366
+
367
+ static void nostr_native_secp256k1_gej_set_ge(nostr_native_secp256k1_gej *r, const nostr_native_secp256k1_ge *a) {
368
+ SECP256K1_GE_VERIFY(a);
369
+
370
+ r->infinity = a->infinity;
371
+ r->x = a->x;
372
+ r->y = a->y;
373
+ nostr_native_secp256k1_fe_set_int(&r->z, 1);
374
+
375
+ SECP256K1_GEJ_VERIFY(r);
376
+ }
377
+
378
+ static int nostr_native_secp256k1_gej_eq_var(const nostr_native_secp256k1_gej *a, const nostr_native_secp256k1_gej *b) {
379
+ nostr_native_secp256k1_gej tmp;
380
+ SECP256K1_GEJ_VERIFY(b);
381
+ SECP256K1_GEJ_VERIFY(a);
382
+
383
+ nostr_native_secp256k1_gej_neg(&tmp, a);
384
+ nostr_native_secp256k1_gej_add_var(&tmp, &tmp, b, NULL);
385
+ return nostr_native_secp256k1_gej_is_infinity(&tmp);
386
+ }
387
+
388
+ static int nostr_native_secp256k1_gej_eq_ge_var(const nostr_native_secp256k1_gej *a, const nostr_native_secp256k1_ge *b) {
389
+ nostr_native_secp256k1_gej tmp;
390
+ SECP256K1_GEJ_VERIFY(a);
391
+ SECP256K1_GE_VERIFY(b);
392
+
393
+ nostr_native_secp256k1_gej_neg(&tmp, a);
394
+ nostr_native_secp256k1_gej_add_ge_var(&tmp, &tmp, b, NULL);
395
+ return nostr_native_secp256k1_gej_is_infinity(&tmp);
396
+ }
397
+
398
+ static int nostr_native_secp256k1_ge_eq_var(const nostr_native_secp256k1_ge *a, const nostr_native_secp256k1_ge *b) {
399
+ nostr_native_secp256k1_fe tmp;
400
+ SECP256K1_GE_VERIFY(a);
401
+ SECP256K1_GE_VERIFY(b);
402
+
403
+ if (a->infinity != b->infinity) return 0;
404
+ if (a->infinity) return 1;
405
+
406
+ tmp = a->x;
407
+ nostr_native_secp256k1_fe_normalize_weak(&tmp);
408
+ if (!nostr_native_secp256k1_fe_equal(&tmp, &b->x)) return 0;
409
+
410
+ tmp = a->y;
411
+ nostr_native_secp256k1_fe_normalize_weak(&tmp);
412
+ if (!nostr_native_secp256k1_fe_equal(&tmp, &b->y)) return 0;
413
+
414
+ return 1;
415
+ }
416
+
417
+ static int nostr_native_secp256k1_gej_eq_x_var(const nostr_native_secp256k1_fe *x, const nostr_native_secp256k1_gej *a) {
418
+ nostr_native_secp256k1_fe r;
419
+ SECP256K1_FE_VERIFY(x);
420
+ SECP256K1_GEJ_VERIFY(a);
421
+ VERIFY_CHECK(!a->infinity);
422
+
423
+ nostr_native_secp256k1_fe_sqr(&r, &a->z); nostr_native_secp256k1_fe_mul(&r, &r, x);
424
+ return nostr_native_secp256k1_fe_equal(&r, &a->x);
425
+ }
426
+
427
+ static void nostr_native_secp256k1_gej_neg(nostr_native_secp256k1_gej *r, const nostr_native_secp256k1_gej *a) {
428
+ SECP256K1_GEJ_VERIFY(a);
429
+
430
+ r->infinity = a->infinity;
431
+ r->x = a->x;
432
+ r->y = a->y;
433
+ r->z = a->z;
434
+ nostr_native_secp256k1_fe_normalize_weak(&r->y);
435
+ nostr_native_secp256k1_fe_negate(&r->y, &r->y, 1);
436
+
437
+ SECP256K1_GEJ_VERIFY(r);
438
+ }
439
+
440
+ static int nostr_native_secp256k1_gej_is_infinity(const nostr_native_secp256k1_gej *a) {
441
+ SECP256K1_GEJ_VERIFY(a);
442
+
443
+ return a->infinity;
444
+ }
445
+
446
+ static int nostr_native_secp256k1_ge_is_valid_var(const nostr_native_secp256k1_ge *a) {
447
+ nostr_native_secp256k1_fe y2, x3;
448
+ SECP256K1_GE_VERIFY(a);
449
+
450
+ if (a->infinity) {
451
+ return 0;
452
+ }
453
+ /* y^2 = x^3 + 7 */
454
+ nostr_native_secp256k1_fe_sqr(&y2, &a->y);
455
+ nostr_native_secp256k1_fe_sqr(&x3, &a->x); nostr_native_secp256k1_fe_mul(&x3, &x3, &a->x);
456
+ nostr_native_secp256k1_fe_add_int(&x3, SECP256K1_B);
457
+ return nostr_native_secp256k1_fe_equal(&y2, &x3);
458
+ }
459
+
460
+ static SECP256K1_INLINE void nostr_native_secp256k1_gej_double(nostr_native_secp256k1_gej *r, const nostr_native_secp256k1_gej *a) {
461
+ /* Operations: 3 mul, 4 sqr, 8 add/half/mul_int/negate */
462
+ nostr_native_secp256k1_fe l, s, t;
463
+ SECP256K1_GEJ_VERIFY(a);
464
+
465
+ r->infinity = a->infinity;
466
+
467
+ /* Formula used:
468
+ * L = (3/2) * X1^2
469
+ * S = Y1^2
470
+ * T = -X1*S
471
+ * X3 = L^2 + 2*T
472
+ * Y3 = -(L*(X3 + T) + S^2)
473
+ * Z3 = Y1*Z1
474
+ */
475
+
476
+ nostr_native_secp256k1_fe_mul(&r->z, &a->z, &a->y); /* Z3 = Y1*Z1 (1) */
477
+ nostr_native_secp256k1_fe_sqr(&s, &a->y); /* S = Y1^2 (1) */
478
+ nostr_native_secp256k1_fe_sqr(&l, &a->x); /* L = X1^2 (1) */
479
+ nostr_native_secp256k1_fe_mul_int(&l, 3); /* L = 3*X1^2 (3) */
480
+ nostr_native_secp256k1_fe_half(&l); /* L = 3/2*X1^2 (2) */
481
+ nostr_native_secp256k1_fe_negate(&t, &s, 1); /* T = -S (2) */
482
+ nostr_native_secp256k1_fe_mul(&t, &t, &a->x); /* T = -X1*S (1) */
483
+ nostr_native_secp256k1_fe_sqr(&r->x, &l); /* X3 = L^2 (1) */
484
+ nostr_native_secp256k1_fe_add(&r->x, &t); /* X3 = L^2 + T (2) */
485
+ nostr_native_secp256k1_fe_add(&r->x, &t); /* X3 = L^2 + 2*T (3) */
486
+ nostr_native_secp256k1_fe_sqr(&s, &s); /* S' = S^2 (1) */
487
+ nostr_native_secp256k1_fe_add(&t, &r->x); /* T' = X3 + T (4) */
488
+ nostr_native_secp256k1_fe_mul(&r->y, &t, &l); /* Y3 = L*(X3 + T) (1) */
489
+ nostr_native_secp256k1_fe_add(&r->y, &s); /* Y3 = L*(X3 + T) + S^2 (2) */
490
+ nostr_native_secp256k1_fe_negate(&r->y, &r->y, 2); /* Y3 = -(L*(X3 + T) + S^2) (3) */
491
+
492
+ SECP256K1_GEJ_VERIFY(r);
493
+ }
494
+
495
+ static void nostr_native_secp256k1_gej_double_var(nostr_native_secp256k1_gej *r, const nostr_native_secp256k1_gej *a, nostr_native_secp256k1_fe *rzr) {
496
+ SECP256K1_GEJ_VERIFY(a);
497
+
498
+ /** For secp256k1, 2Q is infinity if and only if Q is infinity. This is because if 2Q = infinity,
499
+ * Q must equal -Q, or that Q.y == -(Q.y), or Q.y is 0. For a point on y^2 = x^3 + 7 to have
500
+ * y=0, x^3 must be -7 mod p. However, -7 has no cube root mod p.
501
+ *
502
+ * Having said this, if this function receives a point on a sextic twist, e.g. by
503
+ * a fault attack, it is possible for y to be 0. This happens for y^2 = x^3 + 6,
504
+ * since -6 does have a cube root mod p. For this point, this function will not set
505
+ * the infinity flag even though the point doubles to infinity, and the result
506
+ * point will be gibberish (z = 0 but infinity = 0).
507
+ */
508
+ if (a->infinity) {
509
+ nostr_native_secp256k1_gej_set_infinity(r);
510
+ if (rzr != NULL) {
511
+ nostr_native_secp256k1_fe_set_int(rzr, 1);
512
+ }
513
+ return;
514
+ }
515
+
516
+ if (rzr != NULL) {
517
+ *rzr = a->y;
518
+ nostr_native_secp256k1_fe_normalize_weak(rzr);
519
+ }
520
+
521
+ nostr_native_secp256k1_gej_double(r, a);
522
+
523
+ SECP256K1_GEJ_VERIFY(r);
524
+ }
525
+
526
+ static void nostr_native_secp256k1_gej_add_var(nostr_native_secp256k1_gej *r, const nostr_native_secp256k1_gej *a, const nostr_native_secp256k1_gej *b, nostr_native_secp256k1_fe *rzr) {
527
+ /* 12 mul, 4 sqr, 11 add/negate/normalizes_to_zero (ignoring special cases) */
528
+ nostr_native_secp256k1_fe z22, z12, u1, u2, s1, s2, h, i, h2, h3, t;
529
+ SECP256K1_GEJ_VERIFY(a);
530
+ SECP256K1_GEJ_VERIFY(b);
531
+
532
+ if (a->infinity) {
533
+ VERIFY_CHECK(rzr == NULL);
534
+ *r = *b;
535
+ return;
536
+ }
537
+ if (b->infinity) {
538
+ if (rzr != NULL) {
539
+ nostr_native_secp256k1_fe_set_int(rzr, 1);
540
+ }
541
+ *r = *a;
542
+ return;
543
+ }
544
+
545
+ nostr_native_secp256k1_fe_sqr(&z22, &b->z);
546
+ nostr_native_secp256k1_fe_sqr(&z12, &a->z);
547
+ nostr_native_secp256k1_fe_mul(&u1, &a->x, &z22);
548
+ nostr_native_secp256k1_fe_mul(&u2, &b->x, &z12);
549
+ nostr_native_secp256k1_fe_mul(&s1, &a->y, &z22); nostr_native_secp256k1_fe_mul(&s1, &s1, &b->z);
550
+ nostr_native_secp256k1_fe_mul(&s2, &b->y, &z12); nostr_native_secp256k1_fe_mul(&s2, &s2, &a->z);
551
+ nostr_native_secp256k1_fe_negate(&h, &u1, 1); nostr_native_secp256k1_fe_add(&h, &u2);
552
+ nostr_native_secp256k1_fe_negate(&i, &s2, 1); nostr_native_secp256k1_fe_add(&i, &s1);
553
+ if (nostr_native_secp256k1_fe_normalizes_to_zero_var(&h)) {
554
+ if (nostr_native_secp256k1_fe_normalizes_to_zero_var(&i)) {
555
+ nostr_native_secp256k1_gej_double_var(r, a, rzr);
556
+ } else {
557
+ if (rzr != NULL) {
558
+ nostr_native_secp256k1_fe_set_int(rzr, 0);
559
+ }
560
+ nostr_native_secp256k1_gej_set_infinity(r);
561
+ }
562
+ return;
563
+ }
564
+
565
+ r->infinity = 0;
566
+ nostr_native_secp256k1_fe_mul(&t, &h, &b->z);
567
+ if (rzr != NULL) {
568
+ *rzr = t;
569
+ }
570
+ nostr_native_secp256k1_fe_mul(&r->z, &a->z, &t);
571
+
572
+ nostr_native_secp256k1_fe_sqr(&h2, &h);
573
+ nostr_native_secp256k1_fe_negate(&h2, &h2, 1);
574
+ nostr_native_secp256k1_fe_mul(&h3, &h2, &h);
575
+ nostr_native_secp256k1_fe_mul(&t, &u1, &h2);
576
+
577
+ nostr_native_secp256k1_fe_sqr(&r->x, &i);
578
+ nostr_native_secp256k1_fe_add(&r->x, &h3);
579
+ nostr_native_secp256k1_fe_add(&r->x, &t);
580
+ nostr_native_secp256k1_fe_add(&r->x, &t);
581
+
582
+ nostr_native_secp256k1_fe_add(&t, &r->x);
583
+ nostr_native_secp256k1_fe_mul(&r->y, &t, &i);
584
+ nostr_native_secp256k1_fe_mul(&h3, &h3, &s1);
585
+ nostr_native_secp256k1_fe_add(&r->y, &h3);
586
+
587
+ SECP256K1_GEJ_VERIFY(r);
588
+ }
589
+
590
+ static void nostr_native_secp256k1_gej_add_ge_var(nostr_native_secp256k1_gej *r, const nostr_native_secp256k1_gej *a, const nostr_native_secp256k1_ge *b, nostr_native_secp256k1_fe *rzr) {
591
+ /* Operations: 8 mul, 3 sqr, 11 add/negate/normalizes_to_zero (ignoring special cases) */
592
+ nostr_native_secp256k1_fe z12, u1, u2, s1, s2, h, i, h2, h3, t;
593
+ SECP256K1_GEJ_VERIFY(a);
594
+ SECP256K1_GE_VERIFY(b);
595
+
596
+ if (a->infinity) {
597
+ VERIFY_CHECK(rzr == NULL);
598
+ nostr_native_secp256k1_gej_set_ge(r, b);
599
+ return;
600
+ }
601
+ if (b->infinity) {
602
+ if (rzr != NULL) {
603
+ nostr_native_secp256k1_fe_set_int(rzr, 1);
604
+ }
605
+ *r = *a;
606
+ return;
607
+ }
608
+
609
+ nostr_native_secp256k1_fe_sqr(&z12, &a->z);
610
+ u1 = a->x;
611
+ nostr_native_secp256k1_fe_mul(&u2, &b->x, &z12);
612
+ s1 = a->y;
613
+ nostr_native_secp256k1_fe_mul(&s2, &b->y, &z12); nostr_native_secp256k1_fe_mul(&s2, &s2, &a->z);
614
+ nostr_native_secp256k1_fe_negate(&h, &u1, SECP256K1_GEJ_X_MAGNITUDE_MAX); nostr_native_secp256k1_fe_add(&h, &u2);
615
+ nostr_native_secp256k1_fe_negate(&i, &s2, 1); nostr_native_secp256k1_fe_add(&i, &s1);
616
+ if (nostr_native_secp256k1_fe_normalizes_to_zero_var(&h)) {
617
+ if (nostr_native_secp256k1_fe_normalizes_to_zero_var(&i)) {
618
+ nostr_native_secp256k1_gej_double_var(r, a, rzr);
619
+ } else {
620
+ if (rzr != NULL) {
621
+ nostr_native_secp256k1_fe_set_int(rzr, 0);
622
+ }
623
+ nostr_native_secp256k1_gej_set_infinity(r);
624
+ }
625
+ return;
626
+ }
627
+
628
+ r->infinity = 0;
629
+ if (rzr != NULL) {
630
+ *rzr = h;
631
+ }
632
+ nostr_native_secp256k1_fe_mul(&r->z, &a->z, &h);
633
+
634
+ nostr_native_secp256k1_fe_sqr(&h2, &h);
635
+ nostr_native_secp256k1_fe_negate(&h2, &h2, 1);
636
+ nostr_native_secp256k1_fe_mul(&h3, &h2, &h);
637
+ nostr_native_secp256k1_fe_mul(&t, &u1, &h2);
638
+
639
+ nostr_native_secp256k1_fe_sqr(&r->x, &i);
640
+ nostr_native_secp256k1_fe_add(&r->x, &h3);
641
+ nostr_native_secp256k1_fe_add(&r->x, &t);
642
+ nostr_native_secp256k1_fe_add(&r->x, &t);
643
+
644
+ nostr_native_secp256k1_fe_add(&t, &r->x);
645
+ nostr_native_secp256k1_fe_mul(&r->y, &t, &i);
646
+ nostr_native_secp256k1_fe_mul(&h3, &h3, &s1);
647
+ nostr_native_secp256k1_fe_add(&r->y, &h3);
648
+
649
+ SECP256K1_GEJ_VERIFY(r);
650
+ if (rzr != NULL) SECP256K1_FE_VERIFY(rzr);
651
+ }
652
+
653
+ static void nostr_native_secp256k1_gej_add_zinv_var(nostr_native_secp256k1_gej *r, const nostr_native_secp256k1_gej *a, const nostr_native_secp256k1_ge *b, const nostr_native_secp256k1_fe *bzinv) {
654
+ /* Operations: 9 mul, 3 sqr, 11 add/negate/normalizes_to_zero (ignoring special cases) */
655
+ nostr_native_secp256k1_fe az, z12, u1, u2, s1, s2, h, i, h2, h3, t;
656
+ SECP256K1_GEJ_VERIFY(a);
657
+ SECP256K1_GE_VERIFY(b);
658
+ SECP256K1_FE_VERIFY(bzinv);
659
+
660
+ if (a->infinity) {
661
+ nostr_native_secp256k1_fe bzinv2, bzinv3;
662
+ r->infinity = b->infinity;
663
+ nostr_native_secp256k1_fe_sqr(&bzinv2, bzinv);
664
+ nostr_native_secp256k1_fe_mul(&bzinv3, &bzinv2, bzinv);
665
+ nostr_native_secp256k1_fe_mul(&r->x, &b->x, &bzinv2);
666
+ nostr_native_secp256k1_fe_mul(&r->y, &b->y, &bzinv3);
667
+ nostr_native_secp256k1_fe_set_int(&r->z, 1);
668
+ SECP256K1_GEJ_VERIFY(r);
669
+ return;
670
+ }
671
+ if (b->infinity) {
672
+ *r = *a;
673
+ return;
674
+ }
675
+
676
+ /** We need to calculate (rx,ry,rz) = (ax,ay,az) + (bx,by,1/bzinv). Due to
677
+ * secp256k1's isomorphism we can multiply the Z coordinates on both sides
678
+ * by bzinv, and get: (rx,ry,rz*bzinv) = (ax,ay,az*bzinv) + (bx,by,1).
679
+ * This means that (rx,ry,rz) can be calculated as
680
+ * (ax,ay,az*bzinv) + (bx,by,1), when not applying the bzinv factor to rz.
681
+ * The variable az below holds the modified Z coordinate for a, which is used
682
+ * for the computation of rx and ry, but not for rz.
683
+ */
684
+ nostr_native_secp256k1_fe_mul(&az, &a->z, bzinv);
685
+
686
+ nostr_native_secp256k1_fe_sqr(&z12, &az);
687
+ u1 = a->x;
688
+ nostr_native_secp256k1_fe_mul(&u2, &b->x, &z12);
689
+ s1 = a->y;
690
+ nostr_native_secp256k1_fe_mul(&s2, &b->y, &z12); nostr_native_secp256k1_fe_mul(&s2, &s2, &az);
691
+ nostr_native_secp256k1_fe_negate(&h, &u1, SECP256K1_GEJ_X_MAGNITUDE_MAX); nostr_native_secp256k1_fe_add(&h, &u2);
692
+ nostr_native_secp256k1_fe_negate(&i, &s2, 1); nostr_native_secp256k1_fe_add(&i, &s1);
693
+ if (nostr_native_secp256k1_fe_normalizes_to_zero_var(&h)) {
694
+ if (nostr_native_secp256k1_fe_normalizes_to_zero_var(&i)) {
695
+ nostr_native_secp256k1_gej_double_var(r, a, NULL);
696
+ } else {
697
+ nostr_native_secp256k1_gej_set_infinity(r);
698
+ }
699
+ return;
700
+ }
701
+
702
+ r->infinity = 0;
703
+ nostr_native_secp256k1_fe_mul(&r->z, &a->z, &h);
704
+
705
+ nostr_native_secp256k1_fe_sqr(&h2, &h);
706
+ nostr_native_secp256k1_fe_negate(&h2, &h2, 1);
707
+ nostr_native_secp256k1_fe_mul(&h3, &h2, &h);
708
+ nostr_native_secp256k1_fe_mul(&t, &u1, &h2);
709
+
710
+ nostr_native_secp256k1_fe_sqr(&r->x, &i);
711
+ nostr_native_secp256k1_fe_add(&r->x, &h3);
712
+ nostr_native_secp256k1_fe_add(&r->x, &t);
713
+ nostr_native_secp256k1_fe_add(&r->x, &t);
714
+
715
+ nostr_native_secp256k1_fe_add(&t, &r->x);
716
+ nostr_native_secp256k1_fe_mul(&r->y, &t, &i);
717
+ nostr_native_secp256k1_fe_mul(&h3, &h3, &s1);
718
+ nostr_native_secp256k1_fe_add(&r->y, &h3);
719
+
720
+ SECP256K1_GEJ_VERIFY(r);
721
+ }
722
+
723
+
724
+ static void nostr_native_secp256k1_gej_add_ge(nostr_native_secp256k1_gej *r, const nostr_native_secp256k1_gej *a, const nostr_native_secp256k1_ge *b) {
725
+ /* Operations: 7 mul, 5 sqr, 21 add/cmov/half/mul_int/negate/normalizes_to_zero */
726
+ nostr_native_secp256k1_fe zz, u1, u2, s1, s2, t, tt, m, n, q, rr;
727
+ nostr_native_secp256k1_fe m_alt, rr_alt;
728
+ int degenerate;
729
+ SECP256K1_GEJ_VERIFY(a);
730
+ SECP256K1_GE_VERIFY(b);
731
+ VERIFY_CHECK(!b->infinity);
732
+
733
+ /* In:
734
+ * Eric Brier and Marc Joye, Weierstrass Elliptic Curves and Side-Channel Attacks.
735
+ * In D. Naccache and P. Paillier, Eds., Public Key Cryptography, vol. 2274 of Lecture Notes in Computer Science, pages 335-345. Springer-Verlag, 2002.
736
+ * we find as solution for a unified addition/doubling formula:
737
+ * lambda = ((x1 + x2)^2 - x1 * x2 + a) / (y1 + y2), with a = 0 for secp256k1's curve equation.
738
+ * x3 = lambda^2 - (x1 + x2)
739
+ * 2*y3 = lambda * (x1 + x2 - 2 * x3) - (y1 + y2).
740
+ *
741
+ * Substituting x_i = Xi / Zi^2 and yi = Yi / Zi^3, for i=1,2,3, gives:
742
+ * U1 = X1*Z2^2, U2 = X2*Z1^2
743
+ * S1 = Y1*Z2^3, S2 = Y2*Z1^3
744
+ * Z = Z1*Z2
745
+ * T = U1+U2
746
+ * M = S1+S2
747
+ * Q = -T*M^2
748
+ * R = T^2-U1*U2
749
+ * X3 = R^2+Q
750
+ * Y3 = -(R*(2*X3+Q)+M^4)/2
751
+ * Z3 = M*Z
752
+ * (Note that the paper uses xi = Xi / Zi and yi = Yi / Zi instead.)
753
+ *
754
+ * This formula has the benefit of being the same for both addition
755
+ * of distinct points and doubling. However, it breaks down in the
756
+ * case that either point is infinity, or that y1 = -y2. We handle
757
+ * these cases in the following ways:
758
+ *
759
+ * - If b is infinity we simply bail by means of a VERIFY_CHECK.
760
+ *
761
+ * - If a is infinity, we detect this, and at the end of the
762
+ * computation replace the result (which will be meaningless,
763
+ * but we compute to be constant-time) with b.x : b.y : 1.
764
+ *
765
+ * - If a = -b, we have y1 = -y2, which is a degenerate case.
766
+ * But here the answer is infinity, so we simply set the
767
+ * infinity flag of the result, overriding the computed values
768
+ * without even needing to cmov.
769
+ *
770
+ * - If y1 = -y2 but x1 != x2, which does occur thanks to certain
771
+ * properties of our curve (specifically, 1 has nontrivial cube
772
+ * roots in our field, and the curve equation has no x coefficient)
773
+ * then the answer is not infinity but also not given by the above
774
+ * equation. In this case, we cmov in place an alternate expression
775
+ * for lambda. Specifically (y1 - y2)/(x1 - x2). Where both these
776
+ * expressions for lambda are defined, they are equal, and can be
777
+ * obtained from each other by multiplication by (y1 + y2)/(y1 + y2)
778
+ * then substitution of x^3 + 7 for y^2 (using the curve equation).
779
+ * For all pairs of nonzero points (a, b) at least one is defined,
780
+ * so this covers everything.
781
+ */
782
+
783
+ nostr_native_secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */
784
+ u1 = a->x; /* u1 = U1 = X1*Z2^2 (GEJ_X_M) */
785
+ nostr_native_secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */
786
+ s1 = a->y; /* s1 = S1 = Y1*Z2^3 (GEJ_Y_M) */
787
+ nostr_native_secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z1^2 (1) */
788
+ nostr_native_secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */
789
+ t = u1; nostr_native_secp256k1_fe_add(&t, &u2); /* t = T = U1+U2 (GEJ_X_M+1) */
790
+ m = s1; nostr_native_secp256k1_fe_add(&m, &s2); /* m = M = S1+S2 (GEJ_Y_M+1) */
791
+ nostr_native_secp256k1_fe_sqr(&rr, &t); /* rr = T^2 (1) */
792
+ nostr_native_secp256k1_fe_negate(&m_alt, &u2, 1); /* Malt = -X2*Z1^2 (2) */
793
+ nostr_native_secp256k1_fe_mul(&tt, &u1, &m_alt); /* tt = -U1*U2 (1) */
794
+ nostr_native_secp256k1_fe_add(&rr, &tt); /* rr = R = T^2-U1*U2 (2) */
795
+ /* If lambda = R/M = R/0 we have a problem (except in the "trivial"
796
+ * case that Z = z1z2 = 0, and this is special-cased later on). */
797
+ degenerate = nostr_native_secp256k1_fe_normalizes_to_zero(&m);
798
+ /* This only occurs when y1 == -y2 and x1^3 == x2^3, but x1 != x2.
799
+ * This means either x1 == beta*x2 or beta*x1 == x2, where beta is
800
+ * a nontrivial cube root of one. In either case, an alternate
801
+ * non-indeterminate expression for lambda is (y1 - y2)/(x1 - x2),
802
+ * so we set R/M equal to this. */
803
+ rr_alt = s1;
804
+ nostr_native_secp256k1_fe_mul_int(&rr_alt, 2); /* rr_alt = Y1*Z2^3 - Y2*Z1^3 (GEJ_Y_M*2) */
805
+ nostr_native_secp256k1_fe_add(&m_alt, &u1); /* Malt = X1*Z2^2 - X2*Z1^2 (GEJ_X_M+2) */
806
+
807
+ nostr_native_secp256k1_fe_cmov(&rr_alt, &rr, !degenerate); /* rr_alt (GEJ_Y_M*2) */
808
+ nostr_native_secp256k1_fe_cmov(&m_alt, &m, !degenerate); /* m_alt (GEJ_X_M+2) */
809
+ /* Now Ralt / Malt = lambda and is guaranteed not to be Ralt / 0.
810
+ * From here on out Ralt and Malt represent the numerator
811
+ * and denominator of lambda; R and M represent the explicit
812
+ * expressions x1^2 + x2^2 + x1x2 and y1 + y2. */
813
+ nostr_native_secp256k1_fe_sqr(&n, &m_alt); /* n = Malt^2 (1) */
814
+ nostr_native_secp256k1_fe_negate(&q, &t,
815
+ SECP256K1_GEJ_X_MAGNITUDE_MAX + 1); /* q = -T (GEJ_X_M+2) */
816
+ nostr_native_secp256k1_fe_mul(&q, &q, &n); /* q = Q = -T*Malt^2 (1) */
817
+ /* These two lines use the observation that either M == Malt or M == 0,
818
+ * so M^3 * Malt is either Malt^4 (which is computed by squaring), or
819
+ * zero (which is "computed" by cmov). So the cost is one squaring
820
+ * versus two multiplications. */
821
+ nostr_native_secp256k1_fe_sqr(&n, &n); /* n = Malt^4 (1) */
822
+ nostr_native_secp256k1_fe_cmov(&n, &m, degenerate); /* n = M^3 * Malt (GEJ_Y_M+1) */
823
+ nostr_native_secp256k1_fe_sqr(&t, &rr_alt); /* t = Ralt^2 (1) */
824
+ nostr_native_secp256k1_fe_mul(&r->z, &a->z, &m_alt); /* r->z = Z3 = Malt*Z (1) */
825
+ nostr_native_secp256k1_fe_add(&t, &q); /* t = Ralt^2 + Q (2) */
826
+ r->x = t; /* r->x = X3 = Ralt^2 + Q (2) */
827
+ nostr_native_secp256k1_fe_mul_int(&t, 2); /* t = 2*X3 (4) */
828
+ nostr_native_secp256k1_fe_add(&t, &q); /* t = 2*X3 + Q (5) */
829
+ nostr_native_secp256k1_fe_mul(&t, &t, &rr_alt); /* t = Ralt*(2*X3 + Q) (1) */
830
+ nostr_native_secp256k1_fe_add(&t, &n); /* t = Ralt*(2*X3 + Q) + M^3*Malt (GEJ_Y_M+2) */
831
+ nostr_native_secp256k1_fe_negate(&r->y, &t,
832
+ SECP256K1_GEJ_Y_MAGNITUDE_MAX + 2); /* r->y = -(Ralt*(2*X3 + Q) + M^3*Malt) (GEJ_Y_M+3) */
833
+ nostr_native_secp256k1_fe_half(&r->y); /* r->y = Y3 = -(Ralt*(2*X3 + Q) + M^3*Malt)/2 ((GEJ_Y_M+3)/2 + 1) */
834
+
835
+ /* In case a->infinity == 1, replace r with (b->x, b->y, 1). */
836
+ nostr_native_secp256k1_fe_cmov(&r->x, &b->x, a->infinity);
837
+ nostr_native_secp256k1_fe_cmov(&r->y, &b->y, a->infinity);
838
+ nostr_native_secp256k1_fe_cmov(&r->z, &nostr_native_secp256k1_fe_one, a->infinity);
839
+
840
+ /* Set r->infinity if r->z is 0.
841
+ *
842
+ * If a->infinity is set, then r->infinity = (r->z == 0) = (1 == 0) = false,
843
+ * which is correct because the function assumes that b is not infinity.
844
+ *
845
+ * Now assume !a->infinity. This implies Z = Z1 != 0.
846
+ *
847
+ * Case y1 = -y2:
848
+ * In this case we could have a = -b, namely if x1 = x2.
849
+ * We have degenerate = true, r->z = (x1 - x2) * Z.
850
+ * Then r->infinity = ((x1 - x2)Z == 0) = (x1 == x2) = (a == -b).
851
+ *
852
+ * Case y1 != -y2:
853
+ * In this case, we can't have a = -b.
854
+ * We have degenerate = false, r->z = (y1 + y2) * Z.
855
+ * Then r->infinity = ((y1 + y2)Z == 0) = (y1 == -y2) = false. */
856
+ r->infinity = nostr_native_secp256k1_fe_normalizes_to_zero(&r->z);
857
+
858
+ SECP256K1_GEJ_VERIFY(r);
859
+ }
860
+
861
+ static void nostr_native_secp256k1_gej_rescale(nostr_native_secp256k1_gej *r, const nostr_native_secp256k1_fe *s) {
862
+ /* Operations: 4 mul, 1 sqr */
863
+ nostr_native_secp256k1_fe zz;
864
+ SECP256K1_GEJ_VERIFY(r);
865
+ SECP256K1_FE_VERIFY(s);
866
+ VERIFY_CHECK(!nostr_native_secp256k1_fe_normalizes_to_zero_var(s));
867
+
868
+ nostr_native_secp256k1_fe_sqr(&zz, s);
869
+ nostr_native_secp256k1_fe_mul(&r->x, &r->x, &zz); /* r->x *= s^2 */
870
+ nostr_native_secp256k1_fe_mul(&r->y, &r->y, &zz);
871
+ nostr_native_secp256k1_fe_mul(&r->y, &r->y, s); /* r->y *= s^3 */
872
+ nostr_native_secp256k1_fe_mul(&r->z, &r->z, s); /* r->z *= s */
873
+
874
+ SECP256K1_GEJ_VERIFY(r);
875
+ }
876
+
877
+ static void nostr_native_secp256k1_ge_to_storage(nostr_native_secp256k1_ge_storage *r, const nostr_native_secp256k1_ge *a) {
878
+ nostr_native_secp256k1_fe x, y;
879
+ SECP256K1_GE_VERIFY(a);
880
+ VERIFY_CHECK(!a->infinity);
881
+
882
+ x = a->x;
883
+ nostr_native_secp256k1_fe_normalize(&x);
884
+ y = a->y;
885
+ nostr_native_secp256k1_fe_normalize(&y);
886
+ nostr_native_secp256k1_fe_to_storage(&r->x, &x);
887
+ nostr_native_secp256k1_fe_to_storage(&r->y, &y);
888
+ }
889
+
890
+ static void nostr_native_secp256k1_ge_from_storage(nostr_native_secp256k1_ge *r, const nostr_native_secp256k1_ge_storage *a) {
891
+ nostr_native_secp256k1_fe_from_storage(&r->x, &a->x);
892
+ nostr_native_secp256k1_fe_from_storage(&r->y, &a->y);
893
+ r->infinity = 0;
894
+
895
+ SECP256K1_GE_VERIFY(r);
896
+ }
897
+
898
+ static SECP256K1_INLINE void nostr_native_secp256k1_gej_cmov(nostr_native_secp256k1_gej *r, const nostr_native_secp256k1_gej *a, int flag) {
899
+ SECP256K1_GEJ_VERIFY(r);
900
+ SECP256K1_GEJ_VERIFY(a);
901
+ VERIFY_CHECK(flag == 0 || flag == 1);
902
+
903
+ nostr_native_secp256k1_fe_cmov(&r->x, &a->x, flag);
904
+ nostr_native_secp256k1_fe_cmov(&r->y, &a->y, flag);
905
+ nostr_native_secp256k1_fe_cmov(&r->z, &a->z, flag);
906
+ r->infinity ^= (r->infinity ^ a->infinity) & flag;
907
+
908
+ SECP256K1_GEJ_VERIFY(r);
909
+ }
910
+
911
+ static SECP256K1_INLINE void nostr_native_secp256k1_ge_storage_cmov(nostr_native_secp256k1_ge_storage *r, const nostr_native_secp256k1_ge_storage *a, int flag) {
912
+ VERIFY_CHECK(flag == 0 || flag == 1);
913
+ nostr_native_secp256k1_fe_storage_cmov(&r->x, &a->x, flag);
914
+ nostr_native_secp256k1_fe_storage_cmov(&r->y, &a->y, flag);
915
+ }
916
+
917
+ static void nostr_native_secp256k1_ge_mul_lambda(nostr_native_secp256k1_ge *r, const nostr_native_secp256k1_ge *a) {
918
+ SECP256K1_GE_VERIFY(a);
919
+
920
+ *r = *a;
921
+ nostr_native_secp256k1_fe_mul(&r->x, &r->x, &nostr_native_secp256k1_const_beta);
922
+
923
+ SECP256K1_GE_VERIFY(r);
924
+ }
925
+
926
+ static int nostr_native_secp256k1_ge_is_in_correct_subgroup(const nostr_native_secp256k1_ge* ge) {
927
+ #ifdef EXHAUSTIVE_TEST_ORDER
928
+ nostr_native_secp256k1_gej out;
929
+ int i;
930
+ SECP256K1_GE_VERIFY(ge);
931
+
932
+ /* A very simple EC multiplication ladder that avoids a dependency on ecmult. */
933
+ nostr_native_secp256k1_gej_set_infinity(&out);
934
+ for (i = 0; i < 32; ++i) {
935
+ nostr_native_secp256k1_gej_double_var(&out, &out, NULL);
936
+ if ((((uint32_t)EXHAUSTIVE_TEST_ORDER) >> (31 - i)) & 1) {
937
+ nostr_native_secp256k1_gej_add_ge_var(&out, &out, ge, NULL);
938
+ }
939
+ }
940
+ return nostr_native_secp256k1_gej_is_infinity(&out);
941
+ #else
942
+ SECP256K1_GE_VERIFY(ge);
943
+
944
+ (void)ge;
945
+ /* The real secp256k1 group has cofactor 1, so the subgroup is the entire curve. */
946
+ return 1;
947
+ #endif
948
+ }
949
+
950
+ static int nostr_native_secp256k1_ge_x_on_curve_var(const nostr_native_secp256k1_fe *x) {
951
+ nostr_native_secp256k1_fe c;
952
+ nostr_native_secp256k1_fe_sqr(&c, x);
953
+ nostr_native_secp256k1_fe_mul(&c, &c, x);
954
+ nostr_native_secp256k1_fe_add_int(&c, SECP256K1_B);
955
+ return nostr_native_secp256k1_fe_is_square_var(&c);
956
+ }
957
+
958
+ static int nostr_native_secp256k1_ge_x_frac_on_curve_var(const nostr_native_secp256k1_fe *xn, const nostr_native_secp256k1_fe *xd) {
959
+ /* We want to determine whether (xn/xd) is on the curve.
960
+ *
961
+ * (xn/xd)^3 + 7 is square <=> xd*xn^3 + 7*xd^4 is square (multiplying by xd^4, a square).
962
+ */
963
+ nostr_native_secp256k1_fe r, t;
964
+ VERIFY_CHECK(!nostr_native_secp256k1_fe_normalizes_to_zero_var(xd));
965
+
966
+ nostr_native_secp256k1_fe_mul(&r, xd, xn); /* r = xd*xn */
967
+ nostr_native_secp256k1_fe_sqr(&t, xn); /* t = xn^2 */
968
+ nostr_native_secp256k1_fe_mul(&r, &r, &t); /* r = xd*xn^3 */
969
+ nostr_native_secp256k1_fe_sqr(&t, xd); /* t = xd^2 */
970
+ nostr_native_secp256k1_fe_sqr(&t, &t); /* t = xd^4 */
971
+ VERIFY_CHECK(SECP256K1_B <= 31);
972
+ nostr_native_secp256k1_fe_mul_int(&t, SECP256K1_B); /* t = 7*xd^4 */
973
+ nostr_native_secp256k1_fe_add(&r, &t); /* r = xd*xn^3 + 7*xd^4 */
974
+ return nostr_native_secp256k1_fe_is_square_var(&r);
975
+ }
976
+
977
+ static void nostr_native_secp256k1_ge_to_bytes(unsigned char *buf, const nostr_native_secp256k1_ge *a) {
978
+ nostr_native_secp256k1_ge_storage s;
979
+
980
+ /* We require that the nostr_native_secp256k1_ge_storage type is exactly 64 bytes.
981
+ * This is formally not guaranteed by the C standard, but should hold on any
982
+ * sane compiler in the real world. */
983
+ STATIC_ASSERT(sizeof(nostr_native_secp256k1_ge_storage) == 64);
984
+ VERIFY_CHECK(!nostr_native_secp256k1_ge_is_infinity(a));
985
+ nostr_native_secp256k1_ge_to_storage(&s, a);
986
+ memcpy(buf, &s, 64);
987
+ }
988
+
989
+ static void nostr_native_secp256k1_ge_from_bytes(nostr_native_secp256k1_ge *r, const unsigned char *buf) {
990
+ nostr_native_secp256k1_ge_storage s;
991
+
992
+ STATIC_ASSERT(sizeof(nostr_native_secp256k1_ge_storage) == 64);
993
+ memcpy(&s, buf, 64);
994
+ nostr_native_secp256k1_ge_from_storage(r, &s);
995
+ }
996
+
997
+ static void nostr_native_secp256k1_ge_to_bytes_ext(unsigned char *data, const nostr_native_secp256k1_ge *ge) {
998
+ if (nostr_native_secp256k1_ge_is_infinity(ge)) {
999
+ memset(data, 0, 64);
1000
+ } else {
1001
+ nostr_native_secp256k1_ge_to_bytes(data, ge);
1002
+ }
1003
+ }
1004
+
1005
+ static void nostr_native_secp256k1_ge_from_bytes_ext(nostr_native_secp256k1_ge *ge, const unsigned char *data) {
1006
+ static const unsigned char zeros[64] = { 0 };
1007
+ if (nostr_native_secp256k1_memcmp_var(data, zeros, sizeof(zeros)) == 0) {
1008
+ nostr_native_secp256k1_ge_set_infinity(ge);
1009
+ } else {
1010
+ nostr_native_secp256k1_ge_from_bytes(ge, data);
1011
+ }
1012
+ }
1013
+
1014
+ #endif /* SECP256K1_GROUP_IMPL_H */