return n\r
}\r
\r
- /**\r
- * Type-checks arbitrary number of arguments to verify whether they are all\r
- * Uint8Array<ArrayBuffer> objects.\r
- *\r
- * @param {object} args - Key-value pairs of arguments to be checked\r
- * @throws {TypeError} If any argument is not a Uint8Array<ArrayBuffer>\r
- */\r
- static #checkArrayTypes (args: { [i: string]: unknown }): asserts args is { [i: string]: Uint8Array<ArrayBuffer> } {\r
- for (const arg of Object.keys(args)) {\r
- if (typeof args[arg] !== 'object') {\r
- throw new TypeError(`Invalid input, expected Uint8Array, actual ${typeof arg}`)\r
- }\r
- const obj = args[arg] as { [key: string]: unknown }\r
- if (!(obj instanceof Uint8Array)) {\r
- throw new TypeError(`Invalid input, expected Uint8Array, actual ${obj.constructor?.name ?? typeof arg}`)\r
- }\r
- }\r
- }\r
-\r
/**\r
* Derives a public key from a private key "seed".\r
*\r
static convert (seed: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>\r
static convert (seed: unknown): Uint8Array<ArrayBuffer> {\r
try {\r
- const args: { [i: string]: unknown } = { s: seed }\r
- this.#checkArrayTypes(args)\r
- const { s } = args\r
- if (s.length !== this.crypto_sign_SEEDBYTES) {\r
- throw new Error('Invalid seed size to convert to public key')\r
+ if (!(seed instanceof Uint8Array)) {\r
+ throw new TypeError('Seed must be Uint8Array')\r
+ }\r
+ if (seed.byteLength !== this.crypto_sign_SEEDBYTES) {\r
+ throw new Error(`Seed must be ${this.crypto_sign_SEEDBYTES} bytes`)\r
}\r
+ const s = new Uint8Array(seed)\r
+ seed = undefined\r
const pk = new Uint8Array(this.crypto_sign_PUBLICKEYBYTES)\r
const p: Float64Array[] = [new Float64Array(16), new Float64Array(16), new Float64Array(16), new Float64Array(16)]\r
\r
static detached (message: Uint8Array<ArrayBuffer>, privateKey: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>\r
static detached (message: unknown, privateKey: unknown): Uint8Array<ArrayBuffer> {\r
try {\r
- const args: { [i: string]: unknown } = { msg: message, prv: privateKey }\r
- this.#checkArrayTypes(args)\r
- const { msg, prv } = args\r
- const signed = this.sign(msg, prv)\r
- const sig = new Uint8Array(this.crypto_sign_BYTES)\r
- for (let i = 0; i < sig.length; i++) {\r
- sig[i] = signed[i]\r
+ if (!(message instanceof Uint8Array)) {\r
+ throw new TypeError('Message must be Uint8Array')\r
}\r
- return sig\r
+ if (!(privateKey instanceof Uint8Array)) {\r
+ throw new TypeError('Private key must be Uint8Array')\r
+ }\r
+ const m = new Uint8Array(message)\r
+ const mLen = m.length\r
+ const prv = new Uint8Array(privateKey)\r
+ message = undefined\r
+ privateKey = undefined\r
+ const sm = new Uint8Array(this.crypto_sign_BYTES + mLen)\r
+ const pub = this.convert(prv)\r
+ this.crypto_sign(sm, m, mLen, prv, pub)\r
+ return new Uint8Array(sm.buffer.slice(0, this.crypto_sign_BYTES))\r
} catch (err) {\r
throw new Error('Failed to sign and return signature', { cause: err })\r
}\r
static open (signedMessage: Uint8Array<ArrayBuffer>, publicKey: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>\r
static open (signedMessage: unknown, publicKey: unknown): Uint8Array<ArrayBuffer> {\r
try {\r
- const args: { [i: string]: unknown } = { signed: signedMessage, pub: publicKey }\r
- this.#checkArrayTypes(args)\r
- const { signed, pub } = args\r
- if (pub.byteLength !== this.crypto_sign_PUBLICKEYBYTES) {\r
- throw new Error(`Invalid public key size to open message, expected ${this.crypto_sign_PUBLICKEYBYTES}, actual ${pub.byteLength}`)\r
+ if (!(signedMessage instanceof Uint8Array)) {\r
+ throw new TypeError('Signed message must be Uint8Array')\r
}\r
- const tmp = new Uint8Array(signed.length)\r
- const mlen = this.crypto_sign_open(tmp, signed, signed.length, pub)\r
-\r
+ if (!(publicKey instanceof Uint8Array)) {\r
+ throw new TypeError('Public key must be Uint8Array')\r
+ }\r
+ if (publicKey.byteLength !== this.crypto_sign_PUBLICKEYBYTES) {\r
+ throw new Error(`Public key must be ${this.crypto_sign_PUBLICKEYBYTES} bytes`)\r
+ }\r
+ const sm = new Uint8Array(signedMessage)\r
+ const pub = new Uint8Array(publicKey)\r
+ signedMessage = undefined\r
+ publicKey = undefined\r
+ const tmp = new Uint8Array(sm.length)\r
+ const mlen = this.crypto_sign_open(tmp, sm, sm.length, pub)\r
if (mlen < 0) {\r
throw new Error('Signature verification failed')\r
}\r
-\r
const m = new Uint8Array(mlen)\r
m.set(tmp.subarray(0, mlen), 0)\r
return m\r
static sign (message: Uint8Array<ArrayBuffer>, privateKey: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>\r
static sign (message: unknown, privateKey: unknown): Uint8Array<ArrayBuffer> {\r
try {\r
- const args: { [i: string]: unknown } = { msg: message, prv: privateKey }\r
- this.#checkArrayTypes(args)\r
- const { msg, prv } = args\r
- if (prv.byteLength !== this.crypto_sign_PRIVATEKEYBYTES) {\r
- throw new Error(`Invalid key byte length to sign message, expected ${this.crypto_sign_PRIVATEKEYBYTES}, actual ${prv.byteLength}`)\r
+ if (!(message instanceof Uint8Array)) {\r
+ throw new TypeError('Message must be Uint8Array')\r
+ }\r
+ if (!(privateKey instanceof Uint8Array)) {\r
+ throw new TypeError('Private key must be Uint8Array')\r
}\r
+ if (privateKey.byteLength !== this.crypto_sign_SEEDBYTES) {\r
+ throw new Error(`Private key must be ${this.crypto_sign_PRIVATEKEYBYTES} bytes`)\r
+ }\r
+ const msg = new Uint8Array(message)\r
+ const prv = new Uint8Array(privateKey)\r
+ message = undefined\r
+ privateKey = undefined\r
const signed = new Uint8Array(this.crypto_sign_BYTES + msg.length)\r
const pub = this.convert(prv)\r
this.crypto_sign(signed, msg, msg.length, prv, pub)\r
/**\r
* Verifies a detached signature for a message.\r
*\r
- * @param {Uint8Array<ArrayBuffer>} message - Signed message\r
+ * @param {Uint8Array<ArrayBuffer>} signedMessage - Signed message\r
* @param {Uint8Array<ArrayBuffer>} signature - 64-byte signature\r
* @param {Uint8Array<ArrayBuffer>} publicKey - 32-byte key used for signing\r
* @returns {boolean} - True if `publicKey` was used to sign `msg` and generate `sig`, else false\r
*/\r
- static verify (message: Uint8Array<ArrayBuffer>, signature: Uint8Array<ArrayBuffer>, publicKey: Uint8Array<ArrayBuffer>): boolean\r
- static verify (message: unknown, signature: unknown, publicKey: unknown): boolean {\r
+ static verify (signedMessage: Uint8Array<ArrayBuffer>, signature: Uint8Array<ArrayBuffer>, publicKey: Uint8Array<ArrayBuffer>): boolean\r
+ static verify (signedMessage: unknown, signature: unknown, publicKey: unknown): boolean {\r
try {\r
- const args: { [i: string]: unknown } = { msg: message, sig: signature, pub: publicKey }\r
- this.#checkArrayTypes(args)\r
- const { msg, sig, pub } = args\r
- if (sig.length !== this.crypto_sign_BYTES) {\r
- throw new Error('Invalid signature size to verify signature')\r
+ if (!(signedMessage instanceof Uint8Array)) {\r
+ throw new TypeError('Message must be Uint8Array')\r
+ }\r
+ if (!(signature instanceof Uint8Array)) {\r
+ throw new TypeError('Signature must be Uint8Array')\r
+ }\r
+ if (!(publicKey instanceof Uint8Array)) {\r
+ throw new TypeError('Public key must be Uint8Array')\r
+ }\r
+ if (signature.byteLength !== this.crypto_sign_BYTES) {\r
+ throw new Error(`Signature must be ${this.crypto_sign_BYTES} bytes`)\r
}\r
- if (pub.length !== this.crypto_sign_PUBLICKEYBYTES) {\r
- throw new Error('Invalid public key size to verify signature')\r
+ if (publicKey.byteLength !== this.crypto_sign_PUBLICKEYBYTES) {\r
+ throw new Error(`Public key must be ${this.crypto_sign_PUBLICKEYBYTES} bytes`)\r
}\r
+ const msg = new Uint8Array(signedMessage)\r
+ const sig = new Uint8Array(signature)\r
+ const pub = new Uint8Array(publicKey)\r
+ signedMessage = undefined\r
+ signature = undefined\r
+ publicKey = undefined\r
const sm = new Uint8Array(this.crypto_sign_BYTES + msg.length)\r
const m = new Uint8Array(this.crypto_sign_BYTES + msg.length)\r
sm.set(sig, 0)\r