commit 4bd9bb679577d66d2565caf15b8c910933d234cd
parent 120fd5eb7285e88dda9093e97c3f6ebaea1b77b7
Author: finwo <finwo@pm.me>
Date: Sat, 27 May 2023 23:12:20 +0200
Main ts module building
Diffstat:
| M | package-lock.json | | | 213 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | package.json | | | 8 | +++++--- |
| M | src/index.ts | | | 122 | ++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------- |
3 files changed, 299 insertions(+), 44 deletions(-)
diff --git a/package-lock.json b/package-lock.json
@@ -18,6 +18,7 @@
"@typescript-eslint/eslint-plugin": "^5.59.7",
"@typescript-eslint/parser": "^5.56.0",
"eslint": "^8.41.0",
+ "nodemon": "^2.0.22",
"tap": "^16.3.4",
"tape": "^5.0.1"
},
@@ -894,6 +895,12 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
"node_modules/acorn": {
"version": "8.8.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
@@ -2551,6 +2558,12 @@
"node": ">= 4"
}
},
+ "node_modules/ignore-by-default": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
+ "dev": true
+ },
"node_modules/import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -3377,6 +3390,67 @@
"integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==",
"dev": true
},
+ "node_modules/nodemon": {
+ "version": "2.0.22",
+ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
+ "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==",
+ "dev": true,
+ "dependencies": {
+ "chokidar": "^3.5.2",
+ "debug": "^3.2.7",
+ "ignore-by-default": "^1.0.1",
+ "minimatch": "^3.1.2",
+ "pstree.remy": "^1.1.8",
+ "semver": "^5.7.1",
+ "simple-update-notifier": "^1.0.7",
+ "supports-color": "^5.5.0",
+ "touch": "^3.1.0",
+ "undefsafe": "^2.0.5"
+ },
+ "bin": {
+ "nodemon": "bin/nodemon.js"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/nodemon"
+ }
+ },
+ "node_modules/nodemon/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/nodemon/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/nopt": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+ "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
+ "dev": true,
+ "dependencies": {
+ "abbrev": "1"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -3697,6 +3771,12 @@
"node": ">=8"
}
},
+ "node_modules/pstree.remy": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
+ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
+ "dev": true
+ },
"node_modules/punycode": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
@@ -3935,6 +4015,27 @@
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
+ "node_modules/simple-update-notifier": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
+ "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==",
+ "dev": true,
+ "dependencies": {
+ "semver": "~7.0.0"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/simple-update-notifier/node_modules/semver": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+ "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -6223,6 +6324,18 @@
"node": ">=8.0"
}
},
+ "node_modules/touch": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
+ "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
+ "dev": true,
+ "dependencies": {
+ "nopt": "~1.0.10"
+ },
+ "bin": {
+ "nodetouch": "bin/nodetouch.js"
+ }
+ },
"node_modules/trivial-deferred": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.1.2.tgz",
@@ -6326,6 +6439,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/undefsafe": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
+ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
+ "dev": true
+ },
"node_modules/unicode-length": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.1.0.tgz",
@@ -7274,6 +7393,12 @@
"eslint-visitor-keys": "^3.3.0"
}
},
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
"acorn": {
"version": "8.8.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
@@ -8448,6 +8573,12 @@
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"dev": true
},
+ "ignore-by-default": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
+ "dev": true
+ },
"import-fresh": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
@@ -9044,6 +9175,50 @@
"integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==",
"dev": true
},
+ "nodemon": {
+ "version": "2.0.22",
+ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
+ "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==",
+ "dev": true,
+ "requires": {
+ "chokidar": "^3.5.2",
+ "debug": "^3.2.7",
+ "ignore-by-default": "^1.0.1",
+ "minimatch": "^3.1.2",
+ "pstree.remy": "^1.1.8",
+ "semver": "^5.7.1",
+ "simple-update-notifier": "^1.0.7",
+ "supports-color": "^5.5.0",
+ "touch": "^3.1.0",
+ "undefsafe": "^2.0.5"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true
+ }
+ }
+ },
+ "nopt": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+ "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -9283,6 +9458,12 @@
"fromentries": "^1.2.0"
}
},
+ "pstree.remy": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
+ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
+ "dev": true
+ },
"punycode": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
@@ -9441,6 +9622,23 @@
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
+ "simple-update-notifier": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz",
+ "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==",
+ "dev": true,
+ "requires": {
+ "semver": "~7.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+ "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
+ "dev": true
+ }
+ }
+ },
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -10967,6 +11165,15 @@
"is-number": "^7.0.0"
}
},
+ "touch": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
+ "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
+ "dev": true,
+ "requires": {
+ "nopt": "~1.0.10"
+ }
+ },
"trivial-deferred": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.1.2.tgz",
@@ -11042,6 +11249,12 @@
"which-boxed-primitive": "^1.0.2"
}
},
+ "undefsafe": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
+ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
+ "dev": true
+ },
"unicode-length": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.1.0.tgz",
diff --git a/package.json b/package.json
@@ -27,7 +27,8 @@
"build:esm": "tsc -p ./config/tsconfig.esm.json && mv dist/esm/index.js dist/esm/index.mjs && mv dist/esm/index.js.map dist/esm/index.mjs.map",
"build:test": "tsc -p ./config/tsconfig.test.json",
"linter": "eslint src",
- "postpublishonly": "PACKAGE_VERSION=$(jq -r .version < package.json) && PACKAGE_NAME=$(jq -r .name < package.json) && npm deprecate \"${PACKAGE_NAME}@<${PACKAGE_VERSION}\" \"Rolling release, please update to ${PACKAGE_VERSION}\""
+ "postpublishonly": "PACKAGE_VERSION=$(jq -r .version < package.json) && PACKAGE_NAME=$(jq -r .name < package.json) && npm deprecate \"${PACKAGE_NAME}@<${PACKAGE_VERSION}\" \"Rolling release, please update to ${PACKAGE_VERSION}\"",
+ "watch": "nodemon --watch src --ext ts --exec npm -- run build"
},
"repository": {
"type": "git",
@@ -36,11 +37,12 @@
"author": "Yersa Nordman <finwo@pm.me>",
"license": "MIT",
"devDependencies": {
- "@typescript-eslint/eslint-plugin": "^5.59.7",
- "@typescript-eslint/parser": "^5.56.0",
"@types/node": "^20.2.5",
"@types/tap": "^15.0.8",
+ "@typescript-eslint/eslint-plugin": "^5.59.7",
+ "@typescript-eslint/parser": "^5.56.0",
"eslint": "^8.41.0",
+ "nodemon": "^2.0.22",
"tap": "^16.3.4",
"tape": "^5.0.1"
},
diff --git a/src/index.ts b/src/index.ts
@@ -1,15 +1,7 @@
import isBuffer = require('is-buffer');
import { binary } from './supercop.wasm';
-let Module: null | {
- memory : WebAssembly.Memory;
- instance: WebAssembly.Instance;
- exports : {[index:string]:any};
-} = null;
-
-async function instantiateModule() {
- if (Module) return;
-
+const Module = (async () => {
const memory = new WebAssembly.Memory({initial: 2});
const imports = {env: {memory}};
@@ -19,12 +11,17 @@ async function instantiateModule() {
const program = await WebAssembly.instantiate(binary, imports);
- Module = {
+ return {
memory : memory,
instance: program.instance,
exports : program.instance.exports,
+ } as {
+ memory : WebAssembly.Memory;
+ instance: WebAssembly.Instance;
+ exports : {[index:string]:any};
};
-}
+})();
+
function randomBytes(length: number) {
return Buffer.from(new Array(length).fill(0).map(()=>Math.floor(Math.random()*256)));
@@ -64,35 +61,57 @@ export function isSecretKey(data: unknown): data is SecretKey {
}
export class KeyPair {
- publicKey: PublicKey;
- secretKey: SecretKey;
+ publicKey?: PublicKey;
+ secretKey?: SecretKey;
constructor() {
// Intentionally empty
}
+ // Passes signing on to the exported stand-alone method
+ // Async, so the error = promise rejection
async sign(message: string) {
- // TODO: call main sign fn
+ if (!isSecretKey(this.secretKey)) throw new Error('No secret key on this keypair, only verification is possible');
+ if (!isPublicKey(this.publicKey)) throw new Error('Invalid public key');
+ return sign(message, this.publicKey, this.secretKey);
+ }
+
+ // Passes verification on to the exported stand-alone method
+ verify(signature: number[] | Signature, message: string) {
+ if (!isPublicKey(this.publicKey)) throw new Error('Invalid public key');
+ return verify(signature, message, this.publicKey);
+ }
+
+ keyExchange(theirPublicKey: number[] | PublicKey) {
+ if (!isSecretKey(this.secretKey)) throw new Error('Invalid secret key');
+ return keyExchange(theirPublicKey, this.secretKey);
}
- async verify(signature: Signature, message: string) {
- // TODO: call main verify fn
+ static create(seed: number[] | Seed) {
+ return createKeyPair(seed);
+ }
+
+ static from( data: { publicKey: number[] | PublicKey, secretKey?: number[] | SecretKey } ) {
+ return keyPairFrom(data);
}
}
-export function keyPairFrom( data: { publicKey: PublicKey, secretKey: SecretKey } ): false | KeyPair {
+export function keyPairFrom( data: { publicKey: number[] | PublicKey, secretKey?: number[] | SecretKey } ): false | KeyPair {
if ('object' !== typeof data) return false;
if (!data) return false;
+ // Sanitization and sanity checking
+ data = { ...data };
+ if (Array.isArray(data.publicKey)) data.publicKey = Buffer.from(data.publicKey);
+ if (Array.isArray(data.secretKey)) data.secretKey = Buffer.from(data.secretKey);
if (!isPublicKey(data.publicKey)) return false;
- if (!isSecretKey(data.secretKey)) return false;
+ // Not checking the secretKey, allowed to be missing
return Object.create(KeyPair, data);
}
-export async function createKeyPair( seed: Seed | Array<number> ): Promise<false | KeyPair> {
- await instantiateModule();
+export async function createKeyPair( seed: number[] | Seed ): Promise<false | KeyPair> {
// Pre-fetch module components
const fn = (await Module).exports;
@@ -125,24 +144,24 @@ export async function createKeyPair( seed: Seed | Array<number> ): Promise<false
});
}
-export async function sign(message: string | Buffer, publicKey: PublicKey, secretKey: SecretKey): Promise<Signature> {
- await instantiateModule();
+export async function sign(
+ message: string | Buffer,
+ publicKey: number[] | PublicKey,
+ secretKey: number[] | SecretKey
+): Promise<Signature> {
// Pre-fetch module components
const fn = (await Module).exports;
const mem = (await Module).memory;
- // Sanity checking
+ // Sanitization and sanity checking
+ if (Array.isArray(publicKey)) publicKey = Buffer.from(publicKey);
+ if (Array.isArray(secretKey)) secretKey = Buffer.from(secretKey);
if (!isPublicKey(publicKey)) throw new Error('Invalid public key');
if (!isSecretKey(secretKey)) throw new Error('Invalid secret key');
-
-
-
-
if ('string' === typeof message) message = Buffer.from(message);
- // checkArguments({message,publicKey,secretKey});
-
+ // Allocate memory on the wasm side to transfer variables
const messageLen = message.length;
const messageArrPtr = fn._malloc(messageLen);
const messageArr = new Uint8Array(mem.buffer, messageArrPtr, messageLen);
@@ -159,6 +178,7 @@ export async function sign(message: string | Buffer, publicKey: PublicKey, secre
await fn.sign(sigPtr, messageArrPtr, messageLen, publicKeyArrPtr, secretKeyArrPtr);
+ // Free used memory on wasm side
fn._free(messageArrPtr);
fn._free(publicKeyArrPtr);
fn._free(secretKeyArrPtr);
@@ -167,15 +187,23 @@ export async function sign(message: string | Buffer, publicKey: PublicKey, secre
return Buffer.from(sig);
}
-exports.verify = async function(signature, message, publicKey){
- await instantiateModule();
+export async function verify(
+ signature: number[] | Signature,
+ message: string | Buffer,
+ publicKey: number[] | PublicKey
+): Promise<boolean> {
+
const fn = (await Module).exports;
const mem = (await Module).memory;
- if ('string' === typeof message) message = Buffer.from(message);
+
+ // Sanitization and sanity checking
if (Array.isArray(signature)) signature = Buffer.from(signature);
if (Array.isArray(publicKey)) publicKey = Buffer.from(publicKey);
- checkArguments({signature,message,publicKey});
+ if (!isPublicKey(publicKey)) throw new Error('Invalid public key');
+ if (!isSignature(signature)) throw new Error('Invalid signature');
+ if ('string' === typeof message) message = Buffer.from(message);
+ // Allocate memory on the wasm side to transfer variables
const messageLen = message.length;
const messageArrPtr = fn._malloc(messageLen);
const messageArr = new Uint8Array(mem.buffer, messageArrPtr, messageLen);
@@ -188,23 +216,31 @@ exports.verify = async function(signature, message, publicKey){
signatureArr.set(signature);
publicKeyArr.set(publicKey);
- const res = fn.verify(signatureArrPtr, messageArrPtr, messageLen, publicKeyArrPtr) === 1;
+ const res = fn.verify(signatureArrPtr, messageArrPtr, messageLen, publicKeyArrPtr) === 1;
+ // Free used memory on wasm side
fn._free(messageArrPtr);
fn._free(signatureArrPtr);
fn._free(publicKeyArrPtr);
return res;
-};
+}
+
+export async function keyExchange(
+ theirPublicKey: number[] | PublicKey,
+ ourSecretKey: number[] | SecretKey
+): Promise<Buffer> {
-exports.keyExchange = async function(publicKey, secretKey) {
- await instantiateModule();
const fn = (await Module).exports;
const mem = (await Module).memory;
- if (Array.isArray(publicKey)) publicKey = Buffer.from(publicKey);
- if (Array.isArray(secretKey)) secretKey = Buffer.from(secretKey);
- checkArguments({publicKey,secretKey});
+ // Sanitization and sanity checking
+ if (Array.isArray(theirPublicKey)) theirPublicKey = Buffer.from(theirPublicKey);
+ if (Array.isArray(ourSecretKey)) ourSecretKey = Buffer.from(ourSecretKey);
+ if (!isPublicKey(theirPublicKey)) throw new Error('Invalid public key');
+ if (!isSecretKey(ourSecretKey)) throw new Error('Invalid secret key');
+
+ // Allocate memory on the wasm side to transfer variables
const sharedSecretArrPtr = fn._malloc(32);
const sharedSecretArr = new Uint8Array(mem.buffer, sharedSecretArrPtr, 32);
const publicKeyArrPtr = fn._malloc(32);
@@ -212,11 +248,15 @@ exports.keyExchange = async function(publicKey, secretKey) {
const secretKeyArrPtr = fn._malloc(32);
const secretKeyArr = new Uint8Array(mem.buffer, sharedSecretArrPtr, 64);
+ publicKeyArr.set(theirPublicKey);
+ secretKeyArr.set(ourSecretKey);
+
fn.key_exchange(sharedSecretArrPtr, publicKeyArrPtr, secretKeyArrPtr);
+ // Free used memory on wasm side
fn._free(sharedSecretArrPtr);
fn._free(publicKeyArrPtr);
fn._free(secretKeyArrPtr);
return Buffer.from(sharedSecretArr);
-};
+}