react-native-ufsecp 3.10.0

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.
package/ios/RNUfsecp.m ADDED
@@ -0,0 +1,253 @@
1
+ /**
2
+ * UltrafastSecp256k1 — React Native iOS bridge (ufsecp stable C ABI v1).
3
+ *
4
+ * ObjC bridge that links against libufsecp.a (static) and exposes
5
+ * methods to JS via RCT_EXPORT_METHOD.
6
+ */
7
+
8
+ #import <React/RCTBridgeModule.h>
9
+ #import "ufsecp.h"
10
+
11
+ @interface RNUfsecp : NSObject <RCTBridgeModule>
12
+ @end
13
+
14
+ @implementation RNUfsecp
15
+
16
+ RCT_EXPORT_MODULE(Ufsecp)
17
+
18
+ /* ── Hex helpers ───────────────────────────────────────────────────── */
19
+
20
+ static NSData *hexToData(NSString *hex) {
21
+ NSMutableData *d = [NSMutableData dataWithCapacity:hex.length / 2];
22
+ unsigned char byte;
23
+ char tmp[3] = {0};
24
+ for (NSUInteger i = 0; i < hex.length; i += 2) {
25
+ tmp[0] = [hex characterAtIndex:i];
26
+ tmp[1] = [hex characterAtIndex:i + 1];
27
+ byte = (unsigned char)strtol(tmp, NULL, 16);
28
+ [d appendBytes:&byte length:1];
29
+ }
30
+ return d;
31
+ }
32
+
33
+ static NSString *dataToHex(const uint8_t *data, size_t len) {
34
+ NSMutableString *s = [NSMutableString stringWithCapacity:len * 2];
35
+ for (size_t i = 0; i < len; i++) [s appendFormat:@"%02x", data[i]];
36
+ return s;
37
+ }
38
+
39
+ /* ── Context ───────────────────────────────────────────────────────── */
40
+
41
+ RCT_EXPORT_METHOD(create:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
42
+ ufsecp_ctx *ctx = NULL;
43
+ int rc = ufsecp_ctx_create(&ctx);
44
+ if (rc != 0) {
45
+ reject(@"UFSECP", [NSString stringWithFormat:@"ctx_create failed: %d", rc], nil);
46
+ return;
47
+ }
48
+ resolve(@((double)(uintptr_t)ctx));
49
+ }
50
+
51
+ RCT_EXPORT_METHOD(destroy:(double)handle resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
52
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
53
+ if (ctx) ufsecp_ctx_destroy(ctx);
54
+ resolve(nil);
55
+ }
56
+
57
+ /* ── Version ───────────────────────────────────────────────────────── */
58
+
59
+ RCT_EXPORT_METHOD(version:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
60
+ resolve(@(ufsecp_version()));
61
+ }
62
+
63
+ RCT_EXPORT_METHOD(versionString:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
64
+ resolve([NSString stringWithUTF8String:ufsecp_version_string()]);
65
+ }
66
+
67
+ /* ── Key ops ───────────────────────────────────────────────────────── */
68
+
69
+ RCT_EXPORT_METHOD(pubkeyCreate:(double)handle privkey:(NSString *)pkHex
70
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
71
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
72
+ NSData *pk = hexToData(pkHex);
73
+ uint8_t out[33];
74
+ int rc = ufsecp_pubkey_create(ctx, pk.bytes, out);
75
+ if (rc != 0) { reject(@"UFSECP", @"pubkey_create failed", nil); return; }
76
+ resolve(dataToHex(out, 33));
77
+ }
78
+
79
+ RCT_EXPORT_METHOD(pubkeyCreateUncompressed:(double)handle privkey:(NSString *)pkHex
80
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
81
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
82
+ NSData *pk = hexToData(pkHex);
83
+ uint8_t out[65];
84
+ int rc = ufsecp_pubkey_create_uncompressed(ctx, pk.bytes, out);
85
+ if (rc != 0) { reject(@"UFSECP", @"pubkey_create_uncompressed failed", nil); return; }
86
+ resolve(dataToHex(out, 65));
87
+ }
88
+
89
+ RCT_EXPORT_METHOD(seckeyVerify:(double)handle privkey:(NSString *)pkHex
90
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
91
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
92
+ NSData *pk = hexToData(pkHex);
93
+ int rc = ufsecp_seckey_verify(ctx, pk.bytes);
94
+ resolve(@(rc == 0));
95
+ }
96
+
97
+ /* ── ECDSA ─────────────────────────────────────────────────────────── */
98
+
99
+ RCT_EXPORT_METHOD(ecdsaSign:(double)handle msgHash:(NSString *)msgHex privkey:(NSString *)pkHex
100
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
101
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
102
+ NSData *msg = hexToData(msgHex);
103
+ NSData *pk = hexToData(pkHex);
104
+ uint8_t sig[64];
105
+ int rc = ufsecp_ecdsa_sign(ctx, msg.bytes, pk.bytes, sig);
106
+ if (rc != 0) { reject(@"UFSECP", @"ecdsa_sign failed", nil); return; }
107
+ resolve(dataToHex(sig, 64));
108
+ }
109
+
110
+ RCT_EXPORT_METHOD(ecdsaVerify:(double)handle msgHash:(NSString *)msgHex sig:(NSString *)sigHex pubkey:(NSString *)pubHex
111
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
112
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
113
+ NSData *msg = hexToData(msgHex);
114
+ NSData *sig = hexToData(sigHex);
115
+ NSData *pub = hexToData(pubHex);
116
+ int rc = ufsecp_ecdsa_verify(ctx, msg.bytes, sig.bytes, pub.bytes);
117
+ resolve(@(rc == 0));
118
+ }
119
+
120
+ /* ── Schnorr ───────────────────────────────────────────────────────── */
121
+
122
+ RCT_EXPORT_METHOD(schnorrSign:(double)handle msg:(NSString *)msgHex privkey:(NSString *)pkHex auxRand:(NSString *)arHex
123
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
124
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
125
+ NSData *msg = hexToData(msgHex);
126
+ NSData *pk = hexToData(pkHex);
127
+ NSData *ar = hexToData(arHex);
128
+ uint8_t sig[64];
129
+ int rc = ufsecp_schnorr_sign(ctx, msg.bytes, pk.bytes, ar.bytes, sig);
130
+ if (rc != 0) { reject(@"UFSECP", @"schnorr_sign failed", nil); return; }
131
+ resolve(dataToHex(sig, 64));
132
+ }
133
+
134
+ RCT_EXPORT_METHOD(schnorrVerify:(double)handle msg:(NSString *)msgHex sig:(NSString *)sigHex pubkeyX:(NSString *)pxHex
135
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
136
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
137
+ NSData *msg = hexToData(msgHex);
138
+ NSData *sig = hexToData(sigHex);
139
+ NSData *px = hexToData(pxHex);
140
+ int rc = ufsecp_schnorr_verify(ctx, msg.bytes, sig.bytes, px.bytes);
141
+ resolve(@(rc == 0));
142
+ }
143
+
144
+ /* ── ECDH ──────────────────────────────────────────────────────────── */
145
+
146
+ RCT_EXPORT_METHOD(ecdh:(double)handle privkey:(NSString *)pkHex pubkey:(NSString *)pubHex
147
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
148
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
149
+ NSData *pk = hexToData(pkHex);
150
+ NSData *pub = hexToData(pubHex);
151
+ uint8_t out[32];
152
+ int rc = ufsecp_ecdh(ctx, pk.bytes, pub.bytes, out);
153
+ if (rc != 0) { reject(@"UFSECP", @"ecdh failed", nil); return; }
154
+ resolve(dataToHex(out, 32));
155
+ }
156
+
157
+ /* ── Hashing ───────────────────────────────────────────────────────── */
158
+
159
+ RCT_EXPORT_METHOD(sha256:(NSString *)dataHex
160
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
161
+ NSData *d = hexToData(dataHex);
162
+ uint8_t out[32];
163
+ int rc = ufsecp_sha256(d.bytes, d.length, out);
164
+ if (rc != 0) { reject(@"UFSECP", @"sha256 failed", nil); return; }
165
+ resolve(dataToHex(out, 32));
166
+ }
167
+
168
+ RCT_EXPORT_METHOD(hash160:(NSString *)dataHex
169
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
170
+ NSData *d = hexToData(dataHex);
171
+ uint8_t out[20];
172
+ int rc = ufsecp_hash160(d.bytes, d.length, out);
173
+ if (rc != 0) { reject(@"UFSECP", @"hash160 failed", nil); return; }
174
+ resolve(dataToHex(out, 20));
175
+ }
176
+
177
+ /* ── Addresses ─────────────────────────────────────────────────────── */
178
+
179
+ RCT_EXPORT_METHOD(addrP2pkh:(double)handle pubkey:(NSString *)pubHex network:(int)network
180
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
181
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
182
+ NSData *pk = hexToData(pubHex);
183
+ uint8_t addr[128]; size_t alen = 128;
184
+ int rc = ufsecp_addr_p2pkh(ctx, pk.bytes, network, addr, &alen);
185
+ if (rc != 0) { reject(@"UFSECP", @"addr_p2pkh failed", nil); return; }
186
+ resolve([[NSString alloc] initWithBytes:addr length:alen encoding:NSUTF8StringEncoding]);
187
+ }
188
+
189
+ RCT_EXPORT_METHOD(addrP2wpkh:(double)handle pubkey:(NSString *)pubHex network:(int)network
190
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
191
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
192
+ NSData *pk = hexToData(pubHex);
193
+ uint8_t addr[128]; size_t alen = 128;
194
+ int rc = ufsecp_addr_p2wpkh(ctx, pk.bytes, network, addr, &alen);
195
+ if (rc != 0) { reject(@"UFSECP", @"addr_p2wpkh failed", nil); return; }
196
+ resolve([[NSString alloc] initWithBytes:addr length:alen encoding:NSUTF8StringEncoding]);
197
+ }
198
+
199
+ RCT_EXPORT_METHOD(addrP2tr:(double)handle xonly:(NSString *)xHex network:(int)network
200
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
201
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
202
+ NSData *x = hexToData(xHex);
203
+ uint8_t addr[128]; size_t alen = 128;
204
+ int rc = ufsecp_addr_p2tr(ctx, x.bytes, network, addr, &alen);
205
+ if (rc != 0) { reject(@"UFSECP", @"addr_p2tr failed", nil); return; }
206
+ resolve([[NSString alloc] initWithBytes:addr length:alen encoding:NSUTF8StringEncoding]);
207
+ }
208
+
209
+ /* ── WIF ───────────────────────────────────────────────────────────── */
210
+
211
+ RCT_EXPORT_METHOD(wifEncode:(double)handle privkey:(NSString *)pkHex compressed:(BOOL)compressed network:(int)network
212
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
213
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
214
+ NSData *pk = hexToData(pkHex);
215
+ uint8_t wif[128]; size_t wlen = 128;
216
+ int rc = ufsecp_wif_encode(ctx, pk.bytes, compressed ? 1 : 0, network, wif, &wlen);
217
+ if (rc != 0) { reject(@"UFSECP", @"wif_encode failed", nil); return; }
218
+ resolve([[NSString alloc] initWithBytes:wif length:wlen encoding:NSUTF8StringEncoding]);
219
+ }
220
+
221
+ /* ── BIP-32 ────────────────────────────────────────────────────────── */
222
+
223
+ RCT_EXPORT_METHOD(bip32Master:(double)handle seed:(NSString *)seedHex
224
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
225
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
226
+ NSData *seed = hexToData(seedHex);
227
+ uint8_t key[82];
228
+ int rc = ufsecp_bip32_master(ctx, seed.bytes, seed.length, key);
229
+ if (rc != 0) { reject(@"UFSECP", @"bip32_master failed", nil); return; }
230
+ resolve(dataToHex(key, 82));
231
+ }
232
+
233
+ RCT_EXPORT_METHOD(bip32Derive:(double)handle parent:(NSString *)parentHex index:(int)index
234
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
235
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
236
+ NSData *p = hexToData(parentHex);
237
+ uint8_t child[82];
238
+ int rc = ufsecp_bip32_derive(ctx, p.bytes, (uint32_t)index, child);
239
+ if (rc != 0) { reject(@"UFSECP", @"bip32_derive failed", nil); return; }
240
+ resolve(dataToHex(child, 82));
241
+ }
242
+
243
+ RCT_EXPORT_METHOD(bip32DerivePath:(double)handle master:(NSString *)masterHex path:(NSString *)pathStr
244
+ resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
245
+ ufsecp_ctx *ctx = (ufsecp_ctx *)(uintptr_t)(long long)handle;
246
+ NSData *m = hexToData(masterHex);
247
+ uint8_t key[82];
248
+ int rc = ufsecp_bip32_derive_path(ctx, m.bytes, [pathStr UTF8String], key);
249
+ if (rc != 0) { reject(@"UFSECP", @"bip32_derive_path failed", nil); return; }
250
+ resolve(dataToHex(key, 82));
251
+ }
252
+
253
+ @end
@@ -0,0 +1,4 @@
1
+ #import <React/RCTBridgeModule.h>
2
+
3
+ @interface UltrafastSecp256k1 : NSObject <RCTBridgeModule>
4
+ @end