"sourceMap": false,
"debug": false,
"initialMemory": 4,
+ "importMemory": true,
"runtime": "stub",
"exportRuntime": false,
"enable": [
for (let i = 0; i < 32; i++) {
for (let j: u8 = 0; j < 8; j++) {
testbytesA[i] = 1 << j
- if (equalbytes(testbytesA, testbytesB, 32)) { throw new Error('equalbytes failed unit test') }
+ if (equalbytes(testbytesA, testbytesB, 32)) {
+ throw new Error('equalbytes failed unit test')
+ }
testbytesA[i] = 0
}
}
//! SPDX-FileCopyrightText: 2026 Chris Duncan <chris@codecow.com>
//! SPDX-License-Identifier: GPL-3.0-or-later
-import { Mutex, Nano25519TypeError, Pointers, clearMemory, constants, exports, isBytes, normalize } from './wasm'
+import { Mutex, Nano25519TypeError, Pointers, clearMemory, constants, exports, isBytes, memory, normalize } from './wasm'
const { KEY_BYTELENGTH, } = constants
}
const privateKey = normalize('private key', KEY_BYTELENGTH, KEY_BYTELENGTH, prv)
const publicKey = new Uint8Array(KEY_BYTELENGTH)
- let buffer = new Uint8Array(exports.memory.buffer)
+ let buffer = new Uint8Array(memory.buffer)
Mutex.lock()
try {
for (let i = 0; i < KEY_BYTELENGTH; i++) {
buffer[Pointers.INPUT_PRV + i] = privateKey[i]
}
exports.derive()
- if (exports.memory.buffer !== buffer.buffer) {
+ if (memory.buffer !== buffer.buffer) {
throw new Nano25519TypeError('WASM memory buffer detached')
}
for (let i = 0; i < KEY_BYTELENGTH; i++) {
//! SPDX-FileCopyrightText: 2026 Chris Duncan <chris@codecow.com>
//! SPDX-License-Identifier: GPL-3.0-or-later
-import { Mutex, Nano25519TypeError, Pointers, clearMemory, constants, exports, isBytes, normalize } from './wasm'
+import { Mutex, Nano25519TypeError, Pointers, clearMemory, constants, exports, isBytes, memory, normalize } from './wasm'
const { KEY_BYTELENGTH, MAX_MESSAGE_BYTELENGTH, SIGNATURE_BYTELENGTH, } = constants
const privateKey = normalize('private key', KEY_BYTELENGTH, KEY_BYTELENGTH, prv)
const publicKey = normalize('public key', KEY_BYTELENGTH, KEY_BYTELENGTH, pub)
const signature = new Uint8Array(SIGNATURE_BYTELENGTH)
- let buffer = new Uint8Array(exports.memory.buffer)
+ let buffer = new Uint8Array(memory.buffer)
Mutex.lock()
try {
for (let i = 0; i < message.byteLength; i++) {
buffer[Pointers.INPUT_PUB + i] = publicKey[i]
}
exports.sign(message.byteLength)
- if (exports.memory.buffer !== buffer.buffer) {
+ if (memory.buffer !== buffer.buffer) {
throw new Nano25519TypeError('WASM memory buffer detached')
}
for (let i = 0; i < SIGNATURE_BYTELENGTH; i++) {
//! SPDX-FileCopyrightText: 2026 Chris Duncan <chris@codecow.com>
//! SPDX-License-Identifier: GPL-3.0-or-later
-import { Mutex, Nano25519TypeError, Pointers, clearMemory, constants, exports, normalize, } from './wasm'
+import { Mutex, Nano25519TypeError, Pointers, clearMemory, constants, exports, memory, normalize } from './wasm'
const { BLOCKHASH_BYTELENGTH, KEY_BYTELENGTH, MAX_MESSAGE_BYTELENGTH, MAX_VERIFY_BLOCKS, SIGNATURE_BYTELENGTH, } = constants
export function verify (sig: unknown, msg: unknown, pub: unknown): boolean {
- let buffer = new Uint8Array(exports.memory.buffer)
+ let buffer = new Uint8Array(memory.buffer)
Mutex.lock()
try {
const message = normalize('message', 0, MAX_MESSAGE_BYTELENGTH, msg)
buffer[Pointers.INPUT_SIG + i] = signature[i]
}
exports.verify(message.byteLength)
- if (exports.memory.buffer !== buffer.buffer) {
+ if (memory.buffer !== buffer.buffer) {
throw new Nano25519TypeError('WASM memory buffer detached')
}
const verified = buffer[Pointers.OUTPUT_VERIFY]
throw new RangeError(`Bulk Nano block verification must be no more than ${MAX_VERIFY_BLOCKS} blocks`, { cause: count })
}
const verified = new Uint8Array(count)
- let buffer = new Uint8Array(exports.memory.buffer)
+ let buffer = new Uint8Array(memory.buffer)
Mutex.lock()
try {
const publicKey = normalize('public key', KEY_BYTELENGTH, KEY_BYTELENGTH, pub)
p += BLOCKHASH_BYTELENGTH
}
exports.verify_blocks(count)
- if (exports.memory.buffer !== buffer.buffer) {
+ if (memory.buffer !== buffer.buffer) {
throw new Nano25519TypeError('WASM memory buffer detached')
}
for (let i = 0; i < count; i++) {
MAX_VERIFY_BLOCKS: WebAssembly.Global
MAX_VERIFY_BLOCKS_BYTELENGTH: WebAssembly.Global
MAX_MESSAGE_BYTELENGTH: WebAssembly.Global
- memory: WebAssembly.Memory
}
}
}
}
+/**
+ * WASM memory created here and imported, instead of building and exporting, so
+ * that top-level WASM abort calls work while `exports` is still instantiating.
+ * Host-owned memory means abort handler can always read the error message.
+ *
+ * NOTE: `initial` must match `initialMemory` in `asconfig.json`.
+ */
+export const memory = new WebAssembly.Memory({ initial: 4 })
+
const wasm: Uint8Array<ArrayBuffer> = Uint8Array.from(nano25519_wasm)
const module = new WebAssembly.Module(wasm)
export const { exports } = new WebAssembly.Instance(module, {
env: {
+ memory,
abort: (msg: any, file: any, row: any, col: any): never => {
const getString = (pointer: number): string | null => {
- const end = pointer + new Uint32Array(exports.memory.buffer)[pointer - 4 >>> 2] >>> 1
- const buf = new Uint16Array(exports.memory.buffer)
+ const end = pointer + new Uint32Array(memory.buffer)[pointer - 4 >>> 2] >>> 1
+ const buf = new Uint16Array(memory.buffer)
let start = pointer >>> 1
let string = ''
while (end - start > 1024) {
}
export function clearMemory (): void {
- const memory = new Uint8Array(exports.memory.buffer)
- memory.fill(0, INPUT_MSG, INPUT_MSG + MAX_MESSAGE_BYTELENGTH)
- memory.fill(0, INPUT_PRV, INPUT_PRV + KEY_BYTELENGTH)
- memory.fill(0, INPUT_PUB, INPUT_PUB + KEY_BYTELENGTH)
- memory.fill(0, INPUT_SIG, INPUT_SIG + SIGNATURE_BYTELENGTH)
- memory.fill(0, OUTPUT_DERIVE, OUTPUT_DERIVE + KEY_BYTELENGTH)
- memory.fill(0, OUTPUT_SIGN, OUTPUT_SIGN + SIGNATURE_BYTELENGTH)
- memory.fill(255, OUTPUT_VERIFY, OUTPUT_VERIFY + MAX_VERIFY_BLOCKS)
+ const bytes = new Uint8Array(memory.buffer)
+ bytes.fill(0, INPUT_MSG, INPUT_MSG + MAX_MESSAGE_BYTELENGTH)
+ bytes.fill(0, INPUT_PRV, INPUT_PRV + KEY_BYTELENGTH)
+ bytes.fill(0, INPUT_PUB, INPUT_PUB + KEY_BYTELENGTH)
+ bytes.fill(0, INPUT_SIG, INPUT_SIG + SIGNATURE_BYTELENGTH)
+ bytes.fill(0, OUTPUT_DERIVE, OUTPUT_DERIVE + KEY_BYTELENGTH)
+ bytes.fill(0, OUTPUT_SIGN, OUTPUT_SIGN + SIGNATURE_BYTELENGTH)
+ bytes.fill(255, OUTPUT_VERIFY, OUTPUT_VERIFY + MAX_VERIFY_BLOCKS)
locked = false
}