ox 1.0.4 → 1.1.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.
Files changed (230) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/dist/core/Base64.d.ts +10 -21
  3. package/dist/core/Base64.d.ts.map +1 -1
  4. package/dist/core/Base64.js +8 -127
  5. package/dist/core/Base64.js.map +1 -1
  6. package/dist/core/BinaryStateTree.d.ts.map +1 -1
  7. package/dist/core/BinaryStateTree.js +2 -2
  8. package/dist/core/BinaryStateTree.js.map +1 -1
  9. package/dist/core/Bls.d.ts.map +1 -1
  10. package/dist/core/Bls.js +19 -44
  11. package/dist/core/Bls.js.map +1 -1
  12. package/dist/core/Ed25519.d.ts.map +1 -1
  13. package/dist/core/Ed25519.js +7 -6
  14. package/dist/core/Ed25519.js.map +1 -1
  15. package/dist/core/Engine.d.ts +124 -0
  16. package/dist/core/Engine.d.ts.map +1 -0
  17. package/dist/core/Engine.js +180 -0
  18. package/dist/core/Engine.js.map +1 -0
  19. package/dist/core/Hash.d.ts +4 -4
  20. package/dist/core/Hash.d.ts.map +1 -1
  21. package/dist/core/Hash.js +9 -12
  22. package/dist/core/Hash.js.map +1 -1
  23. package/dist/core/Keystore.d.ts.map +1 -1
  24. package/dist/core/Keystore.js +15 -10
  25. package/dist/core/Keystore.js.map +1 -1
  26. package/dist/core/Mnemonic.d.ts.map +1 -1
  27. package/dist/core/Mnemonic.js +3 -2
  28. package/dist/core/Mnemonic.js.map +1 -1
  29. package/dist/core/P256.d.ts.map +1 -1
  30. package/dist/core/P256.js +8 -9
  31. package/dist/core/P256.js.map +1 -1
  32. package/dist/core/Secp256k1.d.ts.map +1 -1
  33. package/dist/core/Secp256k1.js +8 -9
  34. package/dist/core/Secp256k1.js.map +1 -1
  35. package/dist/core/WebCryptoP256.d.ts.map +1 -1
  36. package/dist/core/WebCryptoP256.js +2 -2
  37. package/dist/core/WebCryptoP256.js.map +1 -1
  38. package/dist/core/X25519.d.ts.map +1 -1
  39. package/dist/core/X25519.js +4 -3
  40. package/dist/core/X25519.js.map +1 -1
  41. package/dist/core/internal/bls.d.ts +12 -0
  42. package/dist/core/internal/bls.d.ts.map +1 -0
  43. package/dist/core/internal/bls.js +79 -0
  44. package/dist/core/internal/bls.js.map +1 -0
  45. package/dist/core/internal/codec/base64.d.ts +84 -0
  46. package/dist/core/internal/codec/base64.d.ts.map +1 -0
  47. package/dist/core/internal/codec/base64.js +177 -0
  48. package/dist/core/internal/codec/base64.js.map +1 -0
  49. package/dist/core/internal/codec/hex.d.ts +49 -4
  50. package/dist/core/internal/codec/hex.d.ts.map +1 -1
  51. package/dist/core/internal/codec/hex.js +109 -35
  52. package/dist/core/internal/codec/hex.js.map +1 -1
  53. package/dist/core/internal/curves.d.ts +17 -0
  54. package/dist/core/internal/curves.d.ts.map +1 -0
  55. package/dist/core/internal/curves.js +17 -0
  56. package/dist/core/internal/curves.js.map +1 -0
  57. package/dist/core/internal/ed25519.d.ts +14 -0
  58. package/dist/core/internal/ed25519.d.ts.map +1 -0
  59. package/dist/core/internal/ed25519.js +29 -0
  60. package/dist/core/internal/ed25519.js.map +1 -0
  61. package/dist/core/internal/engine.d.ts +278 -0
  62. package/dist/core/internal/engine.d.ts.map +1 -0
  63. package/dist/core/internal/engine.js +131 -0
  64. package/dist/core/internal/engine.js.map +1 -0
  65. package/dist/core/internal/hash.d.ts +12 -0
  66. package/dist/core/internal/hash.d.ts.map +1 -0
  67. package/dist/core/internal/hash.js +30 -0
  68. package/dist/core/internal/hash.js.map +1 -0
  69. package/dist/core/internal/keystore.d.ts +14 -0
  70. package/dist/core/internal/keystore.d.ts.map +1 -0
  71. package/dist/core/internal/keystore.js +32 -0
  72. package/dist/core/internal/keystore.js.map +1 -0
  73. package/dist/core/internal/mnemonic.d.ts +4 -0
  74. package/dist/core/internal/mnemonic.d.ts.map +1 -0
  75. package/dist/core/internal/mnemonic.js +14 -0
  76. package/dist/core/internal/mnemonic.js.map +1 -0
  77. package/dist/core/internal/p256.d.ts +14 -0
  78. package/dist/core/internal/p256.d.ts.map +1 -0
  79. package/dist/core/internal/p256.js +36 -0
  80. package/dist/core/internal/p256.js.map +1 -0
  81. package/dist/core/internal/secp256k1.d.ts +14 -0
  82. package/dist/core/internal/secp256k1.d.ts.map +1 -0
  83. package/dist/core/internal/secp256k1.js +36 -0
  84. package/dist/core/internal/secp256k1.js.map +1 -0
  85. package/dist/core/internal/x25519.d.ts +8 -0
  86. package/dist/core/internal/x25519.d.ts.map +1 -0
  87. package/dist/core/internal/x25519.js +20 -0
  88. package/dist/core/internal/x25519.js.map +1 -0
  89. package/dist/index.d.ts +35 -0
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.docs.d.ts +2 -0
  92. package/dist/index.docs.d.ts.map +1 -1
  93. package/dist/index.docs.js +2 -0
  94. package/dist/index.docs.js.map +1 -1
  95. package/dist/index.js +35 -0
  96. package/dist/index.js.map +1 -1
  97. package/dist/node/Engine.d.ts +55 -0
  98. package/dist/node/Engine.d.ts.map +1 -0
  99. package/dist/node/Engine.js +51 -0
  100. package/dist/node/Engine.js.map +1 -0
  101. package/dist/node/Hash.d.ts +39 -0
  102. package/dist/node/Hash.d.ts.map +1 -0
  103. package/dist/node/Hash.js +37 -0
  104. package/dist/node/Hash.js.map +1 -0
  105. package/dist/node/index.d.ts +39 -0
  106. package/dist/node/index.d.ts.map +1 -0
  107. package/dist/node/index.js +39 -0
  108. package/dist/node/index.js.map +1 -0
  109. package/dist/tempo/VirtualMaster.d.ts +2 -0
  110. package/dist/tempo/VirtualMaster.d.ts.map +1 -1
  111. package/dist/tempo/VirtualMaster.js +19 -5
  112. package/dist/tempo/VirtualMaster.js.map +1 -1
  113. package/dist/tempo/ZoneId.d.ts +35 -17
  114. package/dist/tempo/ZoneId.d.ts.map +1 -1
  115. package/dist/tempo/ZoneId.js +41 -16
  116. package/dist/tempo/ZoneId.js.map +1 -1
  117. package/dist/tempo/index.d.ts +5 -6
  118. package/dist/tempo/index.d.ts.map +1 -1
  119. package/dist/tempo/index.js +5 -6
  120. package/dist/tempo/index.js.map +1 -1
  121. package/dist/tempo/internal/mine.wasm.d.ts +2 -4
  122. package/dist/tempo/internal/mine.wasm.d.ts.map +1 -1
  123. package/dist/tempo/internal/mine.wasm.js +7 -12
  124. package/dist/tempo/internal/mine.wasm.js.map +1 -1
  125. package/dist/tempo/internal/virtualMasterPool.js +4 -1
  126. package/dist/tempo/internal/virtualMasterPool.js.map +1 -1
  127. package/dist/wasm/Engine.d.ts +62 -0
  128. package/dist/wasm/Engine.d.ts.map +1 -0
  129. package/dist/wasm/Engine.js +57 -0
  130. package/dist/wasm/Engine.js.map +1 -0
  131. package/dist/wasm/Hash.d.ts +49 -0
  132. package/dist/wasm/Hash.d.ts.map +1 -0
  133. package/dist/wasm/Hash.js +70 -0
  134. package/dist/wasm/Hash.js.map +1 -0
  135. package/dist/wasm/index.d.ts +46 -0
  136. package/dist/wasm/index.d.ts.map +1 -0
  137. package/dist/wasm/index.js +46 -0
  138. package/dist/wasm/index.js.map +1 -0
  139. package/dist/wasm/internal/hash.d.ts +9 -0
  140. package/dist/wasm/internal/hash.d.ts.map +1 -0
  141. package/dist/wasm/internal/hash.js +26 -0
  142. package/dist/wasm/internal/hash.js.map +1 -0
  143. package/dist/wasm/internal/hashes.wasm.d.ts +5 -0
  144. package/dist/wasm/internal/hashes.wasm.d.ts.map +1 -0
  145. package/dist/wasm/internal/hashes.wasm.js +12 -0
  146. package/dist/wasm/internal/hashes.wasm.js.map +1 -0
  147. package/dist/wasm/internal/instantiate.d.ts +56 -0
  148. package/dist/wasm/internal/instantiate.d.ts.map +1 -0
  149. package/dist/wasm/internal/instantiate.js +92 -0
  150. package/dist/wasm/internal/instantiate.js.map +1 -0
  151. package/dist/zod/TypedData.d.ts +12 -12
  152. package/package.json +36 -1
  153. package/src/core/Base64.ts +19 -166
  154. package/src/core/BinaryStateTree.ts +2 -3
  155. package/src/core/Bls.ts +27 -77
  156. package/src/core/Ed25519.ts +7 -7
  157. package/src/core/Engine.ts +235 -0
  158. package/src/core/Hash.ts +9 -12
  159. package/src/core/Keystore.ts +17 -17
  160. package/src/core/Mnemonic.ts +3 -6
  161. package/src/core/P256.ts +15 -24
  162. package/src/core/Rlp_tx.bench.ts +2 -4
  163. package/src/core/Secp256k1.ts +9 -14
  164. package/src/core/TxEnvelopeEip1559.bench.ts +0 -5
  165. package/src/core/WebCryptoP256.ts +2 -2
  166. package/src/core/X25519.ts +4 -3
  167. package/src/core/_test/AbiParameters.adversarial.fuzz.ts +1 -2
  168. package/src/core/_test/AbiParameters.fuzz.ts +1 -2
  169. package/src/core/_test/Base.fuzz.ts +1 -2
  170. package/src/core/_test/Cbor.fuzz.ts +1 -2
  171. package/src/core/_test/Engine.fuzz.ts +293 -0
  172. package/src/core/_test/Engine.test-d.ts +84 -0
  173. package/src/core/_test/Engine.test.ts +523 -0
  174. package/src/core/_test/Hash.vectors.test.ts +56 -0
  175. package/src/core/_test/Hex.fuzz.ts +1 -2
  176. package/src/core/_test/Rlp.fuzz.ts +1 -2
  177. package/src/core/_test/Signature.fuzz.ts +1 -2
  178. package/src/core/_test/curves.test.ts +7 -0
  179. package/src/core/_test/index.test.ts +1 -0
  180. package/src/core/internal/bls.ts +121 -0
  181. package/src/core/internal/codec/_test/base64.conformance.ts +156 -0
  182. package/src/core/internal/codec/_test/hex.conformance.ts +204 -0
  183. package/src/core/internal/codec/_test/hex.fuzz.ts +234 -0
  184. package/src/core/internal/codec/_test/hex.test.ts +124 -0
  185. package/src/core/internal/codec/base64.ts +222 -0
  186. package/src/core/internal/codec/hex.ts +115 -34
  187. package/src/core/internal/curves.ts +18 -0
  188. package/src/core/internal/ed25519.ts +64 -0
  189. package/src/core/internal/engine.ts +410 -0
  190. package/src/core/internal/hash.ts +48 -0
  191. package/src/core/internal/keystore.ts +107 -0
  192. package/src/core/internal/mnemonic.ts +18 -0
  193. package/src/core/internal/p256.ts +91 -0
  194. package/src/core/internal/secp256k1.ts +91 -0
  195. package/src/core/internal/x25519.ts +40 -0
  196. package/src/index.docs.ts +2 -0
  197. package/src/index.ts +36 -0
  198. package/src/node/Engine.ts +69 -0
  199. package/src/node/Hash.ts +56 -0
  200. package/src/node/_test/Engine.test.ts +62 -0
  201. package/src/node/_test/Hash.test-d.ts +26 -0
  202. package/src/node/_test/Hash.test.ts +102 -0
  203. package/src/node/index.ts +40 -0
  204. package/src/tempo/VirtualMaster.test.ts +75 -0
  205. package/src/tempo/VirtualMaster.ts +28 -6
  206. package/src/tempo/ZoneId.test-d.ts +16 -0
  207. package/src/tempo/ZoneId.test.ts +48 -13
  208. package/src/tempo/ZoneId.ts +55 -19
  209. package/src/tempo/index.ts +5 -6
  210. package/src/tempo/internal/mine.wasm.ts +7 -13
  211. package/src/tempo/internal/virtualMasterPool.ts +4 -1
  212. package/src/tsconfig.json +2 -1
  213. package/src/version.ts +1 -1
  214. package/src/wasm/Engine.ts +76 -0
  215. package/src/wasm/Hash.bench.ts +60 -0
  216. package/src/wasm/Hash.ts +109 -0
  217. package/src/wasm/_test/Engine.test.ts +62 -0
  218. package/src/wasm/_test/Hash.browser.test.ts +50 -0
  219. package/src/wasm/_test/Hash.fuzz.ts +188 -0
  220. package/src/wasm/_test/Hash.test-d.ts +28 -0
  221. package/src/wasm/_test/Hash.test.ts +211 -0
  222. package/src/wasm/_test/Hash.vectors.test.ts +117 -0
  223. package/src/wasm/_test/Runtime.test.ts +21 -0
  224. package/src/wasm/_test/runtime.wasm.ts +11 -0
  225. package/src/wasm/index.ts +47 -0
  226. package/src/wasm/internal/hash.ts +50 -0
  227. package/src/wasm/internal/hashes.wasm.ts +14 -0
  228. package/src/wasm/internal/instantiate.ts +135 -0
  229. package/src/zod/tempo/_test/ZoneId.test.ts +2 -2
  230. package/src/tempo/internal/mine.c +0 -182
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "ox",
3
3
  "description": "Ethereum Standard Library",
4
4
  "type": "module",
5
- "version": "1.0.4",
5
+ "version": "1.1.0",
6
6
  "main": "./dist/index.js",
7
7
  "sideEffects": false,
8
8
  "license": "MIT",
@@ -220,6 +220,11 @@
220
220
  "types": "./dist/core/Ed25519.d.ts",
221
221
  "default": "./dist/core/Ed25519.js"
222
222
  },
223
+ "./Engine": {
224
+ "src": "./src/core/Engine.ts",
225
+ "types": "./dist/core/Engine.d.ts",
226
+ "default": "./dist/core/Engine.js"
227
+ },
223
228
  "./Ens": {
224
229
  "src": "./src/core/Ens.ts",
225
230
  "types": "./dist/core/Ens.d.ts",
@@ -505,6 +510,21 @@
505
510
  "types": "./dist/erc8021/Attribution.d.ts",
506
511
  "default": "./dist/erc8021/Attribution.js"
507
512
  },
513
+ "./node": {
514
+ "src": "./src/node/index.ts",
515
+ "types": "./dist/node/index.d.ts",
516
+ "default": "./dist/node/index.js"
517
+ },
518
+ "./node/Engine": {
519
+ "src": "./src/node/Engine.ts",
520
+ "types": "./dist/node/Engine.d.ts",
521
+ "default": "./dist/node/Engine.js"
522
+ },
523
+ "./node/Hash": {
524
+ "src": "./src/node/Hash.ts",
525
+ "types": "./dist/node/Hash.d.ts",
526
+ "default": "./dist/node/Hash.js"
527
+ },
508
528
  "./tempo": {
509
529
  "src": "./src/tempo/index.ts",
510
530
  "types": "./dist/tempo/index.d.ts",
@@ -620,6 +640,21 @@
620
640
  "types": "./dist/trusted-setups/Paths.d.ts",
621
641
  "default": "./dist/trusted-setups/Paths.js"
622
642
  },
643
+ "./wasm": {
644
+ "src": "./src/wasm/index.ts",
645
+ "types": "./dist/wasm/index.d.ts",
646
+ "default": "./dist/wasm/index.js"
647
+ },
648
+ "./wasm/Engine": {
649
+ "src": "./src/wasm/Engine.ts",
650
+ "types": "./dist/wasm/Engine.d.ts",
651
+ "default": "./dist/wasm/Engine.js"
652
+ },
653
+ "./wasm/Hash": {
654
+ "src": "./src/wasm/Hash.ts",
655
+ "types": "./dist/wasm/Hash.d.ts",
656
+ "default": "./dist/wasm/Hash.js"
657
+ },
623
658
  "./webauthn": {
624
659
  "src": "./src/webauthn/index.ts",
625
660
  "types": "./dist/webauthn/index.d.ts",
@@ -1,66 +1,7 @@
1
1
  import * as Bytes from './Bytes.js'
2
- import * as Errors from './Errors.js'
2
+ import type * as Errors from './Errors.js'
3
3
  import * as Hex from './Hex.js'
4
- import { decoder } from './internal/codec/utf8.js'
5
-
6
- // Standard Base64 alphabet (RFC 4648 section 4) and URL-safe alphabet (section 5).
7
- const stdAlphabet =
8
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
9
-
10
- // Char-code -> 6-bit integer lookup. Sentinel `0xff` = invalid character.
11
- // Standard alphabet plus URL-safe `-`/`_` (decoders are alphabet-agnostic).
12
- const characterToInteger = /*#__PURE__*/ (() => {
13
- const table = new Uint8Array(256).fill(0xff)
14
- for (let i = 0; i < stdAlphabet.length; i++)
15
- table[stdAlphabet.charCodeAt(i)] = i
16
- // URL-safe alternates: `-` for `+` (62), `_` for `/` (63).
17
- table[45 /* '-' */] = 62
18
- table[95 /* '_' */] = 63
19
- return table
20
- })()
21
-
22
- // Integer -> char-code table for the standard alphabet, indexed by 6-bit value.
23
- const integerToCharacter = /*#__PURE__*/ (() => {
24
- const table = new Uint8Array(64)
25
- for (let i = 0; i < stdAlphabet.length; i++)
26
- table[i] = stdAlphabet.charCodeAt(i)
27
- return table
28
- })()
29
-
30
- // Phase 2 native fast-path detection: `Uint8Array.prototype.toBase64` /
31
- // `Uint8Array.fromBase64` ship in Node 22+, Safari 18+, Firefox 133+.
32
- const nativeToBase64:
33
- | ((
34
- this: Uint8Array,
35
- options?: { alphabet?: 'base64' | 'base64url'; omitPadding?: boolean },
36
- ) => string)
37
- | undefined = (
38
- Uint8Array.prototype as Uint8Array & {
39
- toBase64?: (options?: {
40
- alphabet?: 'base64' | 'base64url'
41
- omitPadding?: boolean
42
- }) => string
43
- }
44
- ).toBase64
45
- const nativeFromBase64:
46
- | ((
47
- value: string,
48
- options?: {
49
- alphabet?: 'base64' | 'base64url-or-base64'
50
- lastChunkHandling?: 'loose' | 'strict' | 'stop-before-partial'
51
- },
52
- ) => Uint8Array)
53
- | undefined = (
54
- Uint8Array as typeof Uint8Array & {
55
- fromBase64?: (
56
- value: string,
57
- options?: {
58
- alphabet?: 'base64' | 'base64url-or-base64'
59
- lastChunkHandling?: 'loose' | 'strict' | 'stop-before-partial'
60
- },
61
- ) => Uint8Array
62
- }
63
- ).fromBase64
4
+ import * as internal from './internal/codec/base64.js'
64
5
 
65
6
  /**
66
7
  * Encodes a {@link ox#Bytes.Bytes} to a Base64-encoded string (with optional padding and/or URL-safe characters).
@@ -109,39 +50,7 @@ const nativeFromBase64:
109
50
  * @returns The Base64 encoded string.
110
51
  */
111
52
  export function fromBytes(value: Bytes.Bytes, options: fromBytes.Options = {}) {
112
- const { pad = true, url = false } = options
113
-
114
- if (nativeToBase64) {
115
- const out = nativeToBase64.call(value, {
116
- alphabet: url ? 'base64url' : 'base64',
117
- omitPadding: !pad,
118
- })
119
- // Native `base64url` already omits padding; if pad was requested, restore it.
120
- if (url && pad) {
121
- const k = value.length % 3
122
- if (k === 1) return `${out}==`
123
- if (k === 2) return `${out}=`
124
- }
125
- return out
126
- }
127
-
128
- const encoded = new Uint8Array(Math.ceil(value.length / 3) * 4)
129
-
130
- for (let i = 0, j = 0; j < value.length; i += 4, j += 3) {
131
- const y = (value[j]! << 16) + (value[j + 1]! << 8) + (value[j + 2]! | 0)
132
- encoded[i] = integerToCharacter[y >> 18]!
133
- encoded[i + 1] = integerToCharacter[(y >> 12) & 0x3f]!
134
- encoded[i + 2] = integerToCharacter[(y >> 6) & 0x3f]!
135
- encoded[i + 3] = integerToCharacter[y & 0x3f]!
136
- }
137
-
138
- const k = value.length % 3
139
- const end = Math.floor(value.length / 3) * 4 + (k && k + 1)
140
- let base64 = decoder.decode(new Uint8Array(encoded.buffer, 0, end))
141
- if (pad && k === 1) base64 += '=='
142
- if (pad && k === 2) base64 += '='
143
- if (url) base64 = base64.replaceAll('+', '-').replaceAll('/', '_')
144
- return base64
53
+ return internal.fromBytes(value, options)
145
54
  }
146
55
 
147
56
  export declare namespace fromBytes {
@@ -307,54 +216,7 @@ export declare namespace fromString {
307
216
  * @returns The Base64 decoded {@link ox#Bytes.Bytes}.
308
217
  */
309
218
  export function toBytes(value: string): Bytes.Bytes {
310
- // Strip trailing '=' padding (only at the very end).
311
- let bodyEnd = value.length
312
- let pad = 0
313
- while (bodyEnd > 0 && value.charCodeAt(bodyEnd - 1) === 61 /* '=' */) {
314
- bodyEnd--
315
- pad++
316
- }
317
-
318
- const size = bodyEnd
319
- // Reject impossible lengths and excessive padding.
320
- if (size % 4 === 1) throw new InvalidLengthError({ length: value.length })
321
- if (pad > 2) throw new InvalidPaddingError({ padding: pad })
322
-
323
- if (nativeFromBase64) {
324
- try {
325
- // `base64url-or-base64` accepts both alphabets transparently.
326
- return nativeFromBase64(value.slice(0, bodyEnd), {
327
- alphabet: 'base64url-or-base64',
328
- lastChunkHandling: 'loose',
329
- })
330
- } catch {
331
- // Fall through to the JS path so we throw the typed error class.
332
- }
333
- }
334
-
335
- // Validate characters: every char must be in the standard or URL-safe
336
- // alphabet, and '=' may not appear in the body (only stripped trailing
337
- // padding).
338
- const decoded = new Uint8Array(
339
- (size >> 2) * 3 + (size % 4 ? (size % 4) - 1 : 0),
340
- )
341
- let acc = 0
342
- let bits = 0
343
- let n = 0
344
- for (let i = 0; i < size; i++) {
345
- const code = value.charCodeAt(i)
346
- if (code === 61 /* '=' */)
347
- throw new InvalidCharacterError({ character: '=' })
348
- const v = characterToInteger[code]!
349
- if (v === 0xff) throw new InvalidCharacterError({ character: value[i]! })
350
- acc = (acc << 6) | v
351
- bits += 6
352
- if (bits >= 8) {
353
- bits -= 8
354
- decoded[n++] = (acc >>> bits) & 0xff
355
- }
356
- }
357
- return decoded
219
+ return internal.toBytes(value)
358
220
  }
359
221
 
360
222
  export declare namespace toBytes {
@@ -409,29 +271,20 @@ export declare namespace toString {
409
271
  type ErrorType = toBytes.ErrorType | Errors.GlobalErrorType
410
272
  }
411
273
 
412
- /** Thrown when a Base64 string contains an invalid character. */
413
- export class InvalidCharacterError extends Errors.BaseError {
414
- override readonly name = 'Base64.InvalidCharacterError'
415
-
416
- constructor({ character }: { character: string }) {
417
- super(`Invalid Base64 character: "${character}".`)
418
- }
419
- }
274
+ /** Thrown when a Base64 string contains a character outside its alphabet. */
275
+ export const InvalidCharacterError = internal.InvalidCharacterError
276
+ export type InvalidCharacterError = InstanceType<
277
+ typeof internal.InvalidCharacterError
278
+ >
420
279
 
421
280
  /** Thrown when a Base64 string has an impossible length. */
422
- export class InvalidLengthError extends Errors.BaseError {
423
- override readonly name = 'Base64.InvalidLengthError'
424
-
425
- constructor({ length }: { length: number }) {
426
- super(`Invalid Base64 input length \`${length}\`.`)
427
- }
428
- }
429
-
430
- /** Thrown when a Base64 string contains too many trailing `=` padding characters. */
431
- export class InvalidPaddingError extends Errors.BaseError {
432
- override readonly name = 'Base64.InvalidPaddingError'
433
-
434
- constructor({ padding }: { padding: number }) {
435
- super(`Invalid Base64 padding length \`${padding}\` (must be 0, 1, or 2).`)
436
- }
437
- }
281
+ export const InvalidLengthError = internal.InvalidLengthError
282
+ export type InvalidLengthError = InstanceType<
283
+ typeof internal.InvalidLengthError
284
+ >
285
+
286
+ /** Thrown when a Base64 string carries more than two padding characters. */
287
+ export const InvalidPaddingError = internal.InvalidPaddingError
288
+ export type InvalidPaddingError = InstanceType<
289
+ typeof internal.InvalidPaddingError
290
+ >
@@ -1,6 +1,5 @@
1
- import { blake3 } from '@noble/hashes/blake3.js'
2
-
3
1
  import * as Bytes from './Bytes.js'
2
+ import * as engine from './internal/hash.js'
4
3
  import type { OneOf } from './internal/types.js'
5
4
 
6
5
  /** Type that defines a Binary State Tree instance. */
@@ -276,5 +275,5 @@ function bitsToBytes(bits: number[]): Bytes.Bytes {
276
275
  function hash(bytes: Bytes.Bytes | undefined): Bytes.Bytes {
277
276
  if (!bytes) return new Uint8Array(32).fill(0)
278
277
  if (!bytes.some((byte) => byte !== 0)) return new Uint8Array(32).fill(0)
279
- return blake3(bytes)
278
+ return engine.blake3(bytes)
280
279
  }
package/src/core/Bls.ts CHANGED
@@ -4,6 +4,7 @@ import * as BlsPoint from './BlsPoint.js'
4
4
  import * as Bytes from './Bytes.js'
5
5
  import * as Errors from './Errors.js'
6
6
  import * as Hex from './Hex.js'
7
+ import * as engine from './internal/bls.js'
7
8
  import type { OneOf } from './internal/types.js'
8
9
 
9
10
  /**
@@ -116,12 +117,11 @@ export function aggregate(
116
117
  return point
117
118
  })
118
119
 
119
- const first = normalized[0]!
120
+ // A single point aggregates to itself. The engine is not consulted because
121
+ // there is no addition to perform, only the identity.
122
+ if (normalized.length === 1) return normalized[0]!
120
123
 
121
- // Fast path: a single point aggregates to itself.
122
- if (normalized.length === 1) return first
123
-
124
- const isG1 = typeof first.x === 'string'
124
+ const isG1 = typeof normalized[0]!.x === 'string'
125
125
  for (let i = 1; i < normalized.length; i++) {
126
126
  if ((typeof normalized[i]!.x === 'string') !== isG1)
127
127
  throw new Errors.BaseError(
@@ -130,13 +130,13 @@ export function aggregate(
130
130
  }
131
131
 
132
132
  const groupName = isG1 ? 'G1' : 'G2'
133
- const group = isG1 ? bls.G1 : bls.G2
134
- let acc = group.Point.ZERO
135
- for (let i = 0; i < normalized.length; i++) {
136
- const p = normalized[i]!
137
- acc = acc.add(BlsPoint.toNoblePoint(p as any, groupName) as any)
138
- }
139
- return BlsPoint.fromNoblePoint(acc, groupName) as BlsPoint.BlsPoint
133
+ const point = engine.aggregate(
134
+ normalized.map((point) =>
135
+ BlsPoint.toBytes(point as BlsPoint.G1 | BlsPoint.G2),
136
+ ),
137
+ groupName,
138
+ )
139
+ return BlsPoint.fromBytes(point, groupName) as BlsPoint.BlsPoint
140
140
  }
141
141
 
142
142
  export declare namespace aggregate {
@@ -349,14 +349,8 @@ export function getPublicKey<
349
349
  export function getPublicKey(options: getPublicKey.Options): unknown {
350
350
  const { as = 'Object', privateKey, size = 'short-key:long-sig' } = options
351
351
  const groupName = size === 'short-key:long-sig' ? 'G1' : 'G2'
352
- const group = groupName === 'G1' ? bls.G1 : bls.G2
353
- const point = group.Point.BASE.multiply(
354
- group.Point.Fn.fromBytes(Bytes.from(privateKey)),
355
- )
356
- const publicKey = BlsPoint.fromNoblePoint(
357
- point,
358
- groupName,
359
- ) as BlsPoint.BlsPoint
352
+ const point = engine.getPublicKey(Bytes.from(privateKey), groupName)
353
+ const publicKey = BlsPoint.fromBytes(point, groupName) as BlsPoint.BlsPoint
360
354
  return formatBlsPoint(publicKey, as)
361
355
  }
362
356
 
@@ -422,7 +416,7 @@ export function randomPrivateKey<as extends 'Hex' | 'Bytes' = 'Hex'>(
422
416
  options: randomPrivateKey.Options<as> = {},
423
417
  ): randomPrivateKey.ReturnType<as> {
424
418
  const { as = 'Hex' } = options
425
- const bytes = bls.utils.randomSecretKey()
419
+ const bytes = engine.randomSecretKey()
426
420
  if (as === 'Hex') return Hex.fromBytes(bytes) as never
427
421
  return bytes as never
428
422
  }
@@ -507,18 +501,11 @@ export function sign(options: sign.Options): unknown {
507
501
 
508
502
  const signatureGroupName: 'G1' | 'G2' =
509
503
  size === 'short-key:long-sig' ? 'G2' : 'G1'
510
- const payloadGroup = signatureGroupName === 'G2' ? bls.G2 : bls.G1
511
- const payloadPoint = payloadGroup.hashToCurve(
512
- Bytes.from(payload),
513
- suite ? { DST: Bytes.fromString(suite) } : undefined,
514
- )
515
-
516
- const privateKeyGroup = size === 'short-key:long-sig' ? bls.G1 : bls.G2
517
- const signature = payloadPoint.multiply(
518
- privateKeyGroup.Point.Fn.fromBytes(Bytes.from(privateKey)),
519
- )
520
-
521
- const result = BlsPoint.fromNoblePoint(
504
+ const signature = engine.sign(Bytes.from(payload), Bytes.from(privateKey), {
505
+ dst: suite ? Bytes.fromString(suite) : undefined,
506
+ group: signatureGroupName,
507
+ })
508
+ const result = BlsPoint.fromBytes(
522
509
  signature,
523
510
  signatureGroupName,
524
511
  ) as BlsPoint.BlsPoint
@@ -674,51 +661,14 @@ export function verify(options: verify.Options): boolean {
674
661
  : normalizeBlsPoint(publicKeyRaw as Hex.Hex | Bytes.Bytes, publicKeyGroup)
675
662
  ) as BlsPoint.BlsPoint<any>
676
663
 
677
- const isShortSig = signatureGroup === 'G1'
678
-
679
- const group = isShortSig ? bls.G1 : bls.G2
680
- const payloadPoint = group.hashToCurve(
664
+ return engine.verify(
665
+ BlsPoint.toBytes(signature as BlsPoint.G1 | BlsPoint.G2),
681
666
  Bytes.from(payload),
682
- suite ? { DST: Bytes.fromString(suite) } : undefined,
683
- )
684
-
685
- const shortSigPairing = () =>
686
- bls.pairingBatch([
687
- {
688
- g1: payloadPoint as InstanceType<typeof bls.G1.Point>,
689
- g2: BlsPoint.toNoblePoint(publicKey as any, 'G2') as InstanceType<
690
- typeof bls.G2.Point
691
- >,
692
- },
693
- {
694
- g1: BlsPoint.toNoblePoint(signature as any, 'G1') as InstanceType<
695
- typeof bls.G1.Point
696
- >,
697
- g2: bls.G2.Point.BASE.negate(),
698
- },
699
- ])
700
-
701
- const longSigPairing = () =>
702
- bls.pairingBatch([
703
- {
704
- g1: (
705
- BlsPoint.toNoblePoint(publicKey as any, 'G1') as InstanceType<
706
- typeof bls.G1.Point
707
- >
708
- ).negate(),
709
- g2: payloadPoint as InstanceType<typeof bls.G2.Point>,
710
- },
711
- {
712
- g1: bls.G1.Point.BASE,
713
- g2: BlsPoint.toNoblePoint(signature as any, 'G2') as InstanceType<
714
- typeof bls.G2.Point
715
- >,
716
- },
717
- ])
718
-
719
- return bls.fields.Fp12.eql(
720
- isShortSig ? shortSigPairing() : longSigPairing(),
721
- bls.fields.Fp12.ONE,
667
+ BlsPoint.toBytes(publicKey as BlsPoint.G1 | BlsPoint.G2),
668
+ {
669
+ dst: suite ? Bytes.fromString(suite) : undefined,
670
+ signatureGroup,
671
+ },
722
672
  )
723
673
  }
724
674
 
@@ -2,6 +2,7 @@ import { ed25519 } from '@noble/curves/ed25519.js'
2
2
  import * as Bytes from './Bytes.js'
3
3
  import type * as Errors from './Errors.js'
4
4
  import * as Hex from './Hex.js'
5
+ import * as engine from './internal/ed25519.js'
5
6
 
6
7
  /** Re-export of noble/curves Ed25519 utilities. */
7
8
  export const noble = ed25519
@@ -77,7 +78,7 @@ export function getPublicKey<as extends 'Hex' | 'Bytes' = 'Hex'>(
77
78
  ): getPublicKey.ReturnType<as> {
78
79
  const { as = 'Hex', privateKey } = options
79
80
  const privateKeyBytes = Bytes.from(privateKey)
80
- const publicKeyBytes = ed25519.getPublicKey(privateKeyBytes)
81
+ const publicKeyBytes = engine.getPublicKey(privateKeyBytes)
81
82
  if (as === 'Hex') return Hex.fromBytes(publicKeyBytes) as never
82
83
  return publicKeyBytes as never
83
84
  }
@@ -122,7 +123,7 @@ export function randomPrivateKey<as extends 'Hex' | 'Bytes' = 'Hex'>(
122
123
  options: randomPrivateKey.Options<as> = {},
123
124
  ): randomPrivateKey.ReturnType<as> {
124
125
  const { as = 'Hex' } = options
125
- const bytes = ed25519.utils.randomSecretKey()
126
+ const bytes = engine.randomSecretKey()
126
127
  if (as === 'Hex') return Hex.fromBytes(bytes) as never
127
128
  return bytes as never
128
129
  }
@@ -166,7 +167,7 @@ export function sign<as extends 'Hex' | 'Bytes' = 'Hex'>(
166
167
  const { as = 'Hex', payload, privateKey } = options
167
168
  const payloadBytes = Bytes.from(payload)
168
169
  const privateKeyBytes = Bytes.from(privateKey)
169
- const signatureBytes = ed25519.sign(payloadBytes, privateKeyBytes)
170
+ const signatureBytes = engine.sign(payloadBytes, privateKeyBytes)
170
171
  if (as === 'Hex') return Hex.fromBytes(signatureBytes) as never
171
172
  return signatureBytes as never
172
173
  }
@@ -227,7 +228,7 @@ export function verify(options: verify.Options): boolean {
227
228
  const payloadBytes = Bytes.from(payload)
228
229
  const publicKeyBytes = Bytes.from(publicKey)
229
230
  const signatureBytes = Bytes.from(signature)
230
- return ed25519.verify(signatureBytes, payloadBytes, publicKeyBytes)
231
+ return engine.verify(signatureBytes, payloadBytes, publicKeyBytes)
231
232
  }
232
233
 
233
234
  export declare namespace verify {
@@ -268,7 +269,7 @@ export function toX25519PublicKey<as extends 'Hex' | 'Bytes' = 'Hex'>(
268
269
  ): toX25519PublicKey.ReturnType<as> {
269
270
  const { as = 'Hex', publicKey } = options
270
271
  const publicKeyBytes = Bytes.from(publicKey)
271
- const x25519PublicKeyBytes = ed25519.utils.toMontgomery(publicKeyBytes)
272
+ const x25519PublicKeyBytes = engine.toMontgomery(publicKeyBytes)
272
273
  if (as === 'Hex') return Hex.fromBytes(x25519PublicKeyBytes) as never
273
274
  return x25519PublicKeyBytes as never
274
275
  }
@@ -319,8 +320,7 @@ export function toX25519PrivateKey<as extends 'Hex' | 'Bytes' = 'Hex'>(
319
320
  ): toX25519PrivateKey.ReturnType<as> {
320
321
  const { as = 'Hex', privateKey } = options
321
322
  const privateKeyBytes = Bytes.from(privateKey)
322
- const x25519PrivateKeyBytes =
323
- ed25519.utils.toMontgomerySecret(privateKeyBytes)
323
+ const x25519PrivateKeyBytes = engine.toMontgomerySecret(privateKeyBytes)
324
324
  if (as === 'Hex') return Hex.fromBytes(x25519PrivateKeyBytes) as never
325
325
  return x25519PrivateKeyBytes as never
326
326
  }