WASM function JS interface construction (#238)
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
# CHANGELOG
|
||||
|
||||
## master
|
||||
|
||||
Changes:
|
||||
|
||||
- Adjust and optimize WASM function JS interface construction
|
||||
|
||||
|
||||
## 4.4.1 Nov 22, 2021
|
||||
|
||||
Changes:
|
||||
|
||||
@@ -7,6 +7,11 @@ import type { AsmCreator, WasmCryptoInstance } from './types';
|
||||
|
||||
import { assert, stringToU8a, u8aToString } from '@polkadot/util';
|
||||
|
||||
type PopFirst<T extends unknown[]> =
|
||||
T extends [WasmCryptoInstance, ...infer N]
|
||||
? N
|
||||
: [];
|
||||
|
||||
let wasm: WasmCryptoInstance | null = null;
|
||||
let cachegetInt32: Int32Array | null = null;
|
||||
let cachegetUint8: Uint8Array | null = null;
|
||||
@@ -31,14 +36,12 @@ export async function initWasm (wasmBytes: Uint8Array | null, asmFn: AsmCreator
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME We really would love to clean this up and have a sign like (wasm, ...params) => T
|
||||
// Alas, TypeScript foo is not that great today, so we sadly have an extra closure here
|
||||
export function withWasm <T, F extends (...params: never[]) => T> (fn: (wasm: WasmCryptoInstance) => F): F {
|
||||
return ((...params: never[]): T => {
|
||||
export function withWasm <T, F extends (wasm: WasmCryptoInstance, ...params: never[]) => T> (fn: F): (...params: PopFirst<Parameters<F>>) => ReturnType<F> {
|
||||
return (...params: PopFirst<Parameters<F>>): ReturnType<F> => {
|
||||
assert(wasm, 'The WASM interface has not been initialized. Ensure that you wait for the initialization Promise with waitReady() from @polkadot/wasm-crypto (or cryptoWaitReady() from @polkadot/util-crypto) before attempting to use WASM-only interfaces.');
|
||||
|
||||
return fn(wasm)(...params);
|
||||
}) as unknown as F;
|
||||
return fn(wasm, ...params) as ReturnType<F>;
|
||||
};
|
||||
}
|
||||
|
||||
export function getWasm (): WasmCryptoInstance {
|
||||
|
||||
@@ -9,299 +9,169 @@ import * as imports from './imports';
|
||||
|
||||
export { packageInfo } from './packageInfo';
|
||||
|
||||
const PTR_VEC = 8;
|
||||
|
||||
const wasmPromise = initWasm(wasmBytes, asmJsInit, imports).catch(() => null);
|
||||
|
||||
export const bip39Generate = withWasm((wasm) =>
|
||||
(words: 12 | 15 | 18 | 21 | 24): string => {
|
||||
wasm.ext_bip39_generate(PTR_VEC, words);
|
||||
export const bip39Generate = withWasm((wasm, words: 12 | 15 | 18 | 21 | 24): string => {
|
||||
wasm.ext_bip39_generate(8, words);
|
||||
|
||||
return resultString();
|
||||
}
|
||||
);
|
||||
return resultString();
|
||||
});
|
||||
|
||||
export const bip39ToEntropy = withWasm((wasm) =>
|
||||
(phrase: string): Uint8Array => {
|
||||
const [ptr0, len0] = allocString(phrase);
|
||||
export const bip39ToEntropy = withWasm((wasm, phrase: string): Uint8Array => {
|
||||
wasm.ext_bip39_to_entropy(8, ...allocString(phrase));
|
||||
|
||||
wasm.ext_bip39_to_entropy(PTR_VEC, ptr0, len0);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
export const bip39ToMiniSecret = withWasm((wasm, phrase: string, password: string): Uint8Array => {
|
||||
wasm.ext_bip39_to_mini_secret(8, ...allocString(phrase), ...allocString(password));
|
||||
|
||||
export const bip39ToMiniSecret = withWasm((wasm) =>
|
||||
(phrase: string, password: string): Uint8Array => {
|
||||
const [ptr0, len0] = allocString(phrase);
|
||||
const [ptr1, len1] = allocString(password);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
wasm.ext_bip39_to_mini_secret(PTR_VEC, ptr0, len0, ptr1, len1);
|
||||
export const bip39ToSeed = withWasm((wasm, phrase: string, password: string): Uint8Array => {
|
||||
wasm.ext_bip39_to_seed(8, ...allocString(phrase), ...allocString(password));
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
export const bip39ToSeed = withWasm((wasm) =>
|
||||
(phrase: string, password: string): Uint8Array => {
|
||||
const [ptr0, len0] = allocString(phrase);
|
||||
const [ptr1, len1] = allocString(password);
|
||||
export const bip39Validate = withWasm((wasm, phrase: string): boolean => {
|
||||
const ret = wasm.ext_bip39_validate(...allocString(phrase));
|
||||
|
||||
wasm.ext_bip39_to_seed(PTR_VEC, ptr0, len0, ptr1, len1);
|
||||
return ret !== 0;
|
||||
});
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
export const ed25519KeypairFromSeed = withWasm((wasm, seed: Uint8Array): Uint8Array => {
|
||||
wasm.ext_ed_from_seed(8, ...allocU8a(seed));
|
||||
|
||||
export const bip39Validate = withWasm((wasm) =>
|
||||
(phrase: string): boolean => {
|
||||
const [ptr0, len0] = allocString(phrase);
|
||||
const ret = wasm.ext_bip39_validate(ptr0, len0);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
return ret !== 0;
|
||||
}
|
||||
);
|
||||
export const ed25519Sign = withWasm((wasm, pubkey: Uint8Array, seckey: Uint8Array, message: Uint8Array): Uint8Array => {
|
||||
wasm.ext_ed_sign(8, ...allocU8a(pubkey), ...allocU8a(seckey), ...allocU8a(message));
|
||||
|
||||
export const ed25519KeypairFromSeed = withWasm((wasm) =>
|
||||
(seed: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(seed);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
wasm.ext_ed_from_seed(PTR_VEC, ptr0, len0);
|
||||
export const ed25519Verify = withWasm((wasm, signature: Uint8Array, message: Uint8Array, pubkey: Uint8Array): boolean => {
|
||||
const ret = wasm.ext_ed_verify(...allocU8a(signature), ...allocU8a(message), ...allocU8a(pubkey));
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
return ret !== 0;
|
||||
});
|
||||
|
||||
export const ed25519Sign = withWasm((wasm) =>
|
||||
(pubkey: Uint8Array, seckey: Uint8Array, message: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(pubkey);
|
||||
const [ptr1, len1] = allocU8a(seckey);
|
||||
const [ptr2, len2] = allocU8a(message);
|
||||
export const sr25519DeriveKeypairHard = withWasm((wasm, pair: Uint8Array, cc: Uint8Array): Uint8Array => {
|
||||
wasm.ext_sr_derive_keypair_hard(8, ...allocU8a(pair), ...allocU8a(cc));
|
||||
|
||||
wasm.ext_ed_sign(PTR_VEC, ptr0, len0, ptr1, len1, ptr2, len2);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
export const sr25519DeriveKeypairSoft = withWasm((wasm, pair: Uint8Array, cc: Uint8Array): Uint8Array => {
|
||||
wasm.ext_sr_derive_keypair_soft(8, ...allocU8a(pair), ...allocU8a(cc));
|
||||
|
||||
export const ed25519Verify = withWasm((wasm) =>
|
||||
(signature: Uint8Array, message: Uint8Array, pubkey: Uint8Array): boolean => {
|
||||
const [ptr0, len0] = allocU8a(signature);
|
||||
const [ptr1, len1] = allocU8a(message);
|
||||
const [ptr2, len2] = allocU8a(pubkey);
|
||||
const ret = wasm.ext_ed_verify(ptr0, len0, ptr1, len1, ptr2, len2);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
return ret !== 0;
|
||||
}
|
||||
);
|
||||
export const sr25519DerivePublicSoft = withWasm((wasm, pubkey: Uint8Array, cc: Uint8Array): Uint8Array => {
|
||||
wasm.ext_sr_derive_public_soft(8, ...allocU8a(pubkey), ...allocU8a(cc));
|
||||
|
||||
export const sr25519DeriveKeypairHard = withWasm((wasm) =>
|
||||
(pair: Uint8Array, cc: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(pair);
|
||||
const [ptr1, len1] = allocU8a(cc);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
wasm.ext_sr_derive_keypair_hard(PTR_VEC, ptr0, len0, ptr1, len1);
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
export const sr25519KeypairFromSeed = withWasm((wasm, seed: Uint8Array): Uint8Array => {
|
||||
wasm.ext_sr_from_seed(8, ...allocU8a(seed));
|
||||
|
||||
export const sr25519DeriveKeypairSoft = withWasm((wasm) =>
|
||||
(pair: Uint8Array, cc: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(pair);
|
||||
const [ptr1, len1] = allocU8a(cc);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
wasm.ext_sr_derive_keypair_soft(PTR_VEC, ptr0, len0, ptr1, len1);
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
export const sr25519Sign = withWasm((wasm, pubkey: Uint8Array, secret: Uint8Array, message: Uint8Array): Uint8Array => {
|
||||
wasm.ext_sr_sign(8, ...allocU8a(pubkey), ...allocU8a(secret), ...allocU8a(message));
|
||||
|
||||
export const sr25519DerivePublicSoft = withWasm((wasm) =>
|
||||
(pubkey: Uint8Array, cc: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(pubkey);
|
||||
const [ptr1, len1] = allocU8a(cc);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
wasm.ext_sr_derive_public_soft(PTR_VEC, ptr0, len0, ptr1, len1);
|
||||
export const sr25519Verify = withWasm((wasm, signature: Uint8Array, message: Uint8Array, pubkey: Uint8Array): boolean => {
|
||||
const ret = wasm.ext_sr_verify(...allocU8a(signature), ...allocU8a(message), ...allocU8a(pubkey));
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
return ret !== 0;
|
||||
});
|
||||
|
||||
export const sr25519KeypairFromSeed = withWasm((wasm) =>
|
||||
(seed: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(seed);
|
||||
export const sr25519Agree = withWasm((wasm, pubkey: Uint8Array, secret: Uint8Array): Uint8Array => {
|
||||
wasm.ext_sr_agree(8, ...allocU8a(pubkey), ...allocU8a(secret));
|
||||
|
||||
wasm.ext_sr_from_seed(PTR_VEC, ptr0, len0);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
export const vrfSign = withWasm((wasm, secret: Uint8Array, context: Uint8Array, message: Uint8Array, extra: Uint8Array): Uint8Array => {
|
||||
wasm.ext_vrf_sign(8, ...allocU8a(secret), ...allocU8a(context), ...allocU8a(message), ...allocU8a(extra));
|
||||
|
||||
export const sr25519Sign = withWasm((wasm) =>
|
||||
(pubkey: Uint8Array, secret: Uint8Array, message: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(pubkey);
|
||||
const [ptr1, len1] = allocU8a(secret);
|
||||
const [ptr2, len2] = allocU8a(message);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
wasm.ext_sr_sign(PTR_VEC, ptr0, len0, ptr1, len1, ptr2, len2);
|
||||
export const vrfVerify = withWasm((wasm, pubkey: Uint8Array, context: Uint8Array, message: Uint8Array, extra: Uint8Array, outAndProof: Uint8Array): boolean => {
|
||||
const ret = wasm.ext_vrf_verify(...allocU8a(pubkey), ...allocU8a(context), ...allocU8a(message), ...allocU8a(extra), ...allocU8a(outAndProof));
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
return ret !== 0;
|
||||
});
|
||||
|
||||
export const sr25519Verify = withWasm((wasm) =>
|
||||
(signature: Uint8Array, message: Uint8Array, pubkey: Uint8Array): boolean => {
|
||||
const [ptr0, len0] = allocU8a(signature);
|
||||
const [ptr1, len1] = allocU8a(message);
|
||||
const [ptr2, len2] = allocU8a(pubkey);
|
||||
const ret = wasm.ext_sr_verify(ptr0, len0, ptr1, len1, ptr2, len2);
|
||||
export const blake2b = withWasm((wasm, data: Uint8Array, key: Uint8Array, size: number): Uint8Array => {
|
||||
wasm.ext_blake2b(8, ...allocU8a(data), ...allocU8a(key), size);
|
||||
|
||||
return ret !== 0;
|
||||
}
|
||||
);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
export const sr25519Agree = withWasm((wasm) =>
|
||||
(pubkey: Uint8Array, secret: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(pubkey);
|
||||
const [ptr1, len1] = allocU8a(secret);
|
||||
export const hmacSha256 = withWasm((wasm, key: Uint8Array, data: Uint8Array): Uint8Array => {
|
||||
wasm.ext_hmac_sha256(8, ...allocU8a(key), ...allocU8a(data));
|
||||
|
||||
wasm.ext_sr_agree(PTR_VEC, ptr0, len0, ptr1, len1);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
export const hmacSha512 = withWasm((wasm, key: Uint8Array, data: Uint8Array): Uint8Array => {
|
||||
wasm.ext_hmac_sha512(8, ...allocU8a(key), ...allocU8a(data));
|
||||
|
||||
export const vrfSign = withWasm((wasm) =>
|
||||
(secret: Uint8Array, context: Uint8Array, message: Uint8Array, extra: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(secret);
|
||||
const [ptr1, len1] = allocU8a(context);
|
||||
const [ptr2, len2] = allocU8a(message);
|
||||
const [ptr3, len3] = allocU8a(extra);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
wasm.ext_vrf_sign(PTR_VEC, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
|
||||
export const keccak256 = withWasm((wasm, data: Uint8Array): Uint8Array => {
|
||||
wasm.ext_keccak256(8, ...allocU8a(data));
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
export const vrfVerify = withWasm((wasm) =>
|
||||
(pubkey: Uint8Array, context: Uint8Array, message: Uint8Array, extra: Uint8Array, outAndProof: Uint8Array): boolean => {
|
||||
const [ptr0, len0] = allocU8a(pubkey);
|
||||
const [ptr1, len1] = allocU8a(context);
|
||||
const [ptr2, len2] = allocU8a(message);
|
||||
const [ptr3, len3] = allocU8a(extra);
|
||||
const [ptr4, len4] = allocU8a(outAndProof);
|
||||
const ret = wasm.ext_vrf_verify(ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4);
|
||||
export const keccak512 = withWasm((wasm, data: Uint8Array): Uint8Array => {
|
||||
wasm.ext_keccak512(8, ...allocU8a(data));
|
||||
|
||||
return ret !== 0;
|
||||
}
|
||||
);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
export const blake2b = withWasm((wasm) =>
|
||||
(data: Uint8Array, key: Uint8Array, size: number): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(data);
|
||||
const [ptr1, len1] = allocU8a(key);
|
||||
export const pbkdf2 = withWasm((wasm, data: Uint8Array, salt: Uint8Array, rounds: number): Uint8Array => {
|
||||
wasm.ext_pbkdf2(8, ...allocU8a(data), ...allocU8a(salt), rounds);
|
||||
|
||||
wasm.ext_blake2b(PTR_VEC, ptr0, len0, ptr1, len1, size);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
export const scrypt = withWasm((wasm, password: Uint8Array, salt: Uint8Array, log2n: number, r: number, p: number): Uint8Array => {
|
||||
wasm.ext_scrypt(8, ...allocU8a(password), ...allocU8a(salt), log2n, r, p);
|
||||
|
||||
export const hmacSha256 = withWasm((wasm) =>
|
||||
(key: Uint8Array, data: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(key);
|
||||
const [ptr1, len1] = allocU8a(data);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
wasm.ext_hmac_sha256(PTR_VEC, ptr0, len0, ptr1, len1);
|
||||
export const sha256 = withWasm((wasm, data: Uint8Array): Uint8Array => {
|
||||
wasm.ext_sha256(8, ...allocU8a(data));
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
export const hmacSha512 = withWasm((wasm) =>
|
||||
(key: Uint8Array, data: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(key);
|
||||
const [ptr1, len1] = allocU8a(data);
|
||||
export const sha512 = withWasm((wasm, data: Uint8Array): Uint8Array => {
|
||||
wasm.ext_sha512(8, ...allocU8a(data));
|
||||
|
||||
wasm.ext_hmac_sha512(PTR_VEC, ptr0, len0, ptr1, len1);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
export const twox = withWasm((wasm, data: Uint8Array, rounds: number) => {
|
||||
wasm.ext_twox(8, ...allocU8a(data), rounds);
|
||||
|
||||
export const keccak256 = withWasm((wasm) =>
|
||||
(data: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(data);
|
||||
|
||||
wasm.ext_keccak256(PTR_VEC, ptr0, len0);
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
|
||||
export const keccak512 = withWasm((wasm) =>
|
||||
(data: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(data);
|
||||
|
||||
wasm.ext_keccak512(PTR_VEC, ptr0, len0);
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
|
||||
export const pbkdf2 = withWasm((wasm) =>
|
||||
(data: Uint8Array, salt: Uint8Array, rounds: number): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(data);
|
||||
const [ptr1, len1] = allocU8a(salt);
|
||||
|
||||
wasm.ext_pbkdf2(PTR_VEC, ptr0, len0, ptr1, len1, rounds);
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
|
||||
export const scrypt = withWasm((wasm) =>
|
||||
(password: Uint8Array, salt: Uint8Array, log2n: number, r: number, p: number): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(password);
|
||||
const [ptr1, len1] = allocU8a(salt);
|
||||
|
||||
wasm.ext_scrypt(PTR_VEC, ptr0, len0, ptr1, len1, log2n, r, p);
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
|
||||
export const sha256 = withWasm((wasm) =>
|
||||
(data: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(data);
|
||||
|
||||
wasm.ext_sha256(PTR_VEC, ptr0, len0);
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
|
||||
export const sha512 = withWasm((wasm) =>
|
||||
(data: Uint8Array): Uint8Array => {
|
||||
const [ptr0, len0] = allocU8a(data);
|
||||
|
||||
wasm.ext_sha512(PTR_VEC, ptr0, len0);
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
|
||||
export const twox = withWasm((wasm) =>
|
||||
(data: Uint8Array, rounds: number) => {
|
||||
const [ptr0, len0] = allocU8a(data);
|
||||
|
||||
wasm.ext_twox(PTR_VEC, ptr0, len0, rounds);
|
||||
|
||||
return resultU8a();
|
||||
}
|
||||
);
|
||||
return resultU8a();
|
||||
});
|
||||
|
||||
export function isReady (): boolean {
|
||||
return !!getWasm();
|
||||
|
||||
Reference in New Issue
Block a user