react-native-quick-crypto 1.1.1 → 1.1.3
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/QuickCrypto.podspec +1 -0
- package/android/CMakeLists.txt +4 -0
- package/cpp/cipher/CCMCipher.cpp +7 -11
- package/cpp/cipher/ChaCha20Cipher.cpp +6 -10
- package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +10 -16
- package/cpp/cipher/GCMCipher.cpp +3 -5
- package/cpp/cipher/HybridCipher.cpp +7 -13
- package/cpp/cipher/HybridRsaCipher.cpp +19 -27
- package/cpp/cipher/OCBCipher.cpp +2 -3
- package/cpp/cipher/XChaCha20Poly1305Cipher.cpp +13 -19
- package/cpp/cipher/XSalsa20Cipher.cpp +8 -12
- package/cpp/cipher/XSalsa20Poly1305Cipher.cpp +11 -16
- package/cpp/keys/HybridKeyObjectHandle.cpp +630 -2
- package/cpp/keys/HybridKeyObjectHandle.hpp +21 -1
- package/cpp/sign/HybridSignHandle.cpp +26 -8
- package/cpp/sign/HybridVerifyHandle.cpp +28 -11
- package/cpp/slhdsa/HybridSlhDsaKeyPair.cpp +245 -0
- package/cpp/slhdsa/HybridSlhDsaKeyPair.hpp +48 -0
- package/cpp/turboshake/HybridTurboShake.cpp +379 -0
- package/cpp/turboshake/HybridTurboShake.hpp +28 -0
- package/cpp/utils/HybridUtils.cpp +83 -21
- package/cpp/utils/HybridUtils.hpp +4 -0
- package/deps/blake3/README.md +6 -7
- package/deps/blake3/c/blake3.c +3 -2
- package/deps/blake3/c/blake3.h +2 -2
- package/deps/blake3/c/blake3_dispatch.c +2 -2
- package/deps/blake3/c/blake3_impl.h +1 -1
- package/deps/blake3/c/blake3_neon.c +5 -4
- package/deps/ncrypto/include/ncrypto/version.h +2 -2
- package/deps/ncrypto/include/ncrypto.h +9 -2
- package/deps/ncrypto/src/ncrypto.cpp +130 -35
- package/lib/commonjs/dhKeyPair.js +3 -0
- package/lib/commonjs/dhKeyPair.js.map +1 -1
- package/lib/commonjs/dsa.js +3 -0
- package/lib/commonjs/dsa.js.map +1 -1
- package/lib/commonjs/ec.js +37 -30
- package/lib/commonjs/ec.js.map +1 -1
- package/lib/commonjs/ed.js +60 -6
- package/lib/commonjs/ed.js.map +1 -1
- package/lib/commonjs/expo-plugin/withXCode.js +3 -3
- package/lib/commonjs/hash.js +52 -5
- package/lib/commonjs/hash.js.map +1 -1
- package/lib/commonjs/keys/classes.js +33 -7
- package/lib/commonjs/keys/classes.js.map +1 -1
- package/lib/commonjs/keys/generateKeyPair.js +85 -4
- package/lib/commonjs/keys/generateKeyPair.js.map +1 -1
- package/lib/commonjs/keys/index.js +50 -2
- package/lib/commonjs/keys/index.js.map +1 -1
- package/lib/commonjs/keys/signVerify.js +9 -2
- package/lib/commonjs/keys/signVerify.js.map +1 -1
- package/lib/commonjs/keys/utils.js +59 -1
- package/lib/commonjs/keys/utils.js.map +1 -1
- package/lib/commonjs/random.js +63 -9
- package/lib/commonjs/random.js.map +1 -1
- package/lib/commonjs/rsa.js +3 -0
- package/lib/commonjs/rsa.js.map +1 -1
- package/lib/commonjs/slhdsa.js +70 -0
- package/lib/commonjs/slhdsa.js.map +1 -0
- package/lib/commonjs/specs/slhDsaKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/slhDsaKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/turboshake.nitro.js +6 -0
- package/lib/commonjs/specs/turboshake.nitro.js.map +1 -0
- package/lib/commonjs/subtle.js +926 -275
- package/lib/commonjs/subtle.js.map +1 -1
- package/lib/commonjs/utils/conversion.js +61 -25
- package/lib/commonjs/utils/conversion.js.map +1 -1
- package/lib/commonjs/utils/errors.js +63 -4
- package/lib/commonjs/utils/errors.js.map +1 -1
- package/lib/commonjs/utils/types.js.map +1 -1
- package/lib/commonjs/utils/validation.js +46 -0
- package/lib/commonjs/utils/validation.js.map +1 -1
- package/lib/module/dhKeyPair.js +3 -0
- package/lib/module/dhKeyPair.js.map +1 -1
- package/lib/module/dsa.js +3 -0
- package/lib/module/dsa.js.map +1 -1
- package/lib/module/ec.js +38 -31
- package/lib/module/ec.js.map +1 -1
- package/lib/module/ed.js +61 -7
- package/lib/module/ed.js.map +1 -1
- package/lib/module/expo-plugin/withXCode.js +3 -3
- package/lib/module/hash.js +52 -5
- package/lib/module/hash.js.map +1 -1
- package/lib/module/keys/classes.js +31 -5
- package/lib/module/keys/classes.js.map +1 -1
- package/lib/module/keys/generateKeyPair.js +86 -5
- package/lib/module/keys/generateKeyPair.js.map +1 -1
- package/lib/module/keys/index.js +50 -2
- package/lib/module/keys/index.js.map +1 -1
- package/lib/module/keys/signVerify.js +9 -2
- package/lib/module/keys/signVerify.js.map +1 -1
- package/lib/module/keys/utils.js +57 -1
- package/lib/module/keys/utils.js.map +1 -1
- package/lib/module/random.js +63 -10
- package/lib/module/random.js.map +1 -1
- package/lib/module/rsa.js +3 -0
- package/lib/module/rsa.js.map +1 -1
- package/lib/module/slhdsa.js +64 -0
- package/lib/module/slhdsa.js.map +1 -0
- package/lib/module/specs/slhDsaKeyPair.nitro.js +4 -0
- package/lib/module/specs/slhDsaKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/turboshake.nitro.js +4 -0
- package/lib/module/specs/turboshake.nitro.js.map +1 -0
- package/lib/module/subtle.js +927 -276
- package/lib/module/subtle.js.map +1 -1
- package/lib/module/utils/conversion.js +59 -25
- package/lib/module/utils/conversion.js.map +1 -1
- package/lib/module/utils/errors.js +61 -4
- package/lib/module/utils/errors.js.map +1 -1
- package/lib/module/utils/types.js.map +1 -1
- package/lib/module/utils/validation.js +44 -0
- package/lib/module/utils/validation.js.map +1 -1
- package/lib/typescript/dhKeyPair.d.ts.map +1 -1
- package/lib/typescript/dsa.d.ts.map +1 -1
- package/lib/typescript/ec.d.ts.map +1 -1
- package/lib/typescript/ed.d.ts.map +1 -1
- package/lib/typescript/hash.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +12 -7
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/keys/classes.d.ts +10 -1
- package/lib/typescript/keys/classes.d.ts.map +1 -1
- package/lib/typescript/keys/generateKeyPair.d.ts +12 -1
- package/lib/typescript/keys/generateKeyPair.d.ts.map +1 -1
- package/lib/typescript/keys/index.d.ts +3 -1
- package/lib/typescript/keys/index.d.ts.map +1 -1
- package/lib/typescript/keys/signVerify.d.ts.map +1 -1
- package/lib/typescript/keys/utils.d.ts +21 -4
- package/lib/typescript/keys/utils.d.ts.map +1 -1
- package/lib/typescript/random.d.ts +5 -1
- package/lib/typescript/random.d.ts.map +1 -1
- package/lib/typescript/rsa.d.ts.map +1 -1
- package/lib/typescript/slhdsa.d.ts +19 -0
- package/lib/typescript/slhdsa.d.ts.map +1 -0
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts +9 -0
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts.map +1 -1
- package/lib/typescript/specs/slhDsaKeyPair.nitro.d.ts +16 -0
- package/lib/typescript/specs/slhDsaKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/turboshake.nitro.d.ts +11 -0
- package/lib/typescript/specs/turboshake.nitro.d.ts.map +1 -0
- package/lib/typescript/subtle.d.ts +3 -2
- package/lib/typescript/subtle.d.ts.map +1 -1
- package/lib/typescript/utils/conversion.d.ts +9 -6
- package/lib/typescript/utils/conversion.d.ts.map +1 -1
- package/lib/typescript/utils/errors.d.ts +12 -0
- package/lib/typescript/utils/errors.d.ts.map +1 -1
- package/lib/typescript/utils/types.d.ts +32 -15
- package/lib/typescript/utils/types.d.ts.map +1 -1
- package/lib/typescript/utils/validation.d.ts +3 -1
- package/lib/typescript/utils/validation.d.ts.map +1 -1
- package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +2 -0
- package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +20 -0
- package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +20 -0
- package/nitrogen/generated/shared/c++/AsymmetricKeyType.hpp +48 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.cpp +9 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +9 -0
- package/nitrogen/generated/shared/c++/HybridSlhDsaKeyPairSpec.cpp +29 -0
- package/nitrogen/generated/shared/c++/HybridSlhDsaKeyPairSpec.hpp +72 -0
- package/nitrogen/generated/shared/c++/HybridTurboShakeSpec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridTurboShakeSpec.hpp +70 -0
- package/nitrogen/generated/shared/c++/JWK.hpp +9 -1
- package/nitrogen/generated/shared/c++/JWKkty.hpp +4 -0
- package/nitrogen/generated/shared/c++/KangarooTwelveVariant.hpp +76 -0
- package/nitrogen/generated/shared/c++/TurboShakeVariant.hpp +76 -0
- package/package.json +4 -5
- package/src/dhKeyPair.ts +8 -0
- package/src/dsa.ts +8 -0
- package/src/ec.ts +52 -29
- package/src/ed.ts +95 -16
- package/src/expo-plugin/withXCode.ts +3 -3
- package/src/hash.ts +108 -5
- package/src/keys/classes.ts +46 -5
- package/src/keys/generateKeyPair.ts +151 -5
- package/src/keys/index.ts +73 -3
- package/src/keys/signVerify.ts +13 -2
- package/src/keys/utils.ts +78 -5
- package/src/random.ts +93 -9
- package/src/rsa.ts +8 -0
- package/src/slhdsa.ts +146 -0
- package/src/specs/keyObjectHandle.nitro.ts +17 -0
- package/src/specs/slhDsaKeyPair.nitro.ts +29 -0
- package/src/specs/turboshake.nitro.ts +21 -0
- package/src/subtle.ts +1191 -360
- package/src/utils/conversion.ts +80 -27
- package/src/utils/errors.ts +72 -4
- package/src/utils/types.ts +80 -15
- package/src/utils/validation.ts +70 -1
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
#include <NitroModules/ArrayBuffer.hpp>
|
|
2
|
+
#include <cstring>
|
|
3
|
+
#include <memory>
|
|
4
|
+
#include <optional>
|
|
5
|
+
#include <stdexcept>
|
|
6
|
+
#include <string>
|
|
7
|
+
#include <vector>
|
|
8
|
+
|
|
9
|
+
#include "HybridTurboShake.hpp"
|
|
10
|
+
#include "QuickCryptoUtils.hpp"
|
|
11
|
+
|
|
12
|
+
// TurboSHAKE128/256 and KangarooTwelve KT128/256 (RFC 9861).
|
|
13
|
+
// Implementation adapted from Node.js src/crypto/crypto_turboshake.cc
|
|
14
|
+
// (commit e0cab9dcf75), which itself adapts the OpenSSL keccak1600.c
|
|
15
|
+
// reference variant. OpenSSL does not yet expose these algorithms via EVP,
|
|
16
|
+
// so the Keccak-p[1600, n_r=12] permutation and sponge are provided here.
|
|
17
|
+
|
|
18
|
+
namespace margelo::nitro::crypto {
|
|
19
|
+
|
|
20
|
+
namespace {
|
|
21
|
+
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Keccak-p[1600, n_r=12] permutation (FIPS 202 §3.3-3.4, RFC 9861 §2.2).
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
inline uint64_t ROL64(uint64_t val, int offset) {
|
|
27
|
+
if (offset == 0)
|
|
28
|
+
return val;
|
|
29
|
+
return (val << offset) | (val >> (64 - offset));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
inline uint64_t LoadLE64(const uint8_t* src) {
|
|
33
|
+
return static_cast<uint64_t>(src[0]) | (static_cast<uint64_t>(src[1]) << 8) | (static_cast<uint64_t>(src[2]) << 16) |
|
|
34
|
+
(static_cast<uint64_t>(src[3]) << 24) | (static_cast<uint64_t>(src[4]) << 32) | (static_cast<uint64_t>(src[5]) << 40) |
|
|
35
|
+
(static_cast<uint64_t>(src[6]) << 48) | (static_cast<uint64_t>(src[7]) << 56);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
inline void StoreLE64(uint8_t* dst, uint64_t val) {
|
|
39
|
+
dst[0] = static_cast<uint8_t>(val);
|
|
40
|
+
dst[1] = static_cast<uint8_t>(val >> 8);
|
|
41
|
+
dst[2] = static_cast<uint8_t>(val >> 16);
|
|
42
|
+
dst[3] = static_cast<uint8_t>(val >> 24);
|
|
43
|
+
dst[4] = static_cast<uint8_t>(val >> 32);
|
|
44
|
+
dst[5] = static_cast<uint8_t>(val >> 40);
|
|
45
|
+
dst[6] = static_cast<uint8_t>(val >> 48);
|
|
46
|
+
dst[7] = static_cast<uint8_t>(val >> 56);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
constexpr unsigned char kRhoTates[5][5] = {
|
|
50
|
+
{0, 1, 62, 28, 27}, {36, 44, 6, 55, 20}, {3, 10, 43, 25, 39}, {41, 45, 15, 21, 8}, {18, 2, 61, 56, 14},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Round constants for Keccak-f[1600]; TurboSHAKE uses indices 12..23.
|
|
54
|
+
constexpr uint64_t kIotas[24] = {
|
|
55
|
+
0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, 0x000000000000808bULL,
|
|
56
|
+
0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, 0x0000000000000088ULL,
|
|
57
|
+
0x0000000080008009ULL, 0x000000008000000aULL, 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL,
|
|
58
|
+
0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800aULL, 0x800000008000000aULL,
|
|
59
|
+
0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
void KeccakP1600_12(uint64_t A[5][5]) {
|
|
63
|
+
for (size_t round = 12; round < 24; round++) {
|
|
64
|
+
uint64_t C[5];
|
|
65
|
+
for (size_t x = 0; x < 5; x++) {
|
|
66
|
+
C[x] = A[0][x] ^ A[1][x] ^ A[2][x] ^ A[3][x] ^ A[4][x];
|
|
67
|
+
}
|
|
68
|
+
uint64_t D[5];
|
|
69
|
+
for (size_t x = 0; x < 5; x++) {
|
|
70
|
+
D[x] = C[(x + 4) % 5] ^ ROL64(C[(x + 1) % 5], 1);
|
|
71
|
+
}
|
|
72
|
+
for (size_t y = 0; y < 5; y++) {
|
|
73
|
+
for (size_t x = 0; x < 5; x++) {
|
|
74
|
+
A[y][x] ^= D[x];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
for (size_t y = 0; y < 5; y++) {
|
|
78
|
+
for (size_t x = 0; x < 5; x++) {
|
|
79
|
+
A[y][x] = ROL64(A[y][x], kRhoTates[y][x]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
uint64_t T[5][5];
|
|
83
|
+
memcpy(T, A, sizeof(T));
|
|
84
|
+
for (size_t y = 0; y < 5; y++) {
|
|
85
|
+
for (size_t x = 0; x < 5; x++) {
|
|
86
|
+
A[y][x] = T[x][(3 * y + x) % 5];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
for (size_t y = 0; y < 5; y++) {
|
|
90
|
+
uint64_t row[5];
|
|
91
|
+
for (size_t x = 0; x < 5; x++) {
|
|
92
|
+
row[x] = A[y][x] ^ (~A[y][(x + 1) % 5] & A[y][(x + 2) % 5]);
|
|
93
|
+
}
|
|
94
|
+
memcpy(A[y], row, sizeof(row));
|
|
95
|
+
}
|
|
96
|
+
A[0][0] ^= kIotas[round];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
// TurboSHAKE sponge (RFC 9861 §2.2, App. A.2/A.3).
|
|
102
|
+
// TurboSHAKE128: rate = 168 bytes (capacity 256 bits).
|
|
103
|
+
// TurboSHAKE256: rate = 136 bytes (capacity 512 bits).
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
constexpr size_t kTurboSHAKE128Rate = 168;
|
|
107
|
+
constexpr size_t kTurboSHAKE256Rate = 136;
|
|
108
|
+
|
|
109
|
+
void TurboSHAKE(const uint8_t* input, size_t input_len, size_t rate, uint8_t domain_sep, uint8_t* output, size_t output_len) {
|
|
110
|
+
uint64_t A[5][5] = {};
|
|
111
|
+
size_t lane_count = rate / 8;
|
|
112
|
+
|
|
113
|
+
size_t offset = 0;
|
|
114
|
+
while (offset + rate <= input_len) {
|
|
115
|
+
for (size_t i = 0; i < lane_count; i++) {
|
|
116
|
+
A[i / 5][i % 5] ^= LoadLE64(input + offset + i * 8);
|
|
117
|
+
}
|
|
118
|
+
KeccakP1600_12(A);
|
|
119
|
+
offset += rate;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
size_t remaining = input_len - offset;
|
|
123
|
+
// Sized for the larger TurboSHAKE128 rate (168); also fits the 136-byte TurboSHAKE256 rate.
|
|
124
|
+
uint8_t pad[kTurboSHAKE128Rate] = {};
|
|
125
|
+
if (remaining > 0) {
|
|
126
|
+
memcpy(pad, input + offset, remaining);
|
|
127
|
+
}
|
|
128
|
+
pad[remaining] ^= domain_sep;
|
|
129
|
+
pad[rate - 1] ^= 0x80;
|
|
130
|
+
|
|
131
|
+
for (size_t i = 0; i < lane_count; i++) {
|
|
132
|
+
A[i / 5][i % 5] ^= LoadLE64(pad + i * 8);
|
|
133
|
+
}
|
|
134
|
+
KeccakP1600_12(A);
|
|
135
|
+
|
|
136
|
+
size_t out_offset = 0;
|
|
137
|
+
while (out_offset < output_len) {
|
|
138
|
+
size_t block = output_len - out_offset;
|
|
139
|
+
if (block > rate)
|
|
140
|
+
block = rate;
|
|
141
|
+
size_t full_lanes = block / 8;
|
|
142
|
+
for (size_t i = 0; i < full_lanes; i++) {
|
|
143
|
+
StoreLE64(output + out_offset + i * 8, A[i / 5][i % 5]);
|
|
144
|
+
}
|
|
145
|
+
size_t rem = block % 8;
|
|
146
|
+
if (rem > 0) {
|
|
147
|
+
uint8_t tmp[8];
|
|
148
|
+
StoreLE64(tmp, A[full_lanes / 5][full_lanes % 5]);
|
|
149
|
+
memcpy(output + out_offset + full_lanes * 8, tmp, rem);
|
|
150
|
+
}
|
|
151
|
+
out_offset += block;
|
|
152
|
+
if (out_offset < output_len) {
|
|
153
|
+
KeccakP1600_12(A);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
void TurboSHAKE128(const uint8_t* input, size_t input_len, uint8_t domain_sep, uint8_t* output, size_t output_len) {
|
|
159
|
+
TurboSHAKE(input, input_len, kTurboSHAKE128Rate, domain_sep, output, output_len);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
void TurboSHAKE256(const uint8_t* input, size_t input_len, uint8_t domain_sep, uint8_t* output, size_t output_len) {
|
|
163
|
+
TurboSHAKE(input, input_len, kTurboSHAKE256Rate, domain_sep, output, output_len);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ---------------------------------------------------------------------------
|
|
167
|
+
// KangarooTwelve tree hashing (RFC 9861 §3).
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
|
|
170
|
+
constexpr size_t kChunkSize = 8192;
|
|
171
|
+
|
|
172
|
+
// length_encode(x) per RFC 9861 §3.3.
|
|
173
|
+
std::vector<uint8_t> LengthEncode(size_t x) {
|
|
174
|
+
if (x == 0) {
|
|
175
|
+
return {0x00};
|
|
176
|
+
}
|
|
177
|
+
std::vector<uint8_t> result;
|
|
178
|
+
size_t val = x;
|
|
179
|
+
while (val > 0) {
|
|
180
|
+
result.push_back(static_cast<uint8_t>(val & 0xFF));
|
|
181
|
+
val >>= 8;
|
|
182
|
+
}
|
|
183
|
+
size_t n = result.size();
|
|
184
|
+
for (size_t i = 0; i < n / 2; i++) {
|
|
185
|
+
std::swap(result[i], result[n - 1 - i]);
|
|
186
|
+
}
|
|
187
|
+
result.push_back(static_cast<uint8_t>(n));
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
using TurboSHAKEFn = void (*)(const uint8_t* input, size_t input_len, uint8_t domain_sep, uint8_t* output, size_t output_len);
|
|
192
|
+
|
|
193
|
+
void KangarooTwelve(const uint8_t* message, size_t msg_len, const uint8_t* customization, size_t custom_len, uint8_t* output,
|
|
194
|
+
size_t output_len, TurboSHAKEFn turboshake, size_t cv_len) {
|
|
195
|
+
auto len_enc = LengthEncode(custom_len);
|
|
196
|
+
size_t s_len = msg_len + custom_len + len_enc.size();
|
|
197
|
+
|
|
198
|
+
// Short message: |S| <= 8192.
|
|
199
|
+
if (s_len <= kChunkSize) {
|
|
200
|
+
std::vector<uint8_t> s(s_len);
|
|
201
|
+
size_t pos = 0;
|
|
202
|
+
if (msg_len > 0) {
|
|
203
|
+
memcpy(s.data() + pos, message, msg_len);
|
|
204
|
+
pos += msg_len;
|
|
205
|
+
}
|
|
206
|
+
if (custom_len > 0) {
|
|
207
|
+
memcpy(s.data() + pos, customization, custom_len);
|
|
208
|
+
pos += custom_len;
|
|
209
|
+
}
|
|
210
|
+
memcpy(s.data() + pos, len_enc.data(), len_enc.size());
|
|
211
|
+
|
|
212
|
+
turboshake(s.data(), s_len, 0x07, output, output_len);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// S is virtual: M || C || length_encode(|C|). Read on demand.
|
|
217
|
+
auto read_s = [&](size_t s_offset, uint8_t* buf, size_t len) {
|
|
218
|
+
size_t copied = 0;
|
|
219
|
+
if (s_offset < msg_len && copied < len) {
|
|
220
|
+
size_t avail = msg_len - s_offset;
|
|
221
|
+
size_t to_copy = avail < (len - copied) ? avail : (len - copied);
|
|
222
|
+
memcpy(buf + copied, message + s_offset, to_copy);
|
|
223
|
+
copied += to_copy;
|
|
224
|
+
s_offset += to_copy;
|
|
225
|
+
}
|
|
226
|
+
size_t custom_start = msg_len;
|
|
227
|
+
if (s_offset < custom_start + custom_len && copied < len) {
|
|
228
|
+
size_t off_in_custom = s_offset - custom_start;
|
|
229
|
+
size_t avail = custom_len - off_in_custom;
|
|
230
|
+
size_t to_copy = avail < (len - copied) ? avail : (len - copied);
|
|
231
|
+
memcpy(buf + copied, customization + off_in_custom, to_copy);
|
|
232
|
+
copied += to_copy;
|
|
233
|
+
s_offset += to_copy;
|
|
234
|
+
}
|
|
235
|
+
size_t le_start = msg_len + custom_len;
|
|
236
|
+
if (s_offset < le_start + len_enc.size() && copied < len) {
|
|
237
|
+
size_t off_in_le = s_offset - le_start;
|
|
238
|
+
size_t avail = len_enc.size() - off_in_le;
|
|
239
|
+
size_t to_copy = avail < (len - copied) ? avail : (len - copied);
|
|
240
|
+
memcpy(buf + copied, len_enc.data() + off_in_le, to_copy);
|
|
241
|
+
copied += to_copy;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
std::vector<uint8_t> first_chunk(kChunkSize);
|
|
246
|
+
read_s(0, first_chunk.data(), kChunkSize);
|
|
247
|
+
|
|
248
|
+
std::vector<uint8_t> final_node;
|
|
249
|
+
final_node.reserve(kChunkSize + 8 + ((s_len / kChunkSize) * cv_len) + 16);
|
|
250
|
+
final_node.insert(final_node.end(), first_chunk.begin(), first_chunk.end());
|
|
251
|
+
final_node.push_back(0x03);
|
|
252
|
+
final_node.insert(final_node.end(), 7, 0x00);
|
|
253
|
+
|
|
254
|
+
size_t offset = kChunkSize;
|
|
255
|
+
size_t num_blocks = 0;
|
|
256
|
+
std::vector<uint8_t> chunk(kChunkSize);
|
|
257
|
+
std::vector<uint8_t> cv(cv_len);
|
|
258
|
+
|
|
259
|
+
while (offset < s_len) {
|
|
260
|
+
size_t block_size = s_len - offset;
|
|
261
|
+
if (block_size > kChunkSize)
|
|
262
|
+
block_size = kChunkSize;
|
|
263
|
+
|
|
264
|
+
chunk.resize(block_size);
|
|
265
|
+
read_s(offset, chunk.data(), block_size);
|
|
266
|
+
|
|
267
|
+
turboshake(chunk.data(), block_size, 0x0B, cv.data(), cv_len);
|
|
268
|
+
final_node.insert(final_node.end(), cv.begin(), cv.end());
|
|
269
|
+
num_blocks++;
|
|
270
|
+
offset += block_size;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
auto num_blocks_enc = LengthEncode(num_blocks);
|
|
274
|
+
final_node.insert(final_node.end(), num_blocks_enc.begin(), num_blocks_enc.end());
|
|
275
|
+
final_node.push_back(0xFF);
|
|
276
|
+
final_node.push_back(0xFF);
|
|
277
|
+
|
|
278
|
+
turboshake(final_node.data(), final_node.size(), 0x06, output, output_len);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
void KT128(const uint8_t* message, size_t msg_len, const uint8_t* customization, size_t custom_len, uint8_t* output, size_t output_len) {
|
|
282
|
+
KangarooTwelve(message, msg_len, customization, custom_len, output, output_len, TurboSHAKE128, 32);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
void KT256(const uint8_t* message, size_t msg_len, const uint8_t* customization, size_t custom_len, uint8_t* output, size_t output_len) {
|
|
286
|
+
KangarooTwelve(message, msg_len, customization, custom_len, output, output_len, TurboSHAKE256, 64);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
uint8_t parseDomainSeparation(double value) {
|
|
290
|
+
if (!(value >= 0x01 && value <= 0x7F) || value != static_cast<double>(static_cast<uint8_t>(value))) {
|
|
291
|
+
throw std::runtime_error("TurboSHAKE domainSeparation must be an integer in 0x01..0x7F");
|
|
292
|
+
}
|
|
293
|
+
return static_cast<uint8_t>(value);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
uint32_t parseOutputLength(double value) {
|
|
297
|
+
if (!(value > 0)) {
|
|
298
|
+
throw std::runtime_error("outputLength must be > 0");
|
|
299
|
+
}
|
|
300
|
+
// 16 MiB upper bound matches HybridHash::setParams to keep memory bounded.
|
|
301
|
+
constexpr double kMaxOutputBytes = 16.0 * 1024.0 * 1024.0;
|
|
302
|
+
if (value > kMaxOutputBytes) {
|
|
303
|
+
throw std::runtime_error("outputLength exceeds maximum allowed size");
|
|
304
|
+
}
|
|
305
|
+
if (value != static_cast<double>(static_cast<uint32_t>(value))) {
|
|
306
|
+
throw std::runtime_error("outputLength must be an integer");
|
|
307
|
+
}
|
|
308
|
+
return static_cast<uint32_t>(value);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
} // namespace
|
|
312
|
+
|
|
313
|
+
std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>> HybridTurboShake::turboShake(TurboShakeVariant variant, double domainSeparation,
|
|
314
|
+
double outputLength,
|
|
315
|
+
const std::shared_ptr<ArrayBuffer>& data) {
|
|
316
|
+
uint8_t ds = parseDomainSeparation(domainSeparation);
|
|
317
|
+
uint32_t outLen = parseOutputLength(outputLength);
|
|
318
|
+
|
|
319
|
+
bool is128 = variant == TurboShakeVariant::TURBOSHAKE128;
|
|
320
|
+
|
|
321
|
+
auto nativeData = ToNativeArrayBuffer(data);
|
|
322
|
+
|
|
323
|
+
return Promise<std::shared_ptr<ArrayBuffer>>::async([is128, ds, outLen, nativeData]() -> std::shared_ptr<ArrayBuffer> {
|
|
324
|
+
auto outBuf = std::make_unique<uint8_t[]>(outLen);
|
|
325
|
+
const uint8_t* in = reinterpret_cast<const uint8_t*>(nativeData->data());
|
|
326
|
+
size_t inLen = nativeData->size();
|
|
327
|
+
if (is128) {
|
|
328
|
+
TurboSHAKE128(in, inLen, ds, outBuf.get(), outLen);
|
|
329
|
+
} else {
|
|
330
|
+
TurboSHAKE256(in, inLen, ds, outBuf.get(), outLen);
|
|
331
|
+
}
|
|
332
|
+
uint8_t* raw = outBuf.get();
|
|
333
|
+
return std::make_shared<NativeArrayBuffer>(outBuf.release(), outLen, [raw]() { delete[] raw; });
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>>
|
|
338
|
+
HybridTurboShake::kangarooTwelve(KangarooTwelveVariant variant, double outputLength, const std::shared_ptr<ArrayBuffer>& data,
|
|
339
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& customization) {
|
|
340
|
+
uint32_t outLen = parseOutputLength(outputLength);
|
|
341
|
+
|
|
342
|
+
bool is128 = variant == KangarooTwelveVariant::KT128;
|
|
343
|
+
|
|
344
|
+
auto nativeData = ToNativeArrayBuffer(data);
|
|
345
|
+
std::optional<std::shared_ptr<ArrayBuffer>> nativeCustom;
|
|
346
|
+
if (customization.has_value()) {
|
|
347
|
+
nativeCustom = ToNativeArrayBuffer(customization.value());
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return Promise<std::shared_ptr<ArrayBuffer>>::async(
|
|
351
|
+
[is128, outLen, nativeData, nativeCustom = std::move(nativeCustom)]() -> std::shared_ptr<ArrayBuffer> {
|
|
352
|
+
const uint8_t* in = reinterpret_cast<const uint8_t*>(nativeData->data());
|
|
353
|
+
size_t inLen = nativeData->size();
|
|
354
|
+
const uint8_t* custom = nullptr;
|
|
355
|
+
size_t customLen = 0;
|
|
356
|
+
if (nativeCustom.has_value() && nativeCustom.value()->size() > 0) {
|
|
357
|
+
custom = reinterpret_cast<const uint8_t*>(nativeCustom.value()->data());
|
|
358
|
+
customLen = nativeCustom.value()->size();
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Mirror Node's overflow guard for s_len = msg + custom + length_encode(|custom|).
|
|
362
|
+
// length_encode produces at most sizeof(size_t) + 1 bytes.
|
|
363
|
+
constexpr size_t kMaxLengthEncodeSize = sizeof(size_t) + 1;
|
|
364
|
+
if (inLen > SIZE_MAX - customLen || inLen + customLen > SIZE_MAX - kMaxLengthEncodeSize) {
|
|
365
|
+
throw std::runtime_error("KangarooTwelve input length overflow");
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
auto outBuf = std::make_unique<uint8_t[]>(outLen);
|
|
369
|
+
if (is128) {
|
|
370
|
+
KT128(in, inLen, custom, customLen, outBuf.get(), outLen);
|
|
371
|
+
} else {
|
|
372
|
+
KT256(in, inLen, custom, customLen, outBuf.get(), outLen);
|
|
373
|
+
}
|
|
374
|
+
uint8_t* raw = outBuf.get();
|
|
375
|
+
return std::make_shared<NativeArrayBuffer>(outBuf.release(), outLen, [raw]() { delete[] raw; });
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
} // namespace margelo::nitro::crypto
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <NitroModules/ArrayBuffer.hpp>
|
|
4
|
+
#include <NitroModules/Promise.hpp>
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <optional>
|
|
7
|
+
#include <string>
|
|
8
|
+
|
|
9
|
+
#include "HybridTurboShakeSpec.hpp"
|
|
10
|
+
|
|
11
|
+
namespace margelo::nitro::crypto {
|
|
12
|
+
|
|
13
|
+
using namespace facebook;
|
|
14
|
+
|
|
15
|
+
class HybridTurboShake : public HybridTurboShakeSpec {
|
|
16
|
+
public:
|
|
17
|
+
HybridTurboShake() : HybridObject(TAG) {}
|
|
18
|
+
|
|
19
|
+
public:
|
|
20
|
+
std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>> turboShake(TurboShakeVariant variant, double domainSeparation, double outputLength,
|
|
21
|
+
const std::shared_ptr<ArrayBuffer>& data) override;
|
|
22
|
+
|
|
23
|
+
std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>>
|
|
24
|
+
kangarooTwelve(KangarooTwelveVariant variant, double outputLength, const std::shared_ptr<ArrayBuffer>& data,
|
|
25
|
+
const std::optional<std::shared_ptr<ArrayBuffer>>& customization) override;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
} // namespace margelo::nitro::crypto
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#include "HybridUtils.hpp"
|
|
2
2
|
|
|
3
|
-
#include <NitroModules/JSIConverter
|
|
3
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
4
4
|
#include <bit>
|
|
5
5
|
#include <cstring>
|
|
6
6
|
#include <openssl/crypto.h>
|
|
@@ -142,11 +142,12 @@ namespace {
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
size_t offset = result.size();
|
|
145
|
-
result.
|
|
145
|
+
result.reserve(offset + (num * 2)); // Allocate buffer conservatively
|
|
146
146
|
|
|
147
|
-
auto* dst = result.data() + offset;
|
|
148
147
|
if (isAscii) {
|
|
149
148
|
// Widen ASCII characters from char into char16_t
|
|
149
|
+
result.resize(offset + (num * 2)); // This fills the buffer with '\0'
|
|
150
|
+
auto* dst = result.data() + offset;
|
|
150
151
|
const auto* asciiSrc = reinterpret_cast<const char*>(data);
|
|
151
152
|
for (size_t i = 0; i < num; i++, dst += 2) {
|
|
152
153
|
*dst = asciiSrc[i];
|
|
@@ -155,13 +156,16 @@ namespace {
|
|
|
155
156
|
return;
|
|
156
157
|
}
|
|
157
158
|
|
|
158
|
-
const auto* utf16Src = reinterpret_cast<const char16_t*>(data);
|
|
159
159
|
if constexpr (kCanDirectCopyUtf16) {
|
|
160
160
|
// Fast&direct copy path
|
|
161
|
-
|
|
161
|
+
const auto* byteSrc = reinterpret_cast<const uint8_t*>(data);
|
|
162
|
+
result.insert(result.end(), byteSrc, byteSrc + num * 2);
|
|
162
163
|
return;
|
|
163
164
|
}
|
|
164
165
|
// Slow path for unexpected endianness/char16_t size
|
|
166
|
+
result.resize(offset + (num * 2));
|
|
167
|
+
const auto* utf16Src = reinterpret_cast<const char16_t*>(data);
|
|
168
|
+
auto* dst = result.data() + offset;
|
|
165
169
|
for (size_t i = 0; i < num; i++) {
|
|
166
170
|
const uint16_t codeUnit = static_cast<uint16_t>(utf16Src[i]);
|
|
167
171
|
dst[i * 2 + 0] = static_cast<uint8_t>(codeUnit & 0xFFu);
|
|
@@ -175,7 +179,7 @@ namespace {
|
|
|
175
179
|
throw std::runtime_error("Unsupported encoding: utf16le");
|
|
176
180
|
}
|
|
177
181
|
|
|
178
|
-
std::vector<uint8_t>
|
|
182
|
+
std::vector<uint8_t> decodeLatin1FromUtf8(const std::string& str) {
|
|
179
183
|
std::vector<uint8_t> result;
|
|
180
184
|
result.reserve(str.size());
|
|
181
185
|
size_t i = 0;
|
|
@@ -204,6 +208,43 @@ namespace {
|
|
|
204
208
|
return result;
|
|
205
209
|
}
|
|
206
210
|
|
|
211
|
+
template <typename JSIString = facebook::jsi::String>
|
|
212
|
+
std::vector<uint8_t> decodeLatin1(facebook::jsi::Runtime& runtime, bool isHermes, const JSIString& str) {
|
|
213
|
+
if constexpr (HasStringGetStringData<JSIString>) {
|
|
214
|
+
if (isHermes) {
|
|
215
|
+
std::vector<uint8_t> result;
|
|
216
|
+
auto chunkCallback = [&result](bool isAscii, const void* data, size_t num) {
|
|
217
|
+
if (num == 0) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
size_t offset = result.size();
|
|
222
|
+
result.reserve(offset + num); // Allocate buffer conservatively
|
|
223
|
+
|
|
224
|
+
if (isAscii) {
|
|
225
|
+
// Fast&direct copy path
|
|
226
|
+
const auto* asciiSrc = reinterpret_cast<const uint8_t*>(data);
|
|
227
|
+
result.insert(result.end(), asciiSrc, asciiSrc + num);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
result.resize(offset + num);
|
|
232
|
+
const auto* utf16Src = reinterpret_cast<const char16_t*>(data);
|
|
233
|
+
auto* dst = result.data() + offset;
|
|
234
|
+
for (size_t i = 0; i < num; i++) {
|
|
235
|
+
// Node.js-like behavior
|
|
236
|
+
dst[i] = static_cast<uint8_t>(utf16Src[i] & 0xFFu);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
str.getStringData(runtime, chunkCallback);
|
|
241
|
+
return result;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// Slow path for non-Hermes runtime/old RN versions
|
|
245
|
+
return decodeLatin1FromUtf8(str.utf8(runtime));
|
|
246
|
+
}
|
|
247
|
+
|
|
207
248
|
std::string encodeLatin1(const uint8_t* data, size_t len) {
|
|
208
249
|
if (len == 0) {
|
|
209
250
|
return {};
|
|
@@ -231,47 +272,68 @@ bool HybridUtils::timingSafeEqual(const std::shared_ptr<ArrayBuffer>& a, const s
|
|
|
231
272
|
return CRYPTO_memcmp(a->data(), b->data(), aLen) == 0;
|
|
232
273
|
}
|
|
233
274
|
|
|
275
|
+
bool HybridUtils::isHermesRuntime(facebook::jsi::Runtime& runtime) {
|
|
276
|
+
// Cache assumes runtimes are long-lived and calls happen on the JS thread.
|
|
277
|
+
if (cachedRuntime_ != &runtime) [[unlikely]] {
|
|
278
|
+
cachedRuntime_ = &runtime;
|
|
279
|
+
cachedIsHermesRuntime_ = runtime.global().hasProperty(runtime, "HermesInternal");
|
|
280
|
+
}
|
|
281
|
+
return cachedIsHermesRuntime_;
|
|
282
|
+
}
|
|
283
|
+
|
|
234
284
|
facebook::jsi::Value HybridUtils::bufferToJsiString(facebook::jsi::Runtime& runtime, const facebook::jsi::Value&,
|
|
235
285
|
const facebook::jsi::Value* args, size_t argCount) {
|
|
236
286
|
// Runtime argument check from react-native-nitro-modules/cpp/core/HybridFunction.hpp
|
|
237
|
-
if (argCount !=
|
|
287
|
+
if (argCount != 4) [[unlikely]] {
|
|
238
288
|
throw facebook::jsi::JSError(runtime,
|
|
239
|
-
"`Utils.bufferToString(...)` expected
|
|
289
|
+
"`Utils.bufferToString(...)` expected 4 arguments, but received " + std::to_string(argCount) + "!");
|
|
240
290
|
}
|
|
241
291
|
|
|
242
292
|
// Exception wrapper from react-native-nitro-modules/cpp/core/HybridFunction.hpp
|
|
243
293
|
try {
|
|
244
|
-
// bufferToString(buffer: ArrayBuffer, encoding: string): string;
|
|
294
|
+
// bufferToString(buffer: ArrayBuffer, encoding: string, start: number, end: number): string;
|
|
295
|
+
// Defined in utils/conversion.ts
|
|
245
296
|
auto buffer = JSIConverter<std::shared_ptr<ArrayBuffer>>::fromJSI(runtime, args[0]);
|
|
246
297
|
std::string encoding = JSIConverter<std::string>::fromJSI(runtime, args[1]);
|
|
298
|
+
const size_t bufferSize = buffer->size();
|
|
299
|
+
// `start` and `end` are normalized in the TS code
|
|
300
|
+
// so it's safe to use `static_cast<size_t>` here
|
|
301
|
+
const size_t start = static_cast<size_t>(JSIConverter<double>::fromJSI(runtime, args[2]));
|
|
302
|
+
const size_t end = static_cast<size_t>(JSIConverter<double>::fromJSI(runtime, args[3]));
|
|
303
|
+
if (start > end || end > bufferSize) {
|
|
304
|
+
// This should never happen if called from the TS wrapper
|
|
305
|
+
// Add this check to avoid out of bounds access
|
|
306
|
+
throw std::runtime_error("Invalid start/end value");
|
|
307
|
+
}
|
|
308
|
+
const size_t offset = start;
|
|
309
|
+
const size_t length = end - start;
|
|
247
310
|
|
|
248
|
-
const auto* data = reinterpret_cast<const uint8_t*>(buffer->data());
|
|
249
|
-
size_t len = buffer->size();
|
|
311
|
+
const auto* data = reinterpret_cast<const uint8_t*>(buffer->data() + offset);
|
|
250
312
|
|
|
251
313
|
if (encoding == "hex") {
|
|
252
|
-
return facebook::jsi::String::
|
|
314
|
+
return facebook::jsi::String::createFromAscii(runtime, encodeHex(data, length));
|
|
253
315
|
}
|
|
254
316
|
if (encoding == "base64") {
|
|
255
|
-
return facebook::jsi::String::
|
|
317
|
+
return facebook::jsi::String::createFromAscii(runtime, encodeBase64(data, length));
|
|
256
318
|
}
|
|
257
319
|
if (encoding == "base64url") {
|
|
258
|
-
return facebook::jsi::String::
|
|
320
|
+
return facebook::jsi::String::createFromAscii(runtime, encodeBase64Url(data, length));
|
|
259
321
|
}
|
|
260
322
|
if (encoding == "utf8" || encoding == "utf-8") {
|
|
261
|
-
return facebook::jsi::String::createFromUtf8(runtime, data,
|
|
323
|
+
return facebook::jsi::String::createFromUtf8(runtime, data, length);
|
|
262
324
|
}
|
|
263
325
|
if (encoding == "latin1" || encoding == "binary") {
|
|
264
|
-
return facebook::jsi::String::createFromUtf8(runtime, encodeLatin1(data,
|
|
326
|
+
return facebook::jsi::String::createFromUtf8(runtime, encodeLatin1(data, length));
|
|
265
327
|
}
|
|
266
328
|
if (encoding == "ascii") {
|
|
267
|
-
std::string result(reinterpret_cast<const char*>(data),
|
|
329
|
+
std::string result(reinterpret_cast<const char*>(data), length);
|
|
268
330
|
for (auto& c : result) {
|
|
269
331
|
c &= 0x7F;
|
|
270
332
|
}
|
|
271
|
-
return facebook::jsi::String::
|
|
333
|
+
return facebook::jsi::String::createFromAscii(runtime, result);
|
|
272
334
|
}
|
|
273
335
|
if (encoding == "utf16le") {
|
|
274
|
-
return createUtf16LeString(runtime, data,
|
|
336
|
+
return createUtf16LeString(runtime, data, length);
|
|
275
337
|
}
|
|
276
338
|
throw std::runtime_error("Unsupported encoding: " + encoding);
|
|
277
339
|
} catch (const std::exception& exception) {
|
|
@@ -310,7 +372,7 @@ facebook::jsi::Value HybridUtils::jsiStringToBuffer(facebook::jsi::Runtime& runt
|
|
|
310
372
|
runtime, ArrayBuffer::copy(reinterpret_cast<const uint8_t*>(utf8Str.data()), utf8Str.size()));
|
|
311
373
|
}
|
|
312
374
|
if (encoding == "latin1" || encoding == "binary" || encoding == "ascii") {
|
|
313
|
-
auto decoded = decodeLatin1(
|
|
375
|
+
auto decoded = decodeLatin1(runtime, isHermesRuntime(runtime), str);
|
|
314
376
|
return JSIConverter<std::shared_ptr<ArrayBuffer>>::toJSI(runtime, ArrayBuffer::move(std::move(decoded)));
|
|
315
377
|
}
|
|
316
378
|
if (encoding == "utf16le") {
|
|
@@ -329,7 +391,7 @@ facebook::jsi::Value HybridUtils::jsiStringToBuffer(facebook::jsi::Runtime& runt
|
|
|
329
391
|
void HybridUtils::loadHybridMethods() {
|
|
330
392
|
HybridUtilsSpec::loadHybridMethods();
|
|
331
393
|
registerHybrids(this, [](Prototype& prototype) {
|
|
332
|
-
prototype.registerRawHybridMethod("bufferToString",
|
|
394
|
+
prototype.registerRawHybridMethod("bufferToString", 4, &HybridUtils::bufferToJsiString);
|
|
333
395
|
prototype.registerRawHybridMethod("stringToBuffer", 2, &HybridUtils::jsiStringToBuffer);
|
|
334
396
|
});
|
|
335
397
|
}
|
|
@@ -15,6 +15,10 @@ class HybridUtils : public HybridUtilsSpec {
|
|
|
15
15
|
void loadHybridMethods() override;
|
|
16
16
|
|
|
17
17
|
private:
|
|
18
|
+
facebook::jsi::Runtime* cachedRuntime_ = nullptr;
|
|
19
|
+
bool cachedIsHermesRuntime_ = false;
|
|
20
|
+
|
|
21
|
+
bool isHermesRuntime(facebook::jsi::Runtime& runtime);
|
|
18
22
|
facebook::jsi::Value bufferToJsiString(facebook::jsi::Runtime& runtime, const facebook::jsi::Value& thisArg,
|
|
19
23
|
const facebook::jsi::Value* args, size_t argCount);
|
|
20
24
|
facebook::jsi::Value jsiStringToBuffer(facebook::jsi::Runtime& runtime, const facebook::jsi::Value& thisArg,
|
package/deps/blake3/README.md
CHANGED
|
@@ -176,14 +176,13 @@ See [`c/README.md`](c/README.md).
|
|
|
176
176
|
|
|
177
177
|
### Other implementations
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
[
|
|
181
|
-
we hear about them. Some highlights include [an optimized Go
|
|
179
|
+
There are too many implementations out there for us to keep track of,
|
|
180
|
+
but some highlights include [an optimized Go
|
|
182
181
|
implementation](https://github.com/zeebo/blake3), [Wasm bindings for
|
|
183
182
|
Node.js and browsers](https://github.com/connor4312/blake3), [binary
|
|
184
183
|
wheels for Python](https://github.com/oconnor663/blake3-py), [.NET
|
|
185
|
-
bindings](https://github.com/xoofx/Blake3.NET), and [
|
|
186
|
-
|
|
184
|
+
bindings](https://github.com/xoofx/Blake3.NET), and [a pure Java
|
|
185
|
+
implementation](https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/digest/Blake3.html).
|
|
187
186
|
|
|
188
187
|
## Contributing
|
|
189
188
|
|
|
@@ -202,7 +201,7 @@ Alternatively, it is licensed under any of the following:
|
|
|
202
201
|
|
|
203
202
|
* [Bazel](https://github.com/bazelbuild/bazel/releases/tag/6.4.0)
|
|
204
203
|
* [Cargo](https://github.com/rust-lang/cargo/pull/14137)
|
|
205
|
-
* [Ccache](https://
|
|
204
|
+
* [Ccache](https://ccache.dev/releasenotes.html#_ccache_4_0)
|
|
206
205
|
* [Chia](https://github.com/Chia-Network/chia-blockchain/blob/main/CHANGELOG.md#10beta8-aka-beta-18---2020-07-16)
|
|
207
206
|
* [Clickhouse](https://github.com/ClickHouse/ClickHouse/blob/master/rust/chcache/Cargo.toml#L7)
|
|
208
207
|
* [Farcaster](https://www.farcaster.xyz/)
|
|
@@ -220,7 +219,7 @@ Alternatively, it is licensed under any of the following:
|
|
|
220
219
|
|
|
221
220
|
## Miscellany
|
|
222
221
|
|
|
223
|
-
- [@veorq] and [@oconnor663] did [an interview with Cryptography FM](https://
|
|
222
|
+
- [@veorq] and [@oconnor663] did [an interview with Cryptography FM](https://cryptography.fireside.fm/3).
|
|
224
223
|
- [@oconnor663] did [an interview with Saito](https://www.youtube.com/watch?v=cJkmIt7yN_E).
|
|
225
224
|
|
|
226
225
|
[@oconnor663]: https://github.com/oconnor663
|
package/deps/blake3/c/blake3.c
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#include <assert.h>
|
|
2
2
|
#include <stdbool.h>
|
|
3
3
|
#include <string.h>
|
|
4
|
+
#include <stdint.h>
|
|
4
5
|
|
|
5
6
|
#include "blake3.h"
|
|
6
7
|
#include "blake3_impl.h"
|
|
@@ -303,8 +304,8 @@ size_t blake3_compress_subtree_wide(const uint8_t *input, size_t input_len,
|
|
|
303
304
|
uint8_t *right_cvs = &cv_array[degree * BLAKE3_OUT_LEN];
|
|
304
305
|
|
|
305
306
|
// Recurse!
|
|
306
|
-
size_t left_n =
|
|
307
|
-
size_t right_n =
|
|
307
|
+
size_t left_n = SIZE_MAX;
|
|
308
|
+
size_t right_n = SIZE_MAX;
|
|
308
309
|
|
|
309
310
|
#if defined(BLAKE3_USE_TBB)
|
|
310
311
|
blake3_compress_subtree_wide_join_tbb(
|