@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,396 @@
1
+ #ifndef SECP256K1_SILENTPAYMENTS_H
2
+ #define SECP256K1_SILENTPAYMENTS_H
3
+
4
+ #include <stdint.h>
5
+ #include "secp256k1.h"
6
+ #include "secp256k1_extrakeys.h"
7
+
8
+ #ifdef __cplusplus
9
+ extern "C" {
10
+ #endif
11
+
12
+ /** This module provides an implementation for Silent Payments, as specified in
13
+ * BIP352. This particularly involves the creation of input tweak data by
14
+ * summing up secret or public keys and the derivation of a shared secret using
15
+ * Elliptic Curve Diffie-Hellman. Combined are either:
16
+ * - spender's secret keys and recipient's public key (a * B, sender side)
17
+ * - spender's public keys and recipient's secret key (A * b, recipient side)
18
+ * With this result, the necessary key material for ultimately creating/scanning
19
+ * or spending Silent Payments outputs can be determined.
20
+ *
21
+ * Note that this module is _not_ a full implementation of BIP352, as it
22
+ * inherently doesn't deal with higher-level concepts like addresses, output
23
+ * script types or transactions. The intent is to provide a module for
24
+ * abstracting away the elliptic-curve operations required for the protocol. For
25
+ * any wallet software already using libsecp256k1, this API should provide all
26
+ * the functions needed for a Silent Payments implementation without requiring
27
+ * any further elliptic-curve operations from the wallet.
28
+ */
29
+
30
+ /* Maximum number of Silent Payments recipients per group (i.e.
31
+ * recipients sharing the same scan public key) as per BIP-352 */
32
+ #define SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT 2323
33
+
34
+ /** The data from a single recipient address
35
+ *
36
+ * This struct serves as an input argument to `silentpayments_sender_create_outputs`.
37
+ *
38
+ * `index` must be set to the position (starting with 0) of this recipient in the
39
+ * `recipients` array passed to `silentpayments_sender_create_outputs`. It is
40
+ * used to map the returned generated outputs back to the original recipient.
41
+ *
42
+ * Note:
43
+ * The spend public key named `spend_pubkey` may have been optionally tweaked with
44
+ * a label by the recipient. Whether `spend_pubkey` has actually been tagged with
45
+ * a label is irrelevant for the sender. As a documentation convention in this API,
46
+ * `unlabeled_spend_pubkey` is used to indicate when the unlabeled spend public key
47
+ * must be used.
48
+ */
49
+ typedef struct nostr_native_secp256k1_silentpayments_recipient {
50
+ nostr_native_secp256k1_pubkey scan_pubkey;
51
+ nostr_native_secp256k1_pubkey spend_pubkey;
52
+ size_t index;
53
+ } nostr_native_secp256k1_silentpayments_recipient;
54
+
55
+ /** Create Silent Payments outputs for recipient(s).
56
+ *
57
+ * Given a list of n secret keys a_1...a_n (one for each Silent Payments
58
+ * eligible input to spend), a serialized outpoint, and a list of recipients,
59
+ * create the taproot outputs. Inputs with conditional branches or multiple
60
+ * public keys are excluded from Silent Payments eligible inputs; see BIP352
61
+ * for more information.
62
+ *
63
+ * `outpoint_smallest36` refers to the smallest outpoint lexicographically
64
+ * from the transaction inputs (both Silent Payments eligible and non-eligible
65
+ * inputs). This value MUST be the smallest outpoint out of all of the
66
+ * transaction inputs, otherwise the recipient will be unable to find the
67
+ * payment. Determining the smallest outpoint from the list of transaction
68
+ * inputs is the responsibility of the caller. It is strongly recommended
69
+ * that implementations ensure they are doing this correctly by using the
70
+ * test vectors from BIP352.
71
+ *
72
+ * When creating more than one generated output, all of the generated outputs
73
+ * MUST be included in the final transaction. Dropping any of the generated
74
+ * outputs from the final transaction may make all or some of the outputs
75
+ * unfindable by the recipient.
76
+ *
77
+ * Returns: 1 if creation of outputs was successful.
78
+ * 0 on failure, i.e., when one of the following occurs:
79
+ * - The size of any group (i.e. recipients sharing the same scan public key)
80
+ * exceeds the protocol limit SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT.
81
+ * - The sum of all input secret keys is 0.
82
+ * (This occurs only with negligible probability if at least one of the
83
+ * input secret keys is uniformly random and independent of all other keys.)
84
+ * - An invalid output public key is created. (This can only happen for an
85
+ * adversarially chosen recipient spend public key.)
86
+ *
87
+ * Args: ctx: pointer to a context object
88
+ * (not nostr_native_secp256k1_context_static).
89
+ * Out: generated_outputs: pointer to an array of pointers to xonly public keys,
90
+ * one per recipient.
91
+ * The outputs are ordered to match the original
92
+ * ordering of the recipient objects, i.e.,
93
+ * `generated_outputs[0]` is the generated output
94
+ * for the `nostr_native_secp256k1_silentpayments_recipient` object
95
+ * with index = 0.
96
+ * In: recipients: pointer to an array of pointers to Silent Payments
97
+ * recipients, where each recipient is a scan public
98
+ * key, a spend public key, and an index indicating
99
+ * its position in the original ordering. This function
100
+ * may reorder the pointers to the recipient objects
101
+ * within the array, i.e., after the call (including on
102
+ * failure), the index fields of the recipient objects
103
+ * may no longer correspond to the positions in the
104
+ * array. Multiple recipient objects with the same scan
105
+ * public key and/or same spend public key can be passed
106
+ * if they carry different indices.
107
+ * n_recipients: the size of the recipients array.
108
+ * outpoint_smallest36: serialized (36-byte) smallest outpoint
109
+ * (lexicographically) from the transaction inputs
110
+ * keypairs: pointer to an array of pointers to taproot
111
+ * keypair inputs (can be NULL if no secret keys
112
+ * of taproot inputs are used)
113
+ * n_keypairs: the size of the keypairs array.
114
+ * seckeys: pointer to an array of pointers to 32-byte
115
+ * secret keys of non-taproot inputs (can be NULL
116
+ * if no secret keys of non-taproot inputs are
117
+ * used)
118
+ * n_seckeys: the size of the seckeys array.
119
+ */
120
+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int nostr_native_secp256k1_silentpayments_sender_create_outputs(
121
+ const nostr_native_secp256k1_context *ctx,
122
+ nostr_native_secp256k1_xonly_pubkey **generated_outputs,
123
+ const nostr_native_secp256k1_silentpayments_recipient **recipients,
124
+ size_t n_recipients,
125
+ const unsigned char *outpoint_smallest36,
126
+ const nostr_native_secp256k1_keypair * const *keypairs,
127
+ size_t n_keypairs,
128
+ const unsigned char * const *seckeys,
129
+ size_t n_seckeys
130
+ ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
131
+
132
+ /** Opaque data structure that holds a Silent Payments label.
133
+ *
134
+ * Guaranteed to be 68 bytes in size. Serialized and parsed with
135
+ * `nostr_native_secp256k1_silentpayments_recipient_label_serialize` and
136
+ * `nostr_native_secp256k1_silentpayments_recipient_label_parse`.
137
+ */
138
+ typedef struct nostr_native_secp256k1_silentpayments_label {
139
+ unsigned char data[68];
140
+ } nostr_native_secp256k1_silentpayments_label;
141
+
142
+ /** Parse a Silent Payments label.
143
+ *
144
+ * Returns: 1 when the label could be parsed, 0 otherwise.
145
+ * Args: ctx: pointer to a context object
146
+ * Out: label: pointer to a label object
147
+ * In: in33: pointer to the 33-byte label to be parsed
148
+ */
149
+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int nostr_native_secp256k1_silentpayments_recipient_label_parse(
150
+ const nostr_native_secp256k1_context *ctx,
151
+ nostr_native_secp256k1_silentpayments_label *label,
152
+ const unsigned char *in33
153
+ ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
154
+
155
+ /** Serialize a Silent Payments label
156
+ *
157
+ * Returns: 1 always
158
+ * Args: ctx: pointer to a context object
159
+ * Out: out33: pointer to a 33-byte array to store the serialized label
160
+ * In: label: pointer to the label
161
+ */
162
+ SECP256K1_API int nostr_native_secp256k1_silentpayments_recipient_label_serialize(
163
+ const nostr_native_secp256k1_context *ctx,
164
+ unsigned char *out33,
165
+ const nostr_native_secp256k1_silentpayments_label *label
166
+ ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
167
+
168
+ /** Create Silent Payments label tweak and label.
169
+ *
170
+ * Given a recipient's 32 byte scan key and a label integer m, calculate the
171
+ * corresponding label tweak and label:
172
+ *
173
+ * label_tweak = hash(scan_key || m)
174
+ * label = label_tweak * G
175
+ *
176
+ * Returns: 1 if label tweak and label creation was successful.
177
+ * 0 if scan_key32 is invalid or the hash output label_tweak32 is
178
+ * not a valid scalar (negligible probability per hash evaluation).
179
+ *
180
+ * WARNING: Creating a large number of labels may significantly degrade
181
+ * scanning performance in certain Silent Payments wallet implementations,
182
+ * such as light clients. The scanning function provided in this module,
183
+ * which is designed for full nodes, performs consistently even with hundreds
184
+ * of thousands of labels. Other implementations may not share this property
185
+ * or may be unable to use it due to lacking full transaction data.
186
+ *
187
+ * To maximize wallet interoperability, it is recommended to create only
188
+ * the change label (m = 0) and avoid distributing labeled addresses.
189
+ *
190
+ * Args: ctx: pointer to a context object
191
+ * (not nostr_native_secp256k1_context_static)
192
+ * Out: label: pointer to the resulting label
193
+ * label_tweak32: pointer to the 32 byte label tweak
194
+ * In: scan_key32: pointer to the recipient's 32 byte scan key
195
+ * m: integer for the m-th label (0 is used for change outputs)
196
+ */
197
+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int nostr_native_secp256k1_silentpayments_recipient_label_create(
198
+ const nostr_native_secp256k1_context *ctx,
199
+ nostr_native_secp256k1_silentpayments_label *label,
200
+ unsigned char *label_tweak32,
201
+ const unsigned char *scan_key32,
202
+ uint32_t m
203
+ ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
204
+
205
+ /** Create Silent Payments labeled spend public key.
206
+ *
207
+ * Given a recipient's spend public key and a label, calculate the
208
+ * corresponding labeled spend public key:
209
+ *
210
+ * labeled_spend_pubkey = unlabeled_spend_pubkey + label
211
+ *
212
+ * The result is used by the recipient to create a Silent Payments address,
213
+ * consisting of the serialized and concatenated scan public key and
214
+ * (labeled) spend public key.
215
+ *
216
+ * Returns: 1 if labeled spend public key creation was successful.
217
+ * 0 if spend pubkey and label sum to zero (negligible probability for
218
+ * labels created according to BIP352).
219
+ *
220
+ * Args: ctx: pointer to a context object
221
+ * Out: labeled_spend_pubkey: pointer to the resulting labeled spend public key
222
+ * In: unlabeled_spend_pubkey: pointer to the recipient's unlabeled spend public key
223
+ * label: pointer to the recipient's label
224
+ */
225
+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int nostr_native_secp256k1_silentpayments_recipient_create_labeled_spend_pubkey(
226
+ const nostr_native_secp256k1_context *ctx,
227
+ nostr_native_secp256k1_pubkey *labeled_spend_pubkey,
228
+ const nostr_native_secp256k1_pubkey *unlabeled_spend_pubkey,
229
+ const nostr_native_secp256k1_silentpayments_label *label
230
+ ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
231
+
232
+ /** Opaque data structure that holds Silent Payments prevouts summary data.
233
+ *
234
+ * The exact representation of data inside is implementation defined and not
235
+ * guaranteed to be portable between different platforms or versions. It is
236
+ * however guaranteed to be 101 bytes in size, and can be safely copied/moved.
237
+ * This structure does not contain secret data. It can be created with
238
+ * `nostr_native_secp256k1_silentpayments_recipient_prevouts_summary_create`.
239
+ */
240
+ typedef struct nostr_native_secp256k1_silentpayments_prevouts_summary {
241
+ unsigned char data[101];
242
+ } nostr_native_secp256k1_silentpayments_prevouts_summary;
243
+
244
+ /** Compute Silent Payments prevouts summary from prevout public keys and transaction
245
+ * inputs.
246
+ *
247
+ * Given a list of n public keys A_1...A_n (one for each Silent Payments
248
+ * eligible input to spend) and a serialized outpoint_smallest36, create a
249
+ * `prevouts_summary` object. This object summarizes the prevout data from the
250
+ * transaction inputs needed for scanning.
251
+ *
252
+ * `outpoint_smallest36` refers to the smallest outpoint lexicographically
253
+ * from the transaction inputs (both Silent Payments eligible and non-eligible
254
+ * inputs). This value MUST be the smallest outpoint out of all of the
255
+ * transaction inputs, otherwise the recipient will be unable to find the
256
+ * payment.
257
+ *
258
+ * The public keys have to be passed in via two different parameter pairs, one
259
+ * for regular and one for x-only public keys, in order to avoid the need of
260
+ * users converting to a common public key format before calling this function.
261
+ * The resulting data can be used for scanning on the recipient side.
262
+ *
263
+ * Returns: 1 if prevouts summary creation was successful.
264
+ * 0 if the transaction is not a Silent Payments transaction.
265
+ *
266
+ * Args: ctx: pointer to a context object
267
+ * Out: prevouts_summary: pointer to prevouts_summary object containing the
268
+ * summed public key and input_hash.
269
+ * In: outpoint_smallest36: serialized smallest outpoint (lexicographically)
270
+ * from the transaction inputs
271
+ * xonly_pubkeys: pointer to an array of pointers to taproot
272
+ * x-only public keys (can be NULL if no taproot
273
+ * inputs are used)
274
+ * n_xonly_pubkeys: the size of the xonly_pubkeys array.
275
+ * pubkeys: pointer to an array of pointers to non-taproot
276
+ * public keys (can be NULL if no non-taproot
277
+ * inputs are used)
278
+ * n_pubkeys: the size of the pubkeys array.
279
+ */
280
+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int nostr_native_secp256k1_silentpayments_recipient_prevouts_summary_create(
281
+ const nostr_native_secp256k1_context *ctx,
282
+ nostr_native_secp256k1_silentpayments_prevouts_summary *prevouts_summary,
283
+ const unsigned char *outpoint_smallest36,
284
+ const nostr_native_secp256k1_xonly_pubkey * const *xonly_pubkeys,
285
+ size_t n_xonly_pubkeys,
286
+ const nostr_native_secp256k1_pubkey * const *pubkeys,
287
+ size_t n_pubkeys
288
+ ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
289
+
290
+ /** Type of callback function for label lookups
291
+ *
292
+ * A function of this type will be used to retrieve the label tweak for a given
293
+ * label during scanning. A typical implementation will perform a lookup in a
294
+ * key-value store called the "label cache".
295
+ *
296
+ * For creating the label cache data,
297
+ * `nostr_native_secp256k1_silentpayments_recipient_label_create` and
298
+ * `nostr_native_secp256k1_silentpayments_recipient_label_serialize` can be used.
299
+ *
300
+ * Returns: pointer to the 32-byte label tweak if there is a match.
301
+ * NULL pointer if there is no match.
302
+ *
303
+ * In: label: pointer to the serialized 33-byte label to check
304
+ * (computed during scanning)
305
+ * label_context: pointer to the recipient's label cache.
306
+ */
307
+ typedef const unsigned char* (*nostr_native_secp256k1_silentpayments_label_lookup)(const unsigned char* label33, const void* label_context);
308
+
309
+ /** Found outputs struct
310
+ *
311
+ * Struct for holding a found output along with data needed to spend it later.
312
+ *
313
+ * output: the x-only public key for the taproot output
314
+ * tweak: the 32-byte tweak needed to spend the output
315
+ * found_with_label: boolean value to indicate if the output was sent to a
316
+ * labeled address. If true, label will be set to a valid value.
317
+ * label: the label used. If found_with_label = false, this is set to
318
+ * an invalid value.
319
+ */
320
+ typedef struct nostr_native_secp256k1_silentpayments_found_output {
321
+ nostr_native_secp256k1_xonly_pubkey output;
322
+ unsigned char tweak[32];
323
+ int found_with_label;
324
+ nostr_native_secp256k1_silentpayments_label label;
325
+ } nostr_native_secp256k1_silentpayments_found_output;
326
+
327
+ /** Scan for Silent Payments transaction outputs.
328
+ *
329
+ * Given a prevouts_summary object, a recipient's 32 byte scan key and spend public key,
330
+ * and the relevant transaction outputs, scan for outputs belonging to
331
+ * the recipient and return the tweak(s) needed for spending the output(s). An
332
+ * optional label_lookup callback function and label_context can be passed if
333
+ * the recipient uses labels. This allows for checking if a label exists in
334
+ * the recipients label cache and retrieving the label tweak during scanning.
335
+ *
336
+ * If used, the `label_lookup` function must return a pointer to a 32-byte label
337
+ * tweak if the label is found, or NULL otherwise. The returned pointer must remain
338
+ * valid until the next call to `label_lookup` or until the function returns,
339
+ * whichever comes first. It is not retained beyond that.
340
+ *
341
+ * For creating the label cache, `nostr_native_secp256k1_silentpayments_recipient_label_create`
342
+ * and `nostr_native_secp256k1_silentpayments_recipient_label_serialize` can be used.
343
+ *
344
+ * Note:
345
+ * Scanning is bounded by SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT and may
346
+ * miss outputs if a transaction contains more outputs for a single scan public
347
+ * key group than this limit.
348
+ *
349
+ * Returns: 1 if output scanning was successful.
350
+ * 0 if the transaction is not a Silent Payments transaction,
351
+ * or if the arguments are invalid.
352
+ *
353
+ * Args: ctx: pointer to a context object
354
+ * Out: found_outputs: pointer to an array of pointers to found
355
+ * output objects. The found outputs array MUST
356
+ * have the same length as the tx_outputs array.
357
+ * n_found_outputs: pointer to an integer indicating the final
358
+ * size of the found outputs array. This number
359
+ * represents the number of outputs found while
360
+ * scanning (0 if none are found). Can't be larger than
361
+ * SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT.
362
+ * In: tx_outputs: pointer to the transaction's x-only public key outputs,
363
+ * in their original transaction (vout) order
364
+ * n_tx_outputs: the size of the tx_outputs array.
365
+ * scan_key32: pointer to the recipient's 32 byte scan key. The scan
366
+ * key is valid if it passes nostr_native_secp256k1_ec_seckey_verify
367
+ * prevouts_summary: pointer to the transaction prevouts summary data (see
368
+ * `nostr_native_secp256k1_silentpayments_recipient_prevouts_summary_create`).
369
+ * unlabeled_spend_pubkey: pointer to the recipient's unlabeled spend public key
370
+ * label_lookup: pointer to a callback function for looking up
371
+ * a label value. This function takes a serialized 33-byte
372
+ * label as an argument and returns a pointer to the
373
+ * 32-byte label tweak if the label exists, otherwise
374
+ * returns a NULL pointer (NULL if labels are not
375
+ * used)
376
+ * label_context: pointer to a label context object (NULL if
377
+ * labels are not used or context is not needed)
378
+ */
379
+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int nostr_native_secp256k1_silentpayments_recipient_scan_outputs(
380
+ const nostr_native_secp256k1_context *ctx,
381
+ nostr_native_secp256k1_silentpayments_found_output **found_outputs,
382
+ uint32_t *n_found_outputs,
383
+ const nostr_native_secp256k1_xonly_pubkey * const *tx_outputs,
384
+ size_t n_tx_outputs,
385
+ const unsigned char *scan_key32,
386
+ const nostr_native_secp256k1_silentpayments_prevouts_summary *prevouts_summary,
387
+ const nostr_native_secp256k1_pubkey *unlabeled_spend_pubkey,
388
+ nostr_native_secp256k1_silentpayments_label_lookup label_lookup,
389
+ const void *label_context
390
+ ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8);
391
+
392
+ #ifdef __cplusplus
393
+ }
394
+ #endif
395
+
396
+ #endif /* SECP256K1_SILENTPAYMENTS_H */
@@ -0,0 +1,87 @@
1
+ /***********************************************************************
2
+ * Copyright (c) 2020 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_ASSUMPTIONS_H
8
+ #define SECP256K1_ASSUMPTIONS_H
9
+
10
+ #include <limits.h>
11
+
12
+ #include "util.h"
13
+ #if defined(SECP256K1_INT128_NATIVE)
14
+ #include "int128_native.h"
15
+ #endif
16
+
17
+ /* This library, like most software, relies on a number of compiler implementation defined (but not undefined)
18
+ behaviours. Although the behaviours we require are essentially universal we test them specifically here to
19
+ reduce the odds of experiencing an unwelcome surprise.
20
+ */
21
+
22
+ #if defined(__has_attribute)
23
+ # if __has_attribute(__unavailable__)
24
+ __attribute__((__unavailable__("Don't call this function. It only exists because STATIC_ASSERT cannot be used outside a function.")))
25
+ # endif
26
+ #endif
27
+ static void nostr_native_secp256k1_assumption_checker(void) {
28
+ /* Bytes are 8 bits. */
29
+ STATIC_ASSERT(CHAR_BIT == 8);
30
+
31
+ /* No integer promotion for uint32_t. This ensures that we can multiply uintXX_t values where XX >= 32
32
+ without signed overflow, which would be undefined behaviour. */
33
+ STATIC_ASSERT(UINT_MAX <= UINT32_MAX);
34
+
35
+ /* Conversions from unsigned to signed outside of the bounds of the signed type are
36
+ implementation-defined. Verify that they function as reinterpreting the lower
37
+ bits of the input in two's complement notation. Do this for conversions:
38
+ - from uint(N)_t to int(N)_t with negative result
39
+ - from uint(2N)_t to int(N)_t with negative result
40
+ - from int(2N)_t to int(N)_t with negative result
41
+ - from int(2N)_t to int(N)_t with positive result */
42
+
43
+ /* To int8_t. */
44
+ STATIC_ASSERT(((int8_t)(uint8_t)0xAB == (int8_t)-(int8_t)0x55));
45
+ STATIC_ASSERT((int8_t)(uint16_t)0xABCD == (int8_t)-(int8_t)0x33);
46
+ STATIC_ASSERT((int8_t)(int16_t)(uint16_t)0xCDEF == (int8_t)(uint8_t)0xEF);
47
+ STATIC_ASSERT((int8_t)(int16_t)(uint16_t)0x9234 == (int8_t)(uint8_t)0x34);
48
+
49
+ /* To int16_t. */
50
+ STATIC_ASSERT((int16_t)(uint16_t)0xBCDE == (int16_t)-(int16_t)0x4322);
51
+ STATIC_ASSERT((int16_t)(uint32_t)0xA1B2C3D4 == (int16_t)-(int16_t)0x3C2C);
52
+ STATIC_ASSERT((int16_t)(int32_t)(uint32_t)0xC1D2E3F4 == (int16_t)(uint16_t)0xE3F4);
53
+ STATIC_ASSERT((int16_t)(int32_t)(uint32_t)0x92345678 == (int16_t)(uint16_t)0x5678);
54
+
55
+ /* To int32_t. */
56
+ STATIC_ASSERT((int32_t)(uint32_t)0xB2C3D4E5 == (int32_t)-(int32_t)0x4D3C2B1B);
57
+ STATIC_ASSERT((int32_t)(uint64_t)0xA123B456C789D012ULL == (int32_t)-(int32_t)0x38762FEE);
58
+ STATIC_ASSERT((int32_t)(int64_t)(uint64_t)0xC1D2E3F4A5B6C7D8ULL == (int32_t)(uint32_t)0xA5B6C7D8);
59
+ STATIC_ASSERT((int32_t)(int64_t)(uint64_t)0xABCDEF0123456789ULL == (int32_t)(uint32_t)0x23456789);
60
+
61
+ /* To int64_t. */
62
+ STATIC_ASSERT((int64_t)(uint64_t)0xB123C456D789E012ULL == (int64_t)-(int64_t)0x4EDC3BA928761FEEULL);
63
+ #if defined(SECP256K1_INT128_NATIVE)
64
+ STATIC_ASSERT((int64_t)(((uint128_t)0xA1234567B8901234ULL << 64) + 0xC5678901D2345678ULL) == (int64_t)-(int64_t)0x3A9876FE2DCBA988ULL);
65
+ STATIC_ASSERT(((int64_t)(int128_t)(((uint128_t)0xB1C2D3E4F5A6B7C8ULL << 64) + 0xD9E0F1A2B3C4D5E6ULL)) == (int64_t)(uint64_t)0xD9E0F1A2B3C4D5E6ULL);
66
+ STATIC_ASSERT(((int64_t)(int128_t)(((uint128_t)0xABCDEF0123456789ULL << 64) + 0x0123456789ABCDEFULL)) == (int64_t)(uint64_t)0x0123456789ABCDEFULL);
67
+
68
+ /* To int128_t. */
69
+ STATIC_ASSERT((int128_t)(((uint128_t)0xB1234567C8901234ULL << 64) + 0xD5678901E2345678ULL) == (int128_t)(-(int128_t)0x8E1648B3F50E80DCULL * 0x8E1648B3F50E80DDULL + 0x5EA688D5482F9464ULL));
70
+ #endif
71
+
72
+ /* Right shift on negative signed values is implementation defined. Verify that it
73
+ acts as a right shift in two's complement with sign extension (i.e duplicating
74
+ the top bit into newly added bits). */
75
+ STATIC_ASSERT((((int8_t)0xE8) >> 2) == (int8_t)(uint8_t)0xFA);
76
+ STATIC_ASSERT((((int16_t)0xE9AC) >> 4) == (int16_t)(uint16_t)0xFE9A);
77
+ STATIC_ASSERT((((int32_t)0x937C918A) >> 9) == (int32_t)(uint32_t)0xFFC9BE48);
78
+ STATIC_ASSERT((((int64_t)0xA8B72231DF9CF4B9ULL) >> 19) == (int64_t)(uint64_t)0xFFFFF516E4463BF3ULL);
79
+ #if defined(SECP256K1_INT128_NATIVE)
80
+ STATIC_ASSERT((((int128_t)(((uint128_t)0xCD833A65684A0DBCULL << 64) + 0xB349312F71EA7637ULL)) >> 39) == (int128_t)(((uint128_t)0xFFFFFFFFFF9B0674ULL << 64) + 0xCAD0941B79669262ULL));
81
+ #endif
82
+
83
+ /* This function is not supposed to be called. */
84
+ VERIFY_CHECK(0);
85
+ }
86
+
87
+ #endif /* SECP256K1_ASSUMPTIONS_H */
@@ -0,0 +1,117 @@
1
+ /***********************************************************************
2
+ * Copyright (c) 2022 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
+ /* The code here is inspired by Kris Kwiatkowski's approach in
8
+ * https://github.com/kriskwiatkowski/pqc/blob/main/src/common/ct_check.h
9
+ * to provide a general interface for memory-checking mechanisms, primarily
10
+ * for constant-time checking.
11
+ */
12
+
13
+ /* These macros are defined by this header file:
14
+ *
15
+ * - SECP256K1_CHECKMEM_ENABLED:
16
+ * - 1 if memory-checking integration is available, 0 otherwise.
17
+ * This is just a compile-time macro. Use the next macro to check it is actually
18
+ * available at runtime.
19
+ * - SECP256K1_CHECKMEM_RUNNING():
20
+ * - Acts like a function call, returning 1 if memory checking is available
21
+ * at runtime.
22
+ * - SECP256K1_CHECKMEM_CHECK(p, len):
23
+ * - Assert or otherwise fail in case the len-byte memory block pointed to by p is
24
+ * not considered entirely defined.
25
+ * - SECP256K1_CHECKMEM_CHECK_VERIFY(p, len):
26
+ * - Like SECP256K1_CHECKMEM_CHECK, but only works in VERIFY mode.
27
+ * - SECP256K1_CHECKMEM_UNDEFINE(p, len):
28
+ * - marks the len-byte memory block pointed to by p as undefined data (secret data,
29
+ * in the context of constant-time checking).
30
+ * - SECP256K1_CHECKMEM_DEFINE(p, len):
31
+ * - marks the len-byte memory pointed to by p as defined data (public data, in the
32
+ * context of constant-time checking).
33
+ * - SECP256K1_CHECKMEM_MSAN_DEFINE(p, len):
34
+ * - Like SECP256K1_CHECKMEM_DEFINE, but applies only to memory_sanitizer.
35
+ *
36
+ */
37
+
38
+ #ifndef SECP256K1_CHECKMEM_H
39
+ #define SECP256K1_CHECKMEM_H
40
+
41
+ /* Define a statement-like macro that ignores the arguments. */
42
+ #define SECP256K1_CHECKMEM_NOOP(p, len) do { (void)(p); (void)(len); } while(0)
43
+
44
+ /* If compiling under msan, map the SECP256K1_CHECKMEM_* functionality to msan.
45
+ * Choose this preferentially, even when VALGRIND is defined, as msan-compiled
46
+ * binaries can't be run under valgrind anyway. */
47
+ #if defined(__has_feature)
48
+ # if __has_feature(memory_sanitizer)
49
+ # include <sanitizer/msan_interface.h>
50
+ # define SECP256K1_CHECKMEM_ENABLED 1
51
+ # if defined(__clang__) && ((__clang_major__ == 21 && __clang_minor__ >= 1) || __clang_major__ >= 22)
52
+ # define SECP256K1_CHECKMEM_UNDEFINE(p, len) do { \
53
+ /* Work around https://github.com/llvm/llvm-project/issues/160094 */ \
54
+ _Pragma("clang diagnostic push") \
55
+ _Pragma("clang diagnostic ignored \"-Wuninitialized-const-pointer\"") \
56
+ __msan_allocated_memory((p), (len)); \
57
+ _Pragma("clang diagnostic pop") \
58
+ } while(0)
59
+ # else
60
+ # define SECP256K1_CHECKMEM_UNDEFINE(p, len) __msan_allocated_memory((p), (len))
61
+ # endif
62
+ # define SECP256K1_CHECKMEM_DEFINE(p, len) __msan_unpoison((p), (len))
63
+ # define SECP256K1_CHECKMEM_MSAN_DEFINE(p, len) __msan_unpoison((p), (len))
64
+ # define SECP256K1_CHECKMEM_CHECK(p, len) __msan_check_mem_is_initialized((p), (len))
65
+ # define SECP256K1_CHECKMEM_RUNNING() (1)
66
+ # endif
67
+ #endif
68
+
69
+ #if !defined SECP256K1_CHECKMEM_MSAN_DEFINE
70
+ # define SECP256K1_CHECKMEM_MSAN_DEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
71
+ #endif
72
+
73
+ /* If valgrind integration is desired (through the VALGRIND define), implement the
74
+ * SECP256K1_CHECKMEM_* macros using valgrind. */
75
+ #if !defined SECP256K1_CHECKMEM_ENABLED
76
+ # if defined VALGRIND
77
+ # include <stddef.h>
78
+ # if defined(__clang__) && defined(__APPLE__)
79
+ # pragma clang diagnostic push
80
+ # pragma clang diagnostic ignored "-Wreserved-identifier"
81
+ # elif defined(__GNUC__) && (__GNUC__ >= 15)
82
+ # pragma GCC diagnostic push
83
+ # pragma GCC diagnostic ignored "-Wtrailing-whitespace"
84
+ # endif
85
+ # include <valgrind/memcheck.h>
86
+ # if defined(__clang__) && defined(__APPLE__)
87
+ # pragma clang diagnostic pop
88
+ # elif defined(__GNUC__) && (__GNUC__ >= 15)
89
+ # pragma GCC diagnostic pop
90
+ # endif
91
+ # define SECP256K1_CHECKMEM_ENABLED 1
92
+ # define SECP256K1_CHECKMEM_UNDEFINE(p, len) VALGRIND_MAKE_MEM_UNDEFINED((p), (len))
93
+ # define SECP256K1_CHECKMEM_DEFINE(p, len) VALGRIND_MAKE_MEM_DEFINED((p), (len))
94
+ # define SECP256K1_CHECKMEM_CHECK(p, len) VALGRIND_CHECK_MEM_IS_DEFINED((p), (len))
95
+ /* VALGRIND_MAKE_MEM_DEFINED returns 0 iff not running on memcheck.
96
+ * This is more precise than the RUNNING_ON_VALGRIND macro, which
97
+ * checks for valgrind in general instead of memcheck specifically. */
98
+ # define SECP256K1_CHECKMEM_RUNNING() (VALGRIND_MAKE_MEM_DEFINED(NULL, 0) != 0)
99
+ # endif
100
+ #endif
101
+
102
+ /* As a fall-back, map these macros to dummy statements. */
103
+ #if !defined SECP256K1_CHECKMEM_ENABLED
104
+ # define SECP256K1_CHECKMEM_ENABLED 0
105
+ # define SECP256K1_CHECKMEM_UNDEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
106
+ # define SECP256K1_CHECKMEM_DEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
107
+ # define SECP256K1_CHECKMEM_CHECK(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
108
+ # define SECP256K1_CHECKMEM_RUNNING() (0)
109
+ #endif
110
+
111
+ #if defined VERIFY
112
+ #define SECP256K1_CHECKMEM_CHECK_VERIFY(p, len) SECP256K1_CHECKMEM_CHECK((p), (len))
113
+ #else
114
+ #define SECP256K1_CHECKMEM_CHECK_VERIFY(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
115
+ #endif
116
+
117
+ #endif /* SECP256K1_CHECKMEM_H */
@@ -0,0 +1,21 @@
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_ECDSA_H
8
+ #define SECP256K1_ECDSA_H
9
+
10
+ #include <stddef.h>
11
+
12
+ #include "scalar.h"
13
+ #include "group.h"
14
+ #include "ecmult.h"
15
+
16
+ static int nostr_native_secp256k1_ecdsa_sig_parse(nostr_native_secp256k1_scalar *r, nostr_native_secp256k1_scalar *s, const unsigned char *sig, size_t size);
17
+ static int nostr_native_secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const nostr_native_secp256k1_scalar *r, const nostr_native_secp256k1_scalar *s);
18
+ static int nostr_native_secp256k1_ecdsa_sig_verify(const nostr_native_secp256k1_scalar* r, const nostr_native_secp256k1_scalar* s, const nostr_native_secp256k1_ge *pubkey, const nostr_native_secp256k1_scalar *message);
19
+ static int nostr_native_secp256k1_ecdsa_sig_sign(const nostr_native_secp256k1_ecmult_gen_context *ctx, nostr_native_secp256k1_scalar* r, nostr_native_secp256k1_scalar* s, const nostr_native_secp256k1_scalar *seckey, const nostr_native_secp256k1_scalar *message, const nostr_native_secp256k1_scalar *nonce, int *recid);
20
+
21
+ #endif /* SECP256K1_ECDSA_H */