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/android/src/main/java/com/ultrafast/ufsecp/UfsecpModule.java +207 -0
- package/android/src/main/java/com/ultrafastsecp256k1/UltrafastSecp256k1Module.java +385 -0
- package/android/src/main/java/com/ultrafastsecp256k1/UltrafastSecp256k1Package.java +28 -0
- package/ios/RNUfsecp.m +253 -0
- package/ios/UltrafastSecp256k1.h +4 -0
- package/ios/UltrafastSecp256k1.m +483 -0
- package/lib/ufsecp.js +176 -0
- package/package.json +24 -0
- package/react-native-ufsecp.podspec +17 -0
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
|