ox 1.1.0 → 1.1.2
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/CHANGELOG.md +27 -0
- package/dist/core/Engine.d.ts +43 -11
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +40 -10
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/internal/engine.d.ts +8 -8
- package/dist/core/internal/engine.d.ts.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/node/Ed25519.d.ts +33 -0
- package/dist/node/Ed25519.d.ts.map +1 -0
- package/dist/node/Ed25519.js +67 -0
- package/dist/node/Ed25519.js.map +1 -0
- package/dist/node/Engine.d.ts +29 -16
- package/dist/node/Engine.d.ts.map +1 -1
- package/dist/node/Engine.js +38 -14
- package/dist/node/Engine.js.map +1 -1
- package/dist/node/Hash.d.ts +14 -16
- package/dist/node/Hash.d.ts.map +1 -1
- package/dist/node/Hash.js +14 -16
- package/dist/node/Hash.js.map +1 -1
- package/dist/node/Keystore.d.ts +36 -0
- package/dist/node/Keystore.d.ts.map +1 -0
- package/dist/node/Keystore.js +72 -0
- package/dist/node/Keystore.js.map +1 -0
- package/dist/node/Mnemonic.d.ts +35 -0
- package/dist/node/Mnemonic.d.ts.map +1 -0
- package/dist/node/Mnemonic.js +46 -0
- package/dist/node/Mnemonic.js.map +1 -0
- package/dist/node/P256.d.ts +32 -0
- package/dist/node/P256.d.ts.map +1 -0
- package/dist/node/P256.js +34 -0
- package/dist/node/P256.js.map +1 -0
- package/dist/node/X25519.d.ts +31 -0
- package/dist/node/X25519.d.ts.map +1 -0
- package/dist/node/X25519.js +71 -0
- package/dist/node/X25519.js.map +1 -0
- package/dist/node/index.d.ts +95 -8
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +95 -8
- package/dist/node/index.js.map +1 -1
- package/dist/wasm/Ed25519.d.ts +35 -0
- package/dist/wasm/Ed25519.d.ts.map +1 -0
- package/dist/wasm/Ed25519.js +88 -0
- package/dist/wasm/Ed25519.js.map +1 -0
- package/dist/wasm/Engine.d.ts +35 -26
- package/dist/wasm/Engine.d.ts.map +1 -1
- package/dist/wasm/Engine.js +44 -25
- package/dist/wasm/Engine.js.map +1 -1
- package/dist/wasm/Hash.d.ts +13 -19
- package/dist/wasm/Hash.d.ts.map +1 -1
- package/dist/wasm/Hash.js +21 -27
- package/dist/wasm/Hash.js.map +1 -1
- package/dist/wasm/Keystore.d.ts +37 -0
- package/dist/wasm/Keystore.d.ts.map +1 -0
- package/dist/wasm/Keystore.js +34 -0
- package/dist/wasm/Keystore.js.map +1 -0
- package/dist/wasm/Mnemonic.d.ts +33 -0
- package/dist/wasm/Mnemonic.d.ts.map +1 -0
- package/dist/wasm/Mnemonic.js +30 -0
- package/dist/wasm/Mnemonic.js.map +1 -0
- package/dist/wasm/X25519.d.ts +33 -0
- package/dist/wasm/X25519.d.ts.map +1 -0
- package/dist/wasm/X25519.js +53 -0
- package/dist/wasm/X25519.js.map +1 -0
- package/dist/wasm/index.d.ts +81 -12
- package/dist/wasm/index.d.ts.map +1 -1
- package/dist/wasm/index.js +81 -12
- package/dist/wasm/index.js.map +1 -1
- package/dist/wasm/internal/blake3.d.ts +11 -0
- package/dist/wasm/internal/blake3.d.ts.map +1 -0
- package/dist/wasm/internal/blake3.js +31 -0
- package/dist/wasm/internal/blake3.js.map +1 -0
- package/dist/wasm/internal/blake3.wasm.d.ts +3 -0
- package/dist/wasm/internal/blake3.wasm.d.ts.map +1 -0
- package/dist/wasm/internal/blake3.wasm.js +10 -0
- package/dist/wasm/internal/blake3.wasm.js.map +1 -0
- package/dist/wasm/internal/crypto25519.d.ts +16 -0
- package/dist/wasm/internal/crypto25519.d.ts.map +1 -0
- package/dist/wasm/internal/crypto25519.js +5 -0
- package/dist/wasm/internal/crypto25519.js.map +1 -0
- package/dist/wasm/internal/crypto25519.wasm.d.ts +3 -0
- package/dist/wasm/internal/crypto25519.wasm.d.ts.map +1 -0
- package/dist/wasm/internal/crypto25519.wasm.js +10 -0
- package/dist/wasm/internal/crypto25519.wasm.js.map +1 -0
- package/dist/wasm/internal/ed25519.d.ts +4 -0
- package/dist/wasm/internal/ed25519.d.ts.map +1 -0
- package/dist/wasm/internal/ed25519.js +21 -0
- package/dist/wasm/internal/ed25519.js.map +1 -0
- package/dist/wasm/internal/hashes.d.ts +12 -0
- package/dist/wasm/internal/hashes.d.ts.map +1 -0
- package/dist/wasm/internal/hashes.js +8 -0
- package/dist/wasm/internal/hashes.js.map +1 -0
- package/dist/wasm/internal/hashes.wasm.d.ts +4 -2
- package/dist/wasm/internal/hashes.wasm.d.ts.map +1 -1
- package/dist/wasm/internal/hashes.wasm.js +4 -2
- package/dist/wasm/internal/hashes.wasm.js.map +1 -1
- package/dist/wasm/internal/mnemonic.d.ts +4 -0
- package/dist/wasm/internal/mnemonic.d.ts.map +1 -0
- package/dist/wasm/internal/mnemonic.js +45 -0
- package/dist/wasm/internal/mnemonic.js.map +1 -0
- package/dist/wasm/internal/pbkdf2.d.ts +12 -0
- package/dist/wasm/internal/pbkdf2.d.ts.map +1 -0
- package/dist/wasm/internal/pbkdf2.js +51 -0
- package/dist/wasm/internal/pbkdf2.js.map +1 -0
- package/dist/wasm/internal/x25519.d.ts +4 -0
- package/dist/wasm/internal/x25519.d.ts.map +1 -0
- package/dist/wasm/internal/x25519.js +21 -0
- package/dist/wasm/internal/x25519.js.map +1 -0
- package/package.json +46 -1
- package/src/core/Engine.ts +84 -11
- package/src/core/_test/Engine.test-d.ts +56 -0
- package/src/core/_test/Engine.test.ts +95 -0
- package/src/core/_test/Hash.vectors.test.ts +8 -0
- package/src/core/internal/engine.ts +8 -8
- package/src/index.ts +5 -2
- package/src/node/Ed25519.ts +87 -0
- package/src/node/Engine.ts +79 -23
- package/src/node/Hash.ts +22 -27
- package/src/node/Keystore.ts +103 -0
- package/src/node/Mnemonic.ts +68 -0
- package/src/node/P256.ts +48 -0
- package/src/node/X25519.ts +93 -0
- package/src/node/_test/Curves.fuzz.ts +76 -0
- package/src/node/_test/Ed25519.test-d.ts +35 -0
- package/src/node/_test/Ed25519.test.ts +220 -0
- package/src/node/_test/Engine.test-d.ts +28 -0
- package/src/node/_test/Engine.test.ts +62 -22
- package/src/node/_test/Hash.test-d.ts +15 -9
- package/src/node/_test/Hash.test.ts +10 -11
- package/src/node/_test/Keystore.fuzz.ts +58 -0
- package/src/node/_test/Keystore.test-d.ts +43 -0
- package/src/node/_test/Keystore.test.ts +198 -0
- package/src/node/_test/Mnemonic.fuzz.ts +31 -0
- package/src/node/_test/Mnemonic.test-d.ts +21 -0
- package/src/node/_test/Mnemonic.test.ts +98 -0
- package/src/node/_test/P256.test-d.ts +29 -0
- package/src/node/_test/P256.test.ts +102 -0
- package/src/node/_test/X25519.test-d.ts +28 -0
- package/src/node/_test/X25519.test.ts +239 -0
- package/src/node/index.ts +100 -8
- package/src/version.ts +1 -1
- package/src/wasm/Ed25519.ts +114 -0
- package/src/wasm/Engine.ts +76 -31
- package/src/wasm/Hash.bench.ts +2 -2
- package/src/wasm/Hash.ts +29 -50
- package/src/wasm/Keystore.ts +48 -0
- package/src/wasm/Mnemonic.ts +44 -0
- package/src/wasm/X25519.ts +70 -0
- package/src/wasm/_test/Crypto25519.conformance.ts +57 -0
- package/src/wasm/_test/Crypto25519.fuzz.ts +187 -0
- package/src/wasm/_test/Ed25519.test-d.ts +28 -0
- package/src/wasm/_test/Ed25519.test.ts +168 -0
- package/src/wasm/_test/Ed25519.vectors.test.ts +73 -0
- package/src/wasm/_test/Engine.test-d.ts +28 -0
- package/src/wasm/_test/Engine.test.ts +59 -25
- package/src/wasm/_test/Hash.browser.test.ts +11 -7
- package/src/wasm/_test/Hash.fuzz.ts +58 -23
- package/src/wasm/_test/Hash.test-d.ts +15 -10
- package/src/wasm/_test/Hash.test.ts +148 -48
- package/src/wasm/_test/Hash.vectors.test.ts +15 -8
- package/src/wasm/_test/Keystore.browser.test.ts +42 -0
- package/src/wasm/_test/Keystore.fuzz.ts +113 -0
- package/src/wasm/_test/Keystore.test-d.ts +33 -0
- package/src/wasm/_test/Keystore.test.ts +192 -0
- package/src/wasm/_test/Keystore.vectors.test.ts +21 -0
- package/src/wasm/_test/Mnemonic.test-d.ts +17 -0
- package/src/wasm/_test/Mnemonic.test.ts +110 -0
- package/src/wasm/_test/X25519.test-d.ts +21 -0
- package/src/wasm/_test/X25519.test.ts +194 -0
- package/src/wasm/_test/fixtures.ts +4 -0
- package/src/wasm/index.ts +85 -12
- package/src/wasm/internal/blake3.ts +45 -0
- package/src/wasm/internal/blake3.wasm.ts +11 -0
- package/src/wasm/internal/crypto25519.ts +43 -0
- package/src/wasm/internal/crypto25519.wasm.ts +11 -0
- package/src/wasm/internal/ed25519.ts +31 -0
- package/src/wasm/internal/hashes.ts +29 -0
- package/src/wasm/internal/hashes.wasm.ts +5 -2
- package/src/wasm/internal/mnemonic.ts +56 -0
- package/src/wasm/internal/pbkdf2.ts +86 -0
- package/src/wasm/internal/x25519.ts +29 -0
package/src/wasm/Engine.ts
CHANGED
|
@@ -1,55 +1,81 @@
|
|
|
1
1
|
import * as CoreEngine from '../core/Engine.js'
|
|
2
2
|
import type * as Errors from '../core/Errors.js'
|
|
3
|
+
import * as Ed25519 from './Ed25519.js'
|
|
3
4
|
import * as Hash from './Hash.js'
|
|
5
|
+
import * as Keystore from './Keystore.js'
|
|
6
|
+
import * as Mnemonic from './Mnemonic.js'
|
|
7
|
+
import * as X25519 from './X25519.js'
|
|
4
8
|
import type * as internal from './internal/instantiate.js'
|
|
5
9
|
|
|
10
|
+
export {
|
|
11
|
+
AsyncScopeError,
|
|
12
|
+
get,
|
|
13
|
+
InvalidSlotValueError,
|
|
14
|
+
reset,
|
|
15
|
+
set,
|
|
16
|
+
UnknownPrimitiveError,
|
|
17
|
+
UnknownSlotError,
|
|
18
|
+
with,
|
|
19
|
+
} from '../core/Engine.js'
|
|
20
|
+
export type {
|
|
21
|
+
Bls,
|
|
22
|
+
Ecdh,
|
|
23
|
+
Ecdsa,
|
|
24
|
+
Eddsa,
|
|
25
|
+
Engine,
|
|
26
|
+
Hash,
|
|
27
|
+
Keystore,
|
|
28
|
+
Mnemonic,
|
|
29
|
+
} from '../core/Engine.js'
|
|
30
|
+
|
|
6
31
|
/**
|
|
7
|
-
* Compiles every implementation this entrypoint provides
|
|
32
|
+
* Compiles and installs every WASM implementation this entrypoint provides.
|
|
8
33
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
34
|
+
* Slot compilation starts concurrently. Nothing is installed until every slot
|
|
35
|
+
* resolves successfully.
|
|
11
36
|
*
|
|
12
|
-
* Call
|
|
13
|
-
* at call time, so values computed beforehand used whatever was
|
|
37
|
+
* Call this once, during startup, before any crypto call. Ox resolves the
|
|
38
|
+
* engine at call time, so values computed beforehand used whatever was
|
|
39
|
+
* installed then.
|
|
14
40
|
*
|
|
15
41
|
* @example
|
|
16
42
|
* ```ts twoslash
|
|
17
43
|
* // @noErrors
|
|
18
|
-
* import { Hash } from 'ox'
|
|
19
|
-
* import { Engine } from 'ox/wasm'
|
|
44
|
+
* import { Engine, Hash } from 'ox/wasm'
|
|
20
45
|
*
|
|
21
|
-
* await Engine.
|
|
46
|
+
* await Engine.install()
|
|
22
47
|
*
|
|
23
|
-
* Hash.
|
|
48
|
+
* Hash.sha256('0xdeadbeef')
|
|
24
49
|
* ```
|
|
25
50
|
*
|
|
26
51
|
* @returns The engine that was installed.
|
|
27
52
|
*/
|
|
28
|
-
export async function
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
53
|
+
export async function install(): Promise<install.ReturnType> {
|
|
54
|
+
return CoreEngine.install({
|
|
55
|
+
Ed25519: Ed25519.engine(),
|
|
56
|
+
Hash: Hash.engine(),
|
|
57
|
+
Keystore: Keystore.engine(),
|
|
58
|
+
Mnemonic: Mnemonic.engine(),
|
|
59
|
+
X25519: X25519.engine(),
|
|
60
|
+
})
|
|
32
61
|
}
|
|
33
62
|
|
|
34
|
-
export declare namespace
|
|
35
|
-
type ReturnType =
|
|
63
|
+
export declare namespace install {
|
|
64
|
+
type ReturnType = engine.ReturnType
|
|
36
65
|
|
|
37
66
|
type ErrorType =
|
|
38
|
-
|
|
|
39
|
-
| CoreEngine.
|
|
67
|
+
| engine.ErrorType
|
|
68
|
+
| CoreEngine.install.ErrorType
|
|
40
69
|
| Errors.GlobalErrorType
|
|
41
70
|
}
|
|
42
71
|
|
|
43
72
|
/**
|
|
44
|
-
* Compiles every implementation this entrypoint provides, without
|
|
45
|
-
* it.
|
|
73
|
+
* Compiles every WASM implementation this entrypoint provides, without
|
|
74
|
+
* installing it.
|
|
46
75
|
*
|
|
47
|
-
* Reach for this where an engine has to exist as a value
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* engines does not need it, because
|
|
51
|
-
* [`Engine.set`](/api/Engine/set) merges -- `await load()` followed by
|
|
52
|
-
* `Engine.set({ Secp256k1 })` leaves both in place.
|
|
76
|
+
* Reach for this where an engine has to exist as a value, such as a benchmark
|
|
77
|
+
* or an [`Engine.with`](/api/Engine/with) scope. Use the individual module's
|
|
78
|
+
* `engine` function to select only some slots.
|
|
53
79
|
*
|
|
54
80
|
* @example
|
|
55
81
|
* ```ts twoslash
|
|
@@ -57,20 +83,39 @@ export declare namespace load {
|
|
|
57
83
|
* import { Engine, Hash } from 'ox'
|
|
58
84
|
* import { Engine as Wasm } from 'ox/wasm'
|
|
59
85
|
*
|
|
60
|
-
* const wasm = await Wasm.
|
|
86
|
+
* const wasm = await Wasm.engine()
|
|
61
87
|
*
|
|
62
|
-
* Engine.with(wasm, () => Hash.
|
|
88
|
+
* Engine.with(wasm, () => Hash.sha256('0xdeadbeef'))
|
|
63
89
|
* ```
|
|
64
90
|
*
|
|
65
91
|
* @returns An engine, ready to install.
|
|
66
92
|
*/
|
|
67
|
-
export async function
|
|
68
|
-
|
|
93
|
+
export async function engine(): Promise<engine.ReturnType> {
|
|
94
|
+
const [ed25519, hash, keystore, mnemonic, x25519] = await Promise.all([
|
|
95
|
+
Ed25519.engine(),
|
|
96
|
+
Hash.engine(),
|
|
97
|
+
Keystore.engine(),
|
|
98
|
+
Mnemonic.engine(),
|
|
99
|
+
X25519.engine(),
|
|
100
|
+
])
|
|
101
|
+
return {
|
|
102
|
+
Ed25519: ed25519,
|
|
103
|
+
Hash: hash,
|
|
104
|
+
Keystore: keystore,
|
|
105
|
+
Mnemonic: mnemonic,
|
|
106
|
+
X25519: x25519,
|
|
107
|
+
}
|
|
69
108
|
}
|
|
70
109
|
|
|
71
|
-
export declare namespace
|
|
110
|
+
export declare namespace engine {
|
|
72
111
|
/** Every slot this entrypoint supplies, each with its primitives present. */
|
|
73
|
-
type ReturnType =
|
|
112
|
+
type ReturnType = {
|
|
113
|
+
Ed25519: Ed25519.engine.ReturnType
|
|
114
|
+
Hash: Hash.engine.ReturnType
|
|
115
|
+
Keystore: Keystore.engine.ReturnType
|
|
116
|
+
Mnemonic: Mnemonic.engine.ReturnType
|
|
117
|
+
X25519: X25519.engine.ReturnType
|
|
118
|
+
}
|
|
74
119
|
|
|
75
120
|
type ErrorType = internal.MemoryError | Errors.GlobalErrorType
|
|
76
121
|
}
|
package/src/wasm/Hash.bench.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { ripemd160 as noble_ripemd160 } from '@noble/hashes/legacy.js'
|
|
|
3
3
|
import { sha256 as noble_sha256 } from '@noble/hashes/sha2.js'
|
|
4
4
|
import { keccak_256 as noble_keccak256 } from '@noble/hashes/sha3.js'
|
|
5
5
|
import { bench, describe } from 'vp/test'
|
|
6
|
-
import {
|
|
6
|
+
import { engine as wasmEngine } from './Hash.js'
|
|
7
7
|
|
|
8
8
|
// Sizes expose fixed boundary overhead and sustained throughput. Crossovers
|
|
9
9
|
// vary by primitive, runtime, and processor.
|
|
@@ -12,7 +12,7 @@ import { create as createWasm } from './Hash.js'
|
|
|
12
12
|
// run Rust, and this portable benchmark must remain browser-compatible.
|
|
13
13
|
const sizes = [32, 64, 256, 1024, 4096, 65_536, 1_048_576] as const
|
|
14
14
|
|
|
15
|
-
const wasm =
|
|
15
|
+
const wasm = await wasmEngine()
|
|
16
16
|
const key = Uint8Array.from({ length: 32 }, (_, index) => index % 97)
|
|
17
17
|
|
|
18
18
|
for (const size of sizes) {
|
package/src/wasm/Hash.ts
CHANGED
|
@@ -1,38 +1,22 @@
|
|
|
1
1
|
import type * as Engine from '../core/Engine.js'
|
|
2
2
|
import type * as Errors from '../core/Errors.js'
|
|
3
|
+
import * as blake3 from './internal/blake3.js'
|
|
3
4
|
import * as hash from './internal/hash.js'
|
|
4
|
-
import
|
|
5
|
+
import * as hashes from './internal/hashes.js'
|
|
5
6
|
import * as internal from './internal/instantiate.js'
|
|
6
7
|
|
|
8
|
+
export * from '../core/Hash.js'
|
|
7
9
|
export { MemoryError } from './internal/instantiate.js'
|
|
8
10
|
|
|
9
|
-
type Exports = hash.Exports & {
|
|
10
|
-
keccak256(input: number, length: number, out: number): void
|
|
11
|
-
ripemd160(input: number, length: number, out: number): void
|
|
12
|
-
sha256(input: number, length: number, out: number): void
|
|
13
|
-
}
|
|
14
|
-
|
|
15
11
|
/** Digest sizes, in bytes. */
|
|
16
12
|
const digestSize = { keccak256: 32, ripemd160: 20, sha256: 32 }
|
|
17
13
|
|
|
18
14
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* Handing every caller the same object means one of them customising a slot
|
|
22
|
-
* for composition silently changes what a later `create` -- or `Engine.load`
|
|
23
|
-
* -- installs.
|
|
24
|
-
*
|
|
25
|
-
* @internal
|
|
26
|
-
*/
|
|
27
|
-
const instantiate = /*#__PURE__*/ internal.memoize(() =>
|
|
28
|
-
internal.instantiate<Exports>(wasmBase64),
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Compiles the WASM implementation of the [`Hash`](/api/Hash) primitives, without
|
|
33
|
-
* installing it.
|
|
15
|
+
* Compiles the WASM implementation of the [`Hash`](/api/Hash) primitives,
|
|
16
|
+
* without installing it.
|
|
34
17
|
*
|
|
35
|
-
* Most callers want
|
|
18
|
+
* Most callers want
|
|
19
|
+
* [`Engine.install`](/wasm/crypto/Engine/install) instead, which compiles every
|
|
36
20
|
* implementation this entrypoint provides and installs them in one call. Reach
|
|
37
21
|
* for this to take the `Hash` slot on its own, or to hold the implementation
|
|
38
22
|
* without touching the installed engine.
|
|
@@ -46,19 +30,22 @@ const instantiate = /*#__PURE__*/ internal.memoize(() =>
|
|
|
46
30
|
* @example
|
|
47
31
|
* ```ts twoslash
|
|
48
32
|
* // @noErrors
|
|
49
|
-
* import { Engine
|
|
50
|
-
* import
|
|
33
|
+
* import { Engine } from 'ox'
|
|
34
|
+
* import { Hash } from 'ox/wasm'
|
|
51
35
|
*
|
|
52
|
-
* Engine.
|
|
36
|
+
* await Engine.install({ Hash: Hash.engine() })
|
|
53
37
|
*
|
|
54
38
|
* Hash.keccak256('0xdeadbeef')
|
|
55
39
|
* ```
|
|
56
40
|
*
|
|
57
|
-
* @returns
|
|
41
|
+
* @returns The WASM implementation of the `Hash` slot.
|
|
58
42
|
*/
|
|
59
|
-
export async function
|
|
43
|
+
export async function engine(): Promise<engine.ReturnType> {
|
|
60
44
|
{
|
|
61
|
-
const module = await
|
|
45
|
+
const [blake3Module, module] = await Promise.all([
|
|
46
|
+
blake3.load(),
|
|
47
|
+
hashes.load(),
|
|
48
|
+
])
|
|
62
49
|
|
|
63
50
|
// Copies `input` in, runs `hash`, and copies the digest back out.
|
|
64
51
|
function call(
|
|
@@ -77,32 +64,24 @@ export async function create(): Promise<create.ReturnType> {
|
|
|
77
64
|
}
|
|
78
65
|
|
|
79
66
|
return {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
},
|
|
67
|
+
blake3: (input) => blake3.hash(blake3Module, input),
|
|
68
|
+
hmacSha256: (key, message) => hash.hmacSha256(module, key, message),
|
|
69
|
+
keccak256: (input) => call('keccak256', input),
|
|
70
|
+
ripemd160: (input) => call('ripemd160', input),
|
|
71
|
+
sha256: (input) => call('sha256', input),
|
|
86
72
|
}
|
|
87
73
|
}
|
|
88
74
|
}
|
|
89
75
|
|
|
90
|
-
export declare namespace
|
|
91
|
-
/**
|
|
92
|
-
* The `Hash` slot, carrying every primitive this module implements.
|
|
93
|
-
*
|
|
94
|
-
* {@link ox#Engine.Engine} is optional all the way down so that an engine can
|
|
95
|
-
* fill in as little as it likes. This one always fills the same four, and
|
|
96
|
-
* saying so is what spares callers a non-null assertion per primitive.
|
|
97
|
-
*/
|
|
76
|
+
export declare namespace engine {
|
|
77
|
+
/** Every `Hash` primitive this module implements. */
|
|
98
78
|
type ReturnType = {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
79
|
+
[key in
|
|
80
|
+
| 'blake3'
|
|
81
|
+
| 'hmacSha256'
|
|
82
|
+
| 'keccak256'
|
|
83
|
+
| 'ripemd160'
|
|
84
|
+
| 'sha256']-?: NonNullable<Engine.Hash[key]>
|
|
106
85
|
}
|
|
107
86
|
|
|
108
87
|
type ErrorType = internal.MemoryError | Errors.GlobalErrorType
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type * as Engine from '../core/Engine.js'
|
|
2
|
+
import type * as Errors from '../core/Errors.js'
|
|
3
|
+
import * as hashes from './internal/hashes.js'
|
|
4
|
+
import * as internal from './internal/instantiate.js'
|
|
5
|
+
import * as pbkdf2 from './internal/pbkdf2.js'
|
|
6
|
+
|
|
7
|
+
export * from '../core/Keystore.js'
|
|
8
|
+
export { MemoryError } from './internal/instantiate.js'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Compiles the WASM implementation of the [`Keystore`](/api/Keystore) PBKDF2
|
|
12
|
+
* primitive, without installing it.
|
|
13
|
+
*
|
|
14
|
+
* Most callers want
|
|
15
|
+
* [`Engine.install`](/wasm/crypto/Engine/install) instead, which compiles every
|
|
16
|
+
* implementation this entrypoint provides and installs them in one call. This
|
|
17
|
+
* provider deliberately stays synchronous and leaves AES, asynchronous PBKDF2,
|
|
18
|
+
* and scrypt on Ox's default implementation.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts twoslash
|
|
22
|
+
* // @noErrors
|
|
23
|
+
* import { Engine } from 'ox'
|
|
24
|
+
* import { Keystore } from 'ox/wasm'
|
|
25
|
+
*
|
|
26
|
+
* await Engine.install({ Keystore: Keystore.engine() })
|
|
27
|
+
*
|
|
28
|
+
* Keystore.pbkdf2({ password: 'testpassword' })
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @returns The WASM implementation of synchronous PBKDF2-HMAC-SHA256.
|
|
32
|
+
*/
|
|
33
|
+
export async function engine(): Promise<engine.ReturnType> {
|
|
34
|
+
const module = await hashes.load()
|
|
35
|
+
return {
|
|
36
|
+
pbkdf2Sha256: (password, salt, options) =>
|
|
37
|
+
pbkdf2.pbkdf2Sha256(module, password, salt, options),
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export declare namespace engine {
|
|
42
|
+
/** The WASM `Keystore` primitives this module implements. */
|
|
43
|
+
type ReturnType = {
|
|
44
|
+
pbkdf2Sha256: NonNullable<Engine.Keystore['pbkdf2Sha256']>
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type ErrorType = internal.MemoryError | Errors.GlobalErrorType
|
|
48
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type * as Engine from '../core/Engine.js'
|
|
2
|
+
import type * as Errors from '../core/Errors.js'
|
|
3
|
+
import * as crypto25519 from './internal/crypto25519.js'
|
|
4
|
+
import * as internal from './internal/instantiate.js'
|
|
5
|
+
import * as mnemonic from './internal/mnemonic.js'
|
|
6
|
+
|
|
7
|
+
export * from '../core/Mnemonic.js'
|
|
8
|
+
export { MemoryError } from './internal/instantiate.js'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Compiles the WASM implementation of [`Mnemonic.toSeed`](/api/Mnemonic/toSeed),
|
|
12
|
+
* without installing it.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts twoslash
|
|
16
|
+
* // @noErrors
|
|
17
|
+
* import { Engine } from 'ox'
|
|
18
|
+
* import { Mnemonic } from 'ox/wasm'
|
|
19
|
+
*
|
|
20
|
+
* await Engine.install({ Mnemonic: Mnemonic.engine() })
|
|
21
|
+
*
|
|
22
|
+
* Mnemonic.toSeed(
|
|
23
|
+
* 'test test test test test test test test test test test junk'
|
|
24
|
+
* )
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @returns The WASM implementation of the `Mnemonic` slot.
|
|
28
|
+
*/
|
|
29
|
+
export async function engine(): Promise<engine.ReturnType> {
|
|
30
|
+
const module = await crypto25519.load()
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
toSeed: (value, passphrase) => mnemonic.toSeed(module, value, passphrase),
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export declare namespace engine {
|
|
38
|
+
/** Every `Mnemonic` primitive this module implements. */
|
|
39
|
+
type ReturnType = {
|
|
40
|
+
toSeed: NonNullable<Engine.Mnemonic['toSeed']>
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type ErrorType = internal.MemoryError | Errors.GlobalErrorType
|
|
44
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type * as Engine from '../core/Engine.js'
|
|
2
|
+
import type * as Errors from '../core/Errors.js'
|
|
3
|
+
import * as crypto25519 from './internal/crypto25519.js'
|
|
4
|
+
import * as internal from './internal/instantiate.js'
|
|
5
|
+
import * as x25519 from './internal/x25519.js'
|
|
6
|
+
|
|
7
|
+
export * from '../core/X25519.js'
|
|
8
|
+
export { MemoryError } from './internal/instantiate.js'
|
|
9
|
+
|
|
10
|
+
const keySize = 32
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Compiles WASM implementations of selected [`X25519`](/api/X25519)
|
|
14
|
+
* primitives, without installing them.
|
|
15
|
+
*
|
|
16
|
+
* Random key generation remains on Ox's default implementation.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts twoslash
|
|
20
|
+
* // @noErrors
|
|
21
|
+
* import { Engine } from 'ox'
|
|
22
|
+
* import { X25519 } from 'ox/wasm'
|
|
23
|
+
*
|
|
24
|
+
* await Engine.install({ X25519: X25519.engine() })
|
|
25
|
+
*
|
|
26
|
+
* X25519.getPublicKey({ privateKey: '0x...' })
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @returns The WASM implementation of part of the `X25519` slot.
|
|
30
|
+
*/
|
|
31
|
+
export async function engine(): Promise<engine.ReturnType> {
|
|
32
|
+
const module = await crypto25519.load()
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
getPublicKey(privateKey) {
|
|
36
|
+
assertLength(privateKey, 'private')
|
|
37
|
+
module.reserve(keySize * 2)
|
|
38
|
+
const privateKeyPtr = module.heapBase
|
|
39
|
+
const publicKeyPtr = privateKeyPtr + keySize
|
|
40
|
+
try {
|
|
41
|
+
module.view().set(privateKey, privateKeyPtr)
|
|
42
|
+
module.exports.x25519_get_public_key(privateKeyPtr, publicKeyPtr)
|
|
43
|
+
return module.view().slice(publicKeyPtr, publicKeyPtr + keySize)
|
|
44
|
+
} finally {
|
|
45
|
+
module.exports.zero(privateKeyPtr, keySize * 2)
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
getSharedSecret(privateKey, publicKey) {
|
|
49
|
+
assertLength(privateKey, 'private')
|
|
50
|
+
assertLength(publicKey, 'public')
|
|
51
|
+
return x25519.getSharedSecret(module, privateKey, publicKey)
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export declare namespace engine {
|
|
57
|
+
/** Every `X25519` primitive this module implements. */
|
|
58
|
+
type ReturnType = {
|
|
59
|
+
[key in 'getPublicKey' | 'getSharedSecret']-?: NonNullable<Engine.Ecdh[key]>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
type ErrorType = internal.MemoryError | Errors.GlobalErrorType
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function assertLength(key: Uint8Array, type: 'private' | 'public'): void {
|
|
66
|
+
if (key.length !== keySize)
|
|
67
|
+
throw new RangeError(
|
|
68
|
+
`X25519 ${type} key must be ${keySize} bytes, got ${key.length}`,
|
|
69
|
+
)
|
|
70
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ed25519, x25519 } from '@noble/curves/ed25519.js'
|
|
2
|
+
import { mnemonicToSeedSync } from '@scure/bip39'
|
|
3
|
+
import { describe, expect, test } from 'vp/test'
|
|
4
|
+
import { vectors } from '../../../test/vectors/bip39/index.js'
|
|
5
|
+
import * as Ed25519 from '../Ed25519.js'
|
|
6
|
+
import * as Mnemonic from '../Mnemonic.js'
|
|
7
|
+
import * as X25519 from '../X25519.js'
|
|
8
|
+
|
|
9
|
+
describe('crypto25519 WASM', () => {
|
|
10
|
+
test('behavior: Ed25519 works in this runtime', async () => {
|
|
11
|
+
const engine = await Ed25519.engine()
|
|
12
|
+
const privateKey = fromHex(
|
|
13
|
+
'9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60',
|
|
14
|
+
)
|
|
15
|
+
const payload = new TextEncoder().encode('browser conformance')
|
|
16
|
+
const publicKey = engine.getPublicKey(privateKey)
|
|
17
|
+
const signature = engine.sign(payload, privateKey)
|
|
18
|
+
|
|
19
|
+
expect(publicKey).toEqual(ed25519.getPublicKey(privateKey))
|
|
20
|
+
expect(signature).toEqual(ed25519.sign(payload, privateKey))
|
|
21
|
+
expect(engine.verify(signature, payload, publicKey)).toBe(true)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('behavior: X25519 works in this runtime', async () => {
|
|
25
|
+
const engine = await X25519.engine()
|
|
26
|
+
const privateKey = fromHex(
|
|
27
|
+
'77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a',
|
|
28
|
+
)
|
|
29
|
+
const peerPrivateKey = fromHex(
|
|
30
|
+
'5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb',
|
|
31
|
+
)
|
|
32
|
+
const publicKey = x25519.getPublicKey(peerPrivateKey)
|
|
33
|
+
|
|
34
|
+
expect(engine.getPublicKey(privateKey)).toEqual(
|
|
35
|
+
x25519.getPublicKey(privateKey),
|
|
36
|
+
)
|
|
37
|
+
expect(engine.getSharedSecret(privateKey, publicKey)).toEqual(
|
|
38
|
+
x25519.getSharedSecret(privateKey, publicKey),
|
|
39
|
+
)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
test('behavior: Unicode BIP-39 works in this runtime', async () => {
|
|
43
|
+
const engine = await Mnemonic.engine()
|
|
44
|
+
const vector = vectors.japanese
|
|
45
|
+
|
|
46
|
+
expect(engine.toSeed(vector.mnemonic, vector.passphrase)).toEqual(
|
|
47
|
+
mnemonicToSeedSync(vector.mnemonic, vector.passphrase),
|
|
48
|
+
)
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
function fromHex(value: string): Uint8Array {
|
|
53
|
+
const bytes = new Uint8Array(value.length / 2)
|
|
54
|
+
for (let index = 0; index < bytes.length; index++)
|
|
55
|
+
bytes[index] = Number.parseInt(value.slice(index * 2, index * 2 + 2), 16)
|
|
56
|
+
return bytes
|
|
57
|
+
}
|