diff --git a/README.md b/README.md index 6b67716..616f00f 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,18 @@ The [libsecp256k1 C library](https://github.com/bitcoin-core/secp256k1) compiled to WASM and wrapped with an ultralight TypeScript API. -Supports four basic operations: - - Computing the corresponding public key for a given private key - - Signing +Supports the following operations: + - Computing the corresponding public key for a given secret key + - Signing (with recovery ID) - Verifying + - Recovering public key - ECDH + - Tweaking secret/public key via addition/multiplication This module offers *substantially* greater security than pure JavaScript implementations of Secp256k1 due to the fact that JS runtimes simply make it impossible for JS developers to effectively mitigate side-channel attacks. Anyone who says otherwise doesn't know what they're talking about. In addition to zero-ing out private keys after use, the wrapper also randomizes the lib context every time a public key is computed or a message is signed. -Signature recovery is not currently enabled, but is easy to add. If you meed it, please open an issue. - ### [Demo webapp](https://starshell.net/wasm-secp256k1/) and its [source](https://github.com/SolarRepublic/wasm-secp256k1/blob/main/src/demo/webapp.ts) diff --git a/docs/assets/index.js b/docs/assets/index.js index 0ce1e20..f19a100 100644 --- a/docs/assets/index.js +++ b/docs/assets/index.js @@ -277,7 +277,7 @@ const WasmSecp256k1 = async (z_src) => { g_wasm.ecdsa_recoverable_signature_serialize_compact(ip_ctx, ip_sig_scratch, ip_v, ip_sig_rcvr_lib); return [ ATU8_HEAP.slice(ip_sig_scratch, ip_sig_scratch + ByteLens.ECDSA_SIG_COMPACT), - ATU8_HEAP.slice(ip_v, ip_v + 4)[3] + ATU8_HEAP[ip_v] // terminal byte of 32-bit uint ]; }, @@ -321,6 +321,7 @@ const WasmSecp256k1 = async (z_src) => { const elem = (si_id) => document.getElementById(si_id); const dm_sk = elem("sk"); const dm_pk = elem("pk"); +const dm_pkr = elem("pkr"); const dm_v = elem("v"); const dm_msg = elem("msg"); const dm_hash = elem("hash"); @@ -335,6 +336,7 @@ const dm_verified = elem("verified"); let atu8_hash; let atu8_sig; let xc_recovery; + let atu8_pkr; function sk_err(s_msg) { dm_pk.value = s_msg; dm_hash.value = dm_sig_r.value = dm_sig_s.value = dm_verified.value = ""; @@ -374,6 +376,15 @@ const dm_verified = elem("verified"); } catch (e_verify) { return dm_verified.value = e_verify.message; } + try { + atu8_pkr = k_secp.recover(atu8_sig, atu8_hash, xc_recovery); + } catch (e_recover) { + return dm_verified.value = e_recover.message; + } + if (bytes_to_hex(atu8_pk) !== bytes_to_hex(atu8_pkr)) { + return dm_verified.value = `Recovered public keys do not match!`; + } + dm_pkr.value = bytes_to_hex(atu8_pkr); dm_verified.value = "Yes"; } atu8_sk = k_secp.gen_sk(); diff --git a/docs/assets/index.js.map b/docs/assets/index.js.map index b2b4b24..91bbdcc 100644 --- a/docs/assets/index.js.map +++ b/docs/assets/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../../node_modules/.pnpm/@blake.regalia+belt@0.40.1/node_modules/@blake.regalia/belt/dist/mjs/data.js","../../src/api/emsimp.ts","../../src/api/secp256k1-types.ts","../../src/gen/wasm.ts","../../src/api/secp256k1.ts","../../src/demo/webapp.ts"],"sourcesContent":["import { XG_8, is_array, is_dict_es, is_string, entries, from_entries, die, try_sync } from './belt.js';\nexport const SI_HASH_ALGORITHM_SHA256 = 'SHA-256';\nexport const SI_HASH_ALGORITHM_SHA384 = 'SHA-384';\nexport const SI_HASH_ALGORITHM_SHA512 = 'SHA-512';\n// /**\n// * Alias of `Math.max`\n// */\n// export const max = Math.max;\n// /**\n// * Alias of `Math.min`\n// */\n// export const min = Math.min;\n// /**\n// * Alias of `Math.abs`\n// */\n// export const abs = Math.abs;\n/**\n * Returns the lesser of the two `bigint` values\n */\nexport const bigint_lesser = (xg_a, xg_b) => xg_a < xg_b ? xg_a : xg_b;\n/**\n * Returns the greater of the two `bigint` values\n */\nexport const bigint_greater = (xg_a, xg_b) => xg_a > xg_b ? xg_a : xg_b;\n/**\n * Returns the absolute value of the given `bigint` value, or the absolute value of the delta between\n * the two given values if the 2nd argument is provided\n */\nexport const bigint_abs = (xg_a, xg_b = 0n, xg_delta = xg_a - xg_b) => xg_delta < 0n ? -xg_delta : xg_delta;\n/**\n * Computes the maximum value among a list of `bigint` values\n * @param a_values - list of values\n * @returns the max value\n */\nexport const bigint_max = (a_values) => a_values.reduce(bigint_greater, 0n);\n/**\n * Computes the minimunm value among a list of `bigint` values\n * @param a_values - list of values\n * @returns the min value\n */\nexport const bigint_min = (a_values) => a_values.reduce(bigint_lesser, 0n);\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst S_UUID_V4 = 'xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx';\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst R_UUID_V4 = /[xy]/g;\n// @ts-expect-error in case crypto global is not defined\nexport const uuid_v4 = globalThis.crypto?.randomUUID ? () => crypto.randomUUID() : () => {\n let xt_now = Date.now();\n if ('undefined' !== typeof performance)\n xt_now += performance.now();\n return S_UUID_V4.replace(R_UUID_V4, (s) => {\n const x_r = (xt_now + (Math.random() * 16)) % 16 | 0;\n xt_now = Math.floor(xt_now / 16);\n return ('x' === s ? x_r : (x_r & 0x3) | 0x8).toString(16);\n });\n};\n/**\n * Creates a new function that wraps the given function in a `try_sync` and returns the result without throwing\n * @param f_attempt - the function to attempt\n * @returns\n */\nexport const safely_sync = (f_attempt) => (...a_args) => try_sync(_ => f_attempt(...a_args))[0];\n/**\n * Typed alias to `JSON.stringify`\n */\nexport const stringify_json = JSON.stringify;\n/**\n * Strongly typed alias to `JSON.parse`\n */\nexport const parse_json = JSON.parse;\n/**\n * Attempts to parse the given JSON string, returning `undefined` on parse error instead of throwing\n * @param sx_json\n * @returns\n */\nexport const parse_json_safe = (sx_json) => try_sync(_ => parse_json(sx_json))[0];\n/**\n * @deprecated Use {@link parse_json_safe} instead.\n */\nexport const safe_json = parse_json_safe;\n/**\n * Converts a JSON object (in memory) into its canonical form. Must be valid JSON with no cycles\n * and must not contain any non-JSON values. Objects are sorted by keys, arrays are not sorted\n * since order matters.\n * @param w_json JSON-compatible value to canonicalize\n * @returns canonicalized JSON value\n */\nexport const canonicalize_json = (w_json) => {\n // JSON object\n if (is_dict_es(w_json)) {\n // sort all keys\n const h_sorted = from_entries(entries(w_json).sort((a_a, a_b) => a_a[0] < a_b[0] ? -1 : 1));\n // traverse on children\n for (const si_key in h_sorted) {\n h_sorted[si_key] = canonicalize_json(h_sorted[si_key]);\n }\n w_json = h_sorted;\n }\n // JSON array\n else if (is_array(w_json)) {\n w_json = w_json.map(w_item => canonicalize_json(w_item));\n }\n // boolean, number, string, or null\n return w_json;\n};\n/**\n * Helps reduce codesize\n * @param a_args\n * @returns\n */\nexport const bytes = (...a_args) => new Uint8Array(...a_args);\n/**\n * Helps reduce codesize\n * @param a_args\n * @returns\n */\nexport const dataview = (...a_args) => new DataView(...a_args);\n/**\n * Performs SHA-256 hash on the given data.\n * @param atu8_data data to hash\n * @returns the hash digest\n */\nexport const sha256 = async (atu8_data) => bytes(await crypto.subtle.digest(SI_HASH_ALGORITHM_SHA256, atu8_data));\n/**\n * Performs SHA-256(SHA-256(data))\n * @param atu8_data data to hash\n * @returns the hash digest\n */\nexport const sha256d = async (atu8_data) => {\n const atu8_1 = await sha256(atu8_data);\n const atu8_2 = await sha256(atu8_1);\n zero_out(atu8_1);\n return atu8_2;\n};\n/**\n * Performs SHA-384 hash on the given data.\n * @param atu8_data data to hash\n * @returns the hash digest\n */\nexport const sha384 = async (atu8_data) => bytes(await crypto.subtle.digest(SI_HASH_ALGORITHM_SHA384, atu8_data));\n/**\n * Performs SHA-512 hash on the given data.\n * @param atu8_data data to hash\n * @returns the hash digest\n */\nexport const sha512 = async (atu8_data) => bytes(await crypto.subtle.digest(SI_HASH_ALGORITHM_SHA512, atu8_data));\n/**\n * Imports a {@link CryptoKey} from raw bytes\n * @param atu8_sk - the key's raw bytes\n * @param z_algo - the algorithm argument passed to `SubtleCrypto#importKey()`\n * @param da_usages - key usages argument\n * @returns the imported {@link CryptoKey}\n */\nexport const import_key = (atu8_sk, z_algo, da_usages, b_extractable = false) => crypto.subtle.importKey('raw', atu8_sk, z_algo, b_extractable, da_usages);\n/**\n * Performs HMAC signing of the given message, **not the digest**.\n * @param atu8_sk private key\n * @param atu8_message message to sign, **not the digest**.\n * @returns HMAC signature\n */\nexport const hmac = async (atu8_sk, atu8_message, si_algo = SI_HASH_ALGORITHM_SHA256) => {\n // import signing private key\n const dk_sign = await import_key(atu8_sk, {\n name: 'HMAC',\n hash: { name: si_algo },\n }, ['sign']);\n // construct hmac signature\n return bytes(await crypto.subtle.sign('HMAC', dk_sign, atu8_message));\n};\n/**\n * Performs HKDF on the given IKM\n * @param atu8_ikm - the input key material bytes\n * @param ni_bits - number of bits to target\n * @param atu8_salt - salt bytes\n * @param atu8_info - optional info bytes\n * @param si_algo - hashing algorithm to use\n */\nexport const hkdf = async (atu8_ikm, ni_bits, atu8_salt, atu8_info = bytes(), si_algo = SI_HASH_ALGORITHM_SHA256) => {\n // import deriving key\n const dk_derive = await import_key(atu8_ikm, 'HKDF', ['deriveBits']);\n // derive the bits\n return bytes(await crypto.subtle.deriveBits({\n name: 'HKDF',\n hash: si_algo,\n salt: atu8_salt,\n info: atu8_info,\n }, dk_derive, ni_bits));\n};\n/**\n * Wipe the contents of a buffer so that sensitive data does not outlive garbage collection.\n */\nexport const zero_out = (atu8_data) => {\n // overwrite the contents\n atu8_data.fill(0);\n // make sure the engine does not optimize away the above memory wipe instruction\n // @ts-expect-error signature IS compatible with both types\n if (0 !== atu8_data.reduce((c_sum, x_value) => c_sum + x_value, 0))\n die('Failed to zero out sensitive memory region');\n};\nexport const encode_length_prefix_u16 = (atu8_data) => {\n // prep buffer to serialize encoded extension\n const atu8_encoded = concat([\n bytes(2), // 2 bytes for length prefix\n atu8_data,\n ]);\n // use big-endian to encode length prefix\n new DataView(atu8_encoded.buffer).setUint16(atu8_encoded.byteOffset, atu8_data.byteLength, false);\n // return encoded buffer\n return atu8_encoded;\n};\nexport const decode_length_prefix_u16 = (atu8_encoded) => {\n // use big-endian to decode length prefix\n const ib_terminus = new DataView(atu8_encoded.buffer).getUint16(atu8_encoded.byteOffset, false) + 2;\n // return decoded payload buffer and everything after it\n return [atu8_encoded.subarray(2, ib_terminus), atu8_encoded.subarray(ib_terminus)];\n};\n/**\n * UTF-8 encodes the given text to an Uint8Array.\n * @param s_text text to encode\n * @returns UTF-8 encoded Uint8Array\n */\nexport const text_to_bytes = (s_text) => new TextEncoder().encode(s_text);\n/**\n * UTF-8 decodes the given Uint8Array to text.\n * @param atu8_text UTF-8 encoded data to decode\n * @returns text\n */\nexport const bytes_to_text = (atu8_text) => new TextDecoder().decode(atu8_text);\n/**\n * Converts the given base64-encoded string to a buffer, then UTF-8 decodes it.\n * @param sx_buffer input base64-encoded string\n * @returns text\n */\nexport const base64_to_text = (sx_buffer) => bytes_to_text(base64_to_bytes(sx_buffer));\n/**\n * UTF-8 encodes the given text, then converts it to a base64-encoded string.\n * @param s_text text to encode\n * @returns output base64-encoded string\n */\nexport const text_to_base64 = (s_text) => bytes_to_base64(text_to_bytes(s_text));\n/**\n * Attempts to JSON stringify the given primitive/object and subsequently UTF-8 encode it.\n * @param w_json JSON-compatible value to encode\n * @returns UTF-8 encoded Uint8Array\n */\nexport const json_to_bytes = (w_json) => text_to_bytes(stringify_json(w_json));\n/**\n * UTF-8 decodes the given Uint8Array and subsequently attempts to JSON parse it.\n * @param atu8_json UTF-8 encoded JSON string data\n * @returns parsed JSON value\n */\nexport const bytes_to_json = (atu8_json) => parse_json(bytes_to_text(atu8_json));\n/**\n * Encodes the given 32-bit unsigned integer in big-endian format to a new buffer.\n * @param xg_uint\n * @returns\n */\nexport const uint32_to_bytes_be = (xg_uint) => {\n // prep array buffer\n const ab_buffer = new Uint32Array(1).buffer;\n // write to buffer\n new DataView(ab_buffer).setUint32(0, Number(xg_uint), false);\n // wrap as uint8array\n return bytes(ab_buffer);\n};\n/**\n * Decodes a 32-bit unsigned integer in big-endian format from a buffer (optionally at the given position).\n * @param n_uint\n * @returns\n */\nexport const bytes_to_uint32_be = (atu8_buffer, ib_offset = 0) => new DataView(atu8_buffer.buffer).getUint32(atu8_buffer.byteOffset + ib_offset, false);\n/**\n * Encodes the given unsigned bigint in big-endian format to a new 32-byte buffer, or whatever size is given.\n * @param xg_value - the value to encode\n * @param nb_size - size of the buffer to create\n * @returns the encoded buffer\n */\nexport const biguint_to_bytes_be = (xg_value, nb_size = 32) => {\n // prep buffer of the appropriate size\n let atu8_out = bytes(nb_size);\n let ib_write = nb_size;\n while (xg_value > 0n) {\n atu8_out[--ib_write] = Number(xg_value & 0xffn);\n xg_value >>= XG_8;\n }\n return atu8_out;\n};\n/**\n * @deprecated Use {@link biguint_to_bytes_be} instead.\n */\nexport const bigint_to_bytes_be = biguint_to_bytes_be;\n/**\n * Decodes an unsigned bigint in big-endian format from a buffer\n * @param atu8_bytes\n * @returns\n */\nexport const bytes_to_biguint_be = (atu8_bytes) => atu8_bytes.reduce((xg_out, xb_value) => (xg_out << XG_8) | BigInt(xb_value), 0n);\n/**\n * @deprecated Use {@link bytes_to_biguint_be} instead.\n */\nexport const bytes_to_bigint_be = bytes_to_biguint_be;\n/**\n * Concatenate a sequence of Uint8Arrays.\n * @param a_buffers the data to concatenate in order\n * @returns the concatenated output Uint8Array\n */\nexport const concat = (a_buffers) => {\n const nb_out = a_buffers.reduce((c_bytes, atu8_each) => c_bytes + atu8_each.byteLength, 0);\n const atu8_out = bytes(nb_out);\n let ib_write = 0;\n for (const atu8_each of a_buffers) {\n atu8_out.set(atu8_each, ib_write);\n ib_write += atu8_each.byteLength;\n }\n return atu8_out;\n};\n/**\n * Concatenate two Uint8Arrays together.\n * @param atu8_buffer_a left side\n * @param atu8_buffer_b right side\n * @returns the concatenated output Uint8Array\n */\nexport const concat2 = (atu8_a, atu8_b) => {\n const atu8_out = bytes(atu8_a.length + atu8_b.length);\n atu8_out.set(atu8_a);\n atu8_out.set(atu8_b, atu8_a.length);\n return atu8_out;\n};\n// // cache function reference\n// const sfcc = String.fromCharCode;\n/**\n * Converts the given buffer to a hex string format in lowercase.\n * @param atu8_buffer input buffer\n * @returns output hex string\n */\nexport const bytes_to_hex = (atu8_buffer) => atu8_buffer.reduce((s_out, xb_byte) => s_out + xb_byte.toString(16).padStart(2, '0'), '');\n/**\n * Converts the given hex string into a buffer.\n * @param sx_hex input hex string\n * @returns output buffer\n */\nexport const hex_to_bytes = (sx_hex) => bytes(sx_hex.length / 2)\n .map((xb_ignore, i_char) => parseInt(sx_hex.slice(i_char * 2, (i_char * 2) + 2), 16));\n/**\n * Converts the given buffer to a base64-encoded string using minimal code but at the expense of performance.\n * @param atu8_buffer input buffer\n * @returns output base64-encoded string\n */\nexport const bytes_to_base64_slim = (atu8_buffer) => btoa(Array.from(atu8_buffer).map(xb => String.fromCharCode(xb)).join(''));\n/**\n * Converts the given base64-encoded string to a buffer using minimal code but at the expense of performance.\n * @param sx_buffer input base64-encoded string\n * @returns output buffer\n */\nexport const base64_to_bytes_slim = (sx_buffer) => bytes(atob(sx_buffer.replace(/=+$/, '')).split('').map(s => s.charCodeAt(0)));\nconst SX_CHARS_BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// adapted from \n/* eslint-disable no-multi-spaces */\n/**\n * Converts the given buffer to a base64-encoded string.\n * @param atu8_buffer input buffer\n * @returns output base64-encoded string\n */\nexport const bytes_to_base64 = (atu8_buffer) => {\n let s_out = '';\n const nb_buffer = atu8_buffer.byteLength;\n const nb_remainder = nb_buffer % 3;\n const nb_main = nb_buffer - nb_remainder;\n let xb_a = 0;\n let xb_b = 0;\n let xb_c = 0;\n let xb_d = 0;\n let xn_chunk = 0;\n // Main loop deals with bytes in chunks of 3\n for (let ib_offset = 0; ib_offset < nb_main; ib_offset += 3) {\n // Combine the three bytes into a single integer\n xn_chunk = (atu8_buffer[ib_offset] << 16) | (atu8_buffer[ib_offset + 1] << 8) | atu8_buffer[ib_offset + 2];\n // Use bitmasks to extract 6-bit segments from the triplet\n xb_a = (xn_chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18\n xb_b = (xn_chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12\n xb_c = (xn_chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6\n xb_d = xn_chunk & 63; // 63 = 2^6 - 1\n // Convert the raw binary segments to the appropriate ASCII encoding\n s_out += SX_CHARS_BASE64[xb_a] + SX_CHARS_BASE64[xb_b] + SX_CHARS_BASE64[xb_c] + SX_CHARS_BASE64[xb_d];\n }\n // Deal with the remaining bytes and padding\n if (1 === nb_remainder) {\n xn_chunk = atu8_buffer[nb_main];\n xb_a = (xn_chunk & 252) >> 2; // 252 = (2^6 - 1) << 2\n // Set the 4 least significant bits to zero\n xb_b = (xn_chunk & 3) << 4; // 3 = 2^2 - 1\n s_out += SX_CHARS_BASE64[xb_a] + SX_CHARS_BASE64[xb_b] + '==';\n }\n else if (2 === nb_remainder) {\n xn_chunk = (atu8_buffer[nb_main] << 8) | atu8_buffer[nb_main + 1];\n xb_a = (xn_chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10\n xb_b = (xn_chunk & 1008) >> 4; // 1008 = (2^6 - 1) << 4\n // Set the 2 least significant bits to zero\n xb_c = (xn_chunk & 15) << 2; // 15 = 2^4 - 1\n s_out += SX_CHARS_BASE64[xb_a] + SX_CHARS_BASE64[xb_b] + SX_CHARS_BASE64[xb_c] + '=';\n }\n return s_out;\n};\n/* eslint-enable */\n/**\n * Converts the given base64-encoded string to a buffer.\n * @param sb64_data input base64-encoded string\n * @returns output buffer\n */\nexport const base64_to_bytes = (sb64_data) => {\n // remove padding from string\n sb64_data = sb64_data.replace(/=+$/, '');\n // a buffer to store decoded sextets\n let xb_work = 0;\n // number of bits in the buffer\n let nb_buffer = 0;\n // prep output values\n const a_out = [];\n // each character\n for (const s_char of sb64_data) {\n // decode character value\n const xb_char = SX_CHARS_BASE64.indexOf(s_char);\n // invalid base64-encoding\n if (-1 === xb_char)\n die('Invalid base64 string');\n // add 6 bits from index to buffer\n xb_work = (xb_work << 6) | xb_char;\n // increase size of buffer which checking if a whole byte exists in the buffer\n if ((nb_buffer += 6) >= 8) {\n // move byte out of buffer\n a_out.push(xb_work >>> (nb_buffer -= 8));\n // trim the buffer\n xb_work &= (1 << nb_buffer) - 1;\n }\n }\n return bytes(a_out);\n};\n/**\n * Converts the given raw string (no encoding) to bytes.\n * @param sx_buffer input string\n * @returns output buffer\n */\nexport const string8_to_bytes = (sx_buffer) => {\n const nl_chars = sx_buffer.length;\n const atu8_buffer = bytes(nl_chars);\n for (let i_read = 0; i_read < nl_chars; i_read++) {\n atu8_buffer[i_read] = sx_buffer.charCodeAt(i_read);\n }\n return atu8_buffer;\n};\n/**\n * Converts the given bytes to a raw string (no encoding).\n * @param at8u_bytes input bytes\n * @returns output string\n */\nexport const bytes_to_string8 = (atu8_bytes) => {\n let sx_buffer = '';\n for (const xb_value of atu8_bytes) {\n sx_buffer += String.fromCharCode(xb_value);\n }\n return sx_buffer;\n};\n// inspired by \n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst SX_CHARS_BASE93 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&'()*+,-./:;<=>?@[]^_`{|}~ \";\n/**\n * Converts the given buffer to a base93-encoded string.\n * @param atu8_buffer input buffer\n * @returns output base93-encoded string\n */\nexport const bytes_to_base93 = (atu8_buffer) => {\n let s_out = '';\n const nb_buffer = atu8_buffer.byteLength;\n let xb_encode = 0;\n let ni_shift = 0;\n for (let ib_each = 0; ib_each < nb_buffer; ib_each++) {\n const xb_each = atu8_buffer[ib_each];\n xb_encode |= xb_each << ni_shift;\n ni_shift += 8;\n if (ni_shift > 13) {\n let xb_local = xb_encode & 0x1fff;\n if (xb_local > 456) {\n xb_encode >>= 13;\n ni_shift -= 13;\n }\n else {\n xb_local = xb_encode & 0x3fff;\n xb_encode >>= 14;\n ni_shift -= 14;\n }\n s_out += SX_CHARS_BASE93[xb_local % 93] + SX_CHARS_BASE93[(xb_local / 93) | 0];\n }\n }\n if (ni_shift > 0) {\n s_out += SX_CHARS_BASE93[xb_encode % 93];\n if (ni_shift > 7 || xb_encode > 92) {\n s_out += SX_CHARS_BASE93[(xb_encode / 93) | 0];\n }\n }\n return s_out;\n};\n/**\n * Converts the given base93-encoded string to a buffer.\n * @param sb93_data input base93-encoded string\n * @returns output buffer\n */\nexport const base93_to_bytes = (sb93_data) => {\n const a_out = [];\n let xb_decode = 0;\n let ni_shift = 0;\n let xb_work = -1;\n for (const s_char of sb93_data) {\n const xb_char = SX_CHARS_BASE93.indexOf(s_char);\n if (-1 === xb_char)\n die('Invalid base93 string');\n if (-1 === xb_work) {\n xb_work = xb_char;\n continue;\n }\n xb_work += xb_char * 93;\n xb_decode |= xb_work << ni_shift;\n ni_shift += (xb_work & 0x1fff) > 456 ? 13 : 14;\n do {\n a_out.push(xb_decode & 0xff);\n xb_decode >>= 8;\n ni_shift -= 8;\n } while (ni_shift > 7);\n xb_work = -1;\n }\n if (-1 !== xb_work)\n a_out.push(xb_decode | (xb_work << ni_shift));\n return Uint8Array.from(a_out.slice(0, Math.ceil(sb93_data.length * 7 / 8)));\n};\n// inspired by \n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst SX_CHARS_BASE58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst A_CHARS_BASE58 = /*#__PURE__*/ (() => {\n const a_out = Array(256).fill(-1);\n let i_char = 0;\n // eslint-disable-next-line prefer-const\n for (let s_char of SX_CHARS_BASE58) {\n a_out[s_char.charCodeAt(0)] = i_char++;\n }\n return a_out;\n})();\nexport const bytes_to_base58 = (atu8_buffer) => {\n const a_out = [];\n for (const xb_char of atu8_buffer) {\n let xb_carry = xb_char;\n for (let ib_sweep = 0; ib_sweep < a_out.length; ++ib_sweep) {\n const xb_value = (A_CHARS_BASE58[a_out[ib_sweep]] << 8) + xb_carry;\n a_out[ib_sweep] = SX_CHARS_BASE58.charCodeAt(xb_value % 58);\n xb_carry = (xb_value / 58) | 0;\n }\n while (xb_carry) {\n a_out.push(SX_CHARS_BASE58.charCodeAt(xb_carry % 58));\n xb_carry = (xb_carry / 58) | 0;\n }\n }\n for (const xb_char of atu8_buffer) {\n if (xb_char) {\n break;\n }\n else {\n a_out.push('1'.charCodeAt(0));\n }\n }\n a_out.reverse();\n return String.fromCharCode(...a_out);\n};\nexport const base58_to_bytes = (sb58_buffer) => {\n if (!sb58_buffer || !is_string(sb58_buffer)) {\n die(`Expected base58 string but got “${sb58_buffer}”`);\n }\n const m_invalid = sb58_buffer.match(/[IOl0]/gmu);\n if (m_invalid) {\n die(`Invalid base58 character “${String(m_invalid)}”`);\n }\n const m_lz = sb58_buffer.match(/^1+/gmu);\n const nl_psz = m_lz ? m_lz[0].length : 0;\n const nb_out = (((sb58_buffer.length - nl_psz) * (Math.log(58) / Math.log(256))) + 1) >>> 0;\n return bytes([\n ...bytes(nl_psz),\n ...sb58_buffer\n .match(/.{1}/gmu)\n .map(sxb58 => SX_CHARS_BASE58.indexOf(sxb58))\n .reduce((atu8_out, ib_pos) => atu8_out.map((xb_char) => {\n const xb_tmp = (xb_char * 58) + ib_pos;\n ib_pos = xb_tmp >> 8;\n return xb_tmp;\n }), bytes(nb_out))\n .reverse()\n .filter((b_last => xb_each => (b_last = b_last || !!xb_each))(false)),\n ]);\n};\n/**\n * Cryptographically strong random bytes\n * @param nb_len - number of bytes to fill\n */\nexport const crypto_random_bytes = (nb_len = 32) => crypto.getRandomValues(bytes(nb_len));\n/**\n * Cryptographically strong random number in the range [0, 1)\n */\nexport const crypto_random_unit_double = () => crypto_random_bytes(1)[0] / (2 ** 32);\n/**\n * @deprecated Replace with {@link crypto_random_unit_double}\n */\nexport const crypto_random = crypto_random_unit_double;\n/**\n * Generate a cryptographically strong random int within a given range\n */\nexport const crypto_random_int = (x_a, x_b = 0) => {\n const x_min = Math.floor(Math.min(x_a, x_b));\n const x_max = Math.ceil(Math.max(x_a, x_b));\n // confine to range\n return Math.floor(crypto_random_unit_double() * (x_max - x_min)) + x_min;\n};\n//# sourceMappingURL=data.js.map","import type {ImportMapper} from '../types';\n\nexport const emsimp = (f_map_imports: ImportMapper, s_tag: string) => {\n\ts_tag += ': ';\n\n\tlet AB_HEAP: ArrayBuffer;\n\tlet ATU8_HEAP: Uint8Array;\n\tlet ATU32_HEAP: Uint32Array;\n\n\t// eslint-disable-next-line no-console\n\tconst console_out = (s_channel: Extract, s_out: string) => console[s_channel](s_tag+s_out.replace(/\\0/g, '\\n'));\n\n\tlet s_error = '';\n\n\tconst h_fds: Record void> = {\n\t\t// stdout\n\t\t1(s_out) {\n\t\t\tconsole_out('debug', s_out);\n\t\t},\n\n\t\t// stderr\n\t\t2(s_out) {\n\t\t\tconsole_out('error', s_error=s_out);\n\t\t},\n\t};\n\n\tconst g_imports = f_map_imports({\n\t\tabort() {\n\t\t\tthrow Error(s_tag+(s_error || 'An unknown error occurred'));\n\t\t},\n\n\t\tmemcpy: (ip_dst, ip_src, nb_size) => ATU8_HEAP.copyWithin(ip_dst, ip_src, ip_src+nb_size),\n\n\t\tresize(nb_size) {\n\t\t\tthrow Error(s_tag+'Out of memory');\n\t\t},\n\n\t\twrite(i_fd, ip_iov, nl_iovs, ip_written) {\n\t\t\t// output string\n\t\t\tlet s_out = '';\n\n\t\t\t// track number of bytes read from buffers\n\t\t\tlet cb_read = 0;\n\n\t\t\t// each pending iov\n\t\t\tfor(let i_iov=0; i_iov> 2];\n\n\t\t\t\t// size of buffer\n\t\t\t\tconst nb_len = ATU32_HEAP[ip_iov + 4 >> 2];\n\n\t\t\t\t// next iov\n\t\t\t\t(ip_iov as number) += 8;\n\n\t\t\t\t// extract text from buffer\n\t\t\t\ts_out += new TextDecoder().decode(ATU8_HEAP.subarray(ip_start, ip_start+nb_len));\n\n\t\t\t\t// update number of bytes read\n\t\t\t\tcb_read += nb_len;\n\t\t\t}\n\n\t\t\t// route to fd\n\t\t\tif(h_fds[i_fd]) {\n\t\t\t\th_fds[i_fd](s_out);\n\t\t\t}\n\t\t\t// no fd found\n\t\t\telse {\n\t\t\t\tthrow new Error(`libsecp256k1 tried writing to non-open file descriptor: ${i_fd}\\n${s_out}`);\n\t\t\t}\n\n\t\t\t// write bytes read\n\t\t\tATU32_HEAP[ip_written >> 2] = cb_read;\n\n\t\t\t// no error\n\t\t\treturn 0;\n\t\t},\n\t});\n\n\treturn [g_imports, (d_memory: WebAssembly.Memory) => [\n\t\tAB_HEAP = d_memory.buffer,\n\t\tATU8_HEAP = new Uint8Array(AB_HEAP),\n\t\tATU32_HEAP = new Uint32Array(AB_HEAP),\n\t] as const] as const;\n};\n","import type {WasmExportsExtension} from '../gen/wasm.js';\nimport type {ByteSize, Pointer} from '../types.js';\n\nexport type PointerContext = Pointer<'context'>;\nexport type PointerSeed = Pointer<'seed'>;\nexport type PointerPubkey = Pointer<'pubkey'>;\nexport type PointerSig = Pointer<'ecdsa_signature'>;\nexport type PointerSigRecoverable = Pointer<'ecdsa_recoverable_signature'>;\nexport type PointerNonceFn = Pointer<'nonce_function'>;\n\nexport type PointerSha256 = Pointer<'sha256'>;\n\nexport type RecoveryValue = 0 | 1 | 2 | 3;\n\nexport type SignatureAndRecovery = [\n\tatu8_signature: Uint8Array,\n\txc_recovery: RecoveryValue,\n];\n\n\n/* eslint-disable @typescript-eslint/no-duplicate-enum-values, @typescript-eslint/prefer-literal-enum-member */\nexport const enum ByteLens {\n\tRANDOM_SEED = 32, // when randomizing context\n\n\tPRIVATE_KEY = 32,\n\tECDH_SHARED_SK = 32,\n\n\tPUBLIC_KEY_COMPRESSED = 33,\n\tPUBLIC_KEY_LIB = 64, // secp256k1_pubkey: char [64];\n\tPUBLIC_KEY_UNCOMPRESSED = 65,\n\tPUBLIC_KEY_MAX = 65, // uncompressed public key is largest\n\n\tECDSA_SIG_COMPACT = 64,\n\tECDSA_SIG_LIB = 64, // secp256k1_ecdsa_signature: char [64];\n\tECDSA_SIG_RECOVERABLE = 65, // secp256k1_ecdsa_recoverable_signature: char [65];\n\n\tMSG_HASH = 32,\n\tNONCE_ENTROPY = 32,\n\n\t/**\n\t * From the source:\n\t * ```\n\t * typedef struct {\n\t * uint32_t s[8];\n\t * unsigned char buf[64];\n\t * uint64_t bytes;\n\t * } secp256k1_sha256;\n\t * ```\n\t */\n\tSHA256 = (4 * 8) + 64 + 8,\n}\n\n// ##### From secp256k1.h: #####\n// /* All flags' lower 8 bits indicate what they're for. Do not use directly. */\n// #define SECP256K1_FLAGS_TYPE_MASK ((1 << 8) - 1)\n// #define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0)\n// #define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1)\n// /* The higher bits contain the actual data. Do not use directly. */\n// #define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY (1 << 8)\n// #define SECP256K1_FLAGS_BIT_CONTEXT_SIGN (1 << 9)\n// #define SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY (1 << 10)\n// #define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8)\n\n/* eslint-disable @typescript-eslint/prefer-literal-enum-member, no-multi-spaces */\nexport const enum Flags {\n\tCONTEXT_NONE = (1 << 0) | 0,\n\tCONTEXT_VERIFY = (1 << 0) | (1 << 8),\n\tCONTEXT_SIGN = (1 << 0) | (1 << 9),\n\tCONTEXT_DECLASSIFY = (1 << 0) | (1 << 10),\n\n\tCOMPRESSION_UNCOMPRESSED = (1 << 1) | 0,\n\tCOMPRESSION_COMPRESSED = (1 << 1) | (1 << 8),\n}\n/* eslint-enable */\n\n\nexport const enum BinaryResult {\n\tSUCCESS = 1,\n\tFAILURE = 0,\n}\n\nexport interface Secp256k1WasmCore extends WasmExportsExtension {\n\t/** Create a secp256k1 context object (in dynamically allocated memory).\n\t *\n\t * This function uses malloc to allocate memory. It is guaranteed that malloc is\n\t * called at most once for every call of this function. If you need to avoid dynamic\n\t * memory allocation entirely, see secp256k1_context_static and the functions in\n\t * secp256k1_preallocated.h.\n\t *\n\t * Returns: a newly created context object.\n\t * In: flags: Always set to SECP256K1_CONTEXT_NONE (see below).\n\t */\n\tcontext_create(\n\t\txm_flags: Flags,\n\t): PointerContext;\n\n\n\t/** Randomizes the context to provide enhanced protection against side-channel leakage.\n\t *\n\t * Returns: 1: randomization successful\n\t * 0: error\n\t * Args: ctx: pointer to a context object (not secp256k1_context_static).\n\t * In: seed32: pointer to a 32-byte random seed (NULL resets to initial state).\n\t */\n\tcontext_randomize(\n\t\tip_ctx: PointerContext,\n\t\tip_seed: PointerSeed,\n\t): BinaryResult;\n\n\n\t/** Compute the public key for a secret key.\n\t *\n\t * Returns: 1: secret was valid, public key stores.\n\t * 0: secret was invalid, try again.\n\t * Args: ctx: pointer to a context object (not secp256k1_context_static).\n\t * Out: pubkey: pointer to the created public key.\n\t * In: seckey: pointer to a 32-byte secret key.\n\t */\n\tec_pubkey_create(\n\t\tip_ctx: PointerContext,\n\t\tip_pk_out: PointerPubkey,\n\t\tip_sk_in: Pointer<32>,\n\t): BinaryResult;\n\n\n\t/** Verify an ECDSA secret key.\n\t *\n\t * A secret key is valid if it is not 0 and less than the secp256k1 curve order\n\t * when interpreted as an integer (most significant byte first). The\n\t * probability of choosing a 32-byte string uniformly at random which is an\n\t * invalid secret key is negligible.\n\t *\n\t * Returns: 1: secret key is valid\n\t * 0: secret key is invalid\n\t * Args: ctx: pointer to a context object.\n\t * In: seckey: pointer to a 32-byte secret key.\n\t */\n\tec_seckey_verify(\n\t\tip_ctx: PointerContext,\n\t\tip_sk_in: Pointer<32>,\n\t): BinaryResult;\n\n\n\t/** Parse a variable-length public key into the pubkey object.\n\t *\n\t * Returns: 1 if the public key was fully valid.\n\t * 0 if the public key could not be parsed or is invalid.\n\t * Args: ctx: a secp256k1 context object.\n\t * Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a\n\t * parsed version of input. If not, its value is undefined.\n\t * In: input: pointer to a serialized public key\n\t * inputlen: length of the array pointed to by input\n\t */\n\tec_pubkey_parse(\n\t\tip_ctx: PointerContext,\n\t\tip_pk_out: PointerPubkey,\n\t\tip_pk_in: Pointer<65>,\n\t\tnb_len: ByteSize,\n\t): BinaryResult;\n\n\n\t/** Serialize a pubkey object into a serialized byte sequence.\n\t *\n\t * Returns: 1 always.\n\t * Args: ctx: a secp256k1 context object.\n\t * Out: output: a pointer to a 65-byte (if compressed==0) or 33-byte (if\n\t * compressed==1) byte array to place the serialized key\n\t * in.\n\t * In/Out: outputlen: a pointer to an integer which is initially set to the\n\t * size of output, and is overwritten with the written\n\t * size.\n\t * In: pubkey: a pointer to a secp256k1_pubkey containing an\n\t * initialized public key.\n\t * flags: SECP256K1_EC_COMPRESSED if serialization should be in\n\t * compressed format, otherwise SECP256K1_EC_UNCOMPRESSED.\n\t */\n\tec_pubkey_serialize(\n\t\tip_ctx: PointerContext,\n\t\tip_pk_out: Pointer<65>,\n\t\tip_len_inout: Pointer<4>,\n\t\tip_pk_in: PointerPubkey,\n\t\txm_flags: Flags,\n\t): BinaryResult.SUCCESS;\n\n\n\t/** Tweak a secret key by adding tweak to it.\n\t *\n\t * Returns: 0 if the arguments are invalid or the resulting secret key would be\n\t * invalid (only when the tweak is the negation of the secret key). 1\n\t * otherwise.\n\t * Args: ctx: pointer to a context object.\n\t * In/Out: seckey: pointer to a 32-byte secret key. If the secret key is\n\t * invalid according to secp256k1_ec_seckey_verify, this\n\t * function returns 0. seckey will be set to some unspecified\n\t * value if this function returns 0.\n\t * In: tweak32: pointer to a 32-byte tweak, which must be valid according to\n\t * secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly\n\t * random 32-byte tweaks, the chance of being invalid is\n\t * negligible (around 1 in 2^128).\n\t */\n\tec_seckey_tweak_add(\n\t\tthis: void,\n\t\tip_ctx: PointerContext,\n\t\tip_sk_inout: Pointer<32>,\n\t\tip_tweak_in: Pointer<32>,\n\t): BinaryResult.SUCCESS;\n\n\n\t/** Tweak a secret key by multiplying it by a tweak.\n\t *\n\t * Returns: 0 if the arguments are invalid. 1 otherwise.\n\t * Args: ctx: pointer to a context object.\n\t * In/Out: seckey: pointer to a 32-byte secret key. If the secret key is\n\t * invalid according to secp256k1_ec_seckey_verify, this\n\t * function returns 0. seckey will be set to some unspecified\n\t * value if this function returns 0.\n\t * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to\n\t * secp256k1_ec_seckey_verify, this function returns 0. For\n\t * uniformly random 32-byte arrays the chance of being invalid\n\t * is negligible (around 1 in 2^128).\n\t */\n\tec_seckey_tweak_mul(\n\t\tthis: void,\n\t\tip_ctx: PointerContext,\n\t\tip_sk_inout: Pointer<32>,\n\t\tip_tweak_in: Pointer<32>,\n\t): BinaryResult.SUCCESS;\n\n\n\t/** Tweak a public key by adding tweak times the generator to it.\n\t *\n\t * Returns: 0 if the arguments are invalid or the resulting public key would be\n\t * invalid (only when the tweak is the negation of the corresponding\n\t * secret key). 1 otherwise.\n\t * Args: ctx: pointer to a context object.\n\t * In/Out: pubkey: pointer to a public key object. pubkey will be set to an\n\t * invalid value if this function returns 0.\n\t * In: tweak32: pointer to a 32-byte tweak, which must be valid according to\n\t * secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly\n\t * random 32-byte tweaks, the chance of being invalid is\n\t * negligible (around 1 in 2^128).\n\t */\n\tec_pubkey_tweak_add(\n\t\tthis: void,\n\t\tip_ctx: PointerContext,\n\t\tip_pk_inout: PointerPubkey,\n\t\tip_tweak_in: Pointer<32>,\n\t): BinaryResult.SUCCESS;\n\n\n\t/** Tweak a public key by multiplying it by a tweak value.\n\t *\n\t * Returns: 0 if the arguments are invalid. 1 otherwise.\n\t * Args: ctx: pointer to a context object.\n\t * In/Out: pubkey: pointer to a public key object. pubkey will be set to an\n\t * invalid value if this function returns 0.\n\t * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to\n\t * secp256k1_ec_seckey_verify, this function returns 0. For\n\t * uniformly random 32-byte arrays the chance of being invalid\n\t * is negligible (around 1 in 2^128).\n\t */\n\tec_pubkey_tweak_mul(\n\t\tthis: void,\n\t\tip_ctx: PointerContext,\n\t\tip_pk_inout: PointerPubkey,\n\t\tip_tweak_in: Pointer<32>,\n\t): BinaryResult.SUCCESS;\n}\n\n\nexport interface Secp256k1WasmEcdh {\n\t/** Compute an EC Diffie-Hellman secret in constant time\n\t *\n\t * Returns: 1: exponentiation was successful\n\t * 0: scalar was invalid (zero or overflow) or hashfp returned 0\n\t * Args: ctx: pointer to a context object.\n\t * Out: output: pointer to an array to be filled by hashfp.\n\t * In: pubkey: a pointer to a secp256k1_pubkey containing an initialized public key.\n\t * seckey: a 32-byte scalar with which to multiply the point.\n\t * hashfp: pointer to a hash function. If NULL,\n\t * secp256k1_ecdh_hash_function_sha256 is used\n\t * (in which case, 32 bytes will be written to output).\n\t * data: arbitrary data pointer that is passed through to hashfp\n\t * (can be NULL for secp256k1_ecdh_hash_function_sha256).\n\t */\n\tecdh(\n\t\tip_ctx: PointerContext,\n\t\tip_shared_out: Pointer<32>,\n\t\tip_pk_in: PointerPubkey,\n\t\tip_sk_in: Pointer<32>,\n\t\tip_noncefn_in?: PointerNonceFn,\n\t\tip_ent_in?: Pointer<32>,\n\t): BinaryResult;\n}\n\n\nexport interface Secp256k1WasmEcdsaRaw {\n\t/** Parse an ECDSA signature in compact (64 bytes) format.\n\t *\n\t * Returns: 1 when the signature could be parsed, 0 otherwise.\n\t * Args: ctx: a secp256k1 context object\n\t * Out: sig: a pointer to a signature object\n\t * In: input64: a pointer to the 64-byte array to parse\n\t *\n\t * The signature must consist of a 32-byte big endian R value, followed by a\n\t * 32-byte big endian S value. If R or S fall outside of [0..order-1], the\n\t * encoding is invalid. R and S with value 0 are allowed in the encoding.\n\t *\n\t * After the call, sig will always be initialized. If parsing failed or R or\n\t * S are zero, the resulting sig value is guaranteed to fail verification for\n\t * any message and public key.\n\t */\n\tecdsa_signature_parse_compact(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_out: PointerSig,\n\t\tip_sig_in: Pointer<64>,\n\t): BinaryResult;\n\n\n\t/** Serialize an ECDSA signature in compact (64 byte) format.\n\t *\n\t * Returns: 1\n\t * Args: ctx: a secp256k1 context object\n\t * Out: output64: a pointer to a 64-byte array to store the compact serialization\n\t * In: sig: a pointer to an initialized signature object\n\t *\n\t * See secp256k1_ecdsa_signature_parse_compact for details about the encoding.\n\t */\n\tecdsa_signature_serialize_compact(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_out: Pointer<64>,\n\t\tip_sig_in: PointerSig,\n\t): BinaryResult.SUCCESS;\n\n\n\t/** Create an ECDSA signature.\n\t *\n\t * Returns: 1: signature created\n\t * 0: the nonce generation function failed, or the secret key was invalid.\n\t * Args: ctx: pointer to a context object (not secp256k1_context_static).\n\t * Out: sig: pointer to an array where the signature will be placed.\n\t * In: msghash32: the 32-byte message hash being signed.\n\t * seckey: pointer to a 32-byte secret key.\n\t * noncefp: pointer to a nonce generation function. If NULL,\n\t * secp256k1_nonce_function_default is used.\n\t * ndata: pointer to arbitrary data used by the nonce generation function\n\t * (can be NULL). If it is non-NULL and\n\t * secp256k1_nonce_function_default is used, then ndata must be a\n\t * pointer to 32-bytes of additional data.\n\t *\n\t * The created signature is always in lower-S form. See\n\t * secp256k1_ecdsa_signature_normalize for more details.\n\t */\n\tecdsa_sign(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_out: PointerSig,\n\t\tip_hash_in: Pointer<32>,\n\t\tip_sk: Pointer<32>,\n\t\tip_noncefn?: PointerNonceFn,\n\t\tip_ent?: Pointer<32>,\n\t): BinaryResult;\n\n\n\t/** Verify an ECDSA signature.\n\t *\n\t * Returns: 1: correct signature\n\t * 0: incorrect or unparseable signature\n\t * Args: ctx: a secp256k1 context object.\n\t * In: sig: the signature being verified.\n\t * msghash32: the 32-byte message hash being verified.\n\t * The verifier must make sure to apply a cryptographic\n\t * hash function to the message by itself and not accept an\n\t * msghash32 value directly. Otherwise, it would be easy to\n\t * create a \"valid\" signature without knowledge of the\n\t * secret key. See also\n\t * https://bitcoin.stackexchange.com/a/81116/35586 for more\n\t * background on this topic.\n\t * pubkey: pointer to an initialized public key to verify with.\n\t */\n\tecdsa_verify(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_in: PointerSig,\n\t\tip_hash_in: Pointer<32>,\n\t\tip_pk_in: PointerPubkey,\n\t): BinaryResult;\n}\n\n\nexport interface Secp256k1WasmEcdsaRecovery {\n\t/** Parse a compact ECDSA signature (64 bytes + recovery id).\n\t *\n\t * Returns: 1 when the signature could be parsed, 0 otherwise\n\t * Args: ctx: a secp256k1 context object\n\t * Out: sig: a pointer to a signature object\n\t * In: input64: a pointer to a 64-byte compact signature\n\t * recid: the recovery id (0, 1, 2 or 3)\n\t */\n\tecdsa_recoverable_signature_parse_compact(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_out: PointerSigRecoverable,\n\t\tip_sig_in: Pointer<64>,\n\t\txb_v_in: number,\n\t): BinaryResult;\n\n\n\t/** Serialize an ECDSA signature in compact format (64 bytes + recovery id).\n\t *\n\t * Returns: 1\n\t * Args: ctx: a secp256k1 context object.\n\t * Out: output64: a pointer to a 64-byte array of the compact signature.\n\t * recid: a pointer to an integer to hold the recovery id.\n\t * In: sig: a pointer to an initialized signature object.\n\t */\n\tecdsa_recoverable_signature_serialize_compact(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_out: Pointer<64>,\n\t\tip_v_out: Pointer<4>,\n\t\tip_sig_in: PointerSigRecoverable,\n\t): BinaryResult.SUCCESS;\n\n\n\t/** Create a recoverable ECDSA signature.\n\t *\n\t * Returns: 1: signature created\n\t * 0: the nonce generation function failed, or the secret key was invalid.\n\t * Args: ctx: pointer to a context object (not secp256k1_context_static).\n\t * Out: sig: pointer to an array where the signature will be placed.\n\t * In: msghash32: the 32-byte message hash being signed.\n\t * seckey: pointer to a 32-byte secret key.\n\t * noncefp: pointer to a nonce generation function. If NULL,\n\t * secp256k1_nonce_function_default is used.\n\t * ndata: pointer to arbitrary data used by the nonce generation function\n\t * (can be NULL for secp256k1_nonce_function_default).\n\t */\n\tecdsa_sign_recoverable(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_out: PointerSigRecoverable,\n\t\tip_hash_in: Pointer<32>,\n\t\tip_sk_in: Pointer<32>,\n\t\tip_noncefn_in: PointerNonceFn,\n\t\tip_ent_in: Pointer<32>,\n\t): BinaryResult;\n\n\n\t/** Recover an ECDSA public key from a signature.\n\t *\n\t * Returns: 1: public key successfully recovered (which guarantees a correct signature).\n\t * 0: otherwise.\n\t * Args: ctx: pointer to a context object.\n\t * Out: pubkey: pointer to the recovered public key.\n\t * In: sig: pointer to initialized signature that supports pubkey recovery.\n\t * msghash32: the 32-byte message hash assumed to be signed.\n\t */\n\tecdsa_recover(\n\t\tip_ctx: PointerContext,\n\t\tip_pk_out: PointerPubkey,\n\t\tip_sig_in: PointerSigRecoverable,\n\t\tip_hash_in: Pointer<32>,\n\t): BinaryResult;\n}\n\n\nexport interface Secp256k1WasmSha256 {\n\tsha256_initialize(\n\t\tip_hash: PointerSha256,\n\t): void;\n\n\tsha256_write(\n\t\tip_hash: PointerSha256,\n\t\tip_data_in: Pointer,\n\t\tnb_data_in: number,\n\t): void;\n\n\tsha256_finalize(\n\t\tip_hash: PointerSha256,\n\t\tip_digest_out: Pointer<32>,\n\t): void;\n}\n","\n/*\n* ================================\n* GENERATED FILE WARNING\n* Do not edit this file manually.\n* ================================\n*/\n\n/* eslint-disable @typescript-eslint/no-unused-vars, unused-imports/no-unused-imports, no-trailing-spaces */\n\nimport type {\n\tPointer,\n\tByteSize,\n\tByteDelta,\n\tByteOffset,\n\tFileDescriptor,\n\tSeekWhence,\n\tWasmImports,\n\tWasmExports,\n} from '../types.js';\n\nexport interface WasmImportsExtension extends WasmImports {\n\t\n}\n\nexport interface WasmExportsExtension extends WasmExports {\n\tcontext_create: Function;\n\tec_pubkey_parse: Function;\n\tec_pubkey_serialize: Function;\n\tecdsa_signature_parse_compact: Function;\n\tecdsa_verify: Function;\n\tec_seckey_verify: Function;\n\tec_pubkey_create: Function;\n\tec_seckey_tweak_add: Function;\n\tec_pubkey_tweak_add: Function;\n\tec_seckey_tweak_mul: Function;\n\tec_pubkey_tweak_mul: Function;\n\tcontext_randomize: Function;\n\tecdh: Function;\n\tecdsa_recoverable_signature_parse_compact: Function;\n\tecdsa_recoverable_signature_serialize_compact: Function;\n\tecdsa_sign_recoverable: Function;\n\tecdsa_recover: Function;\n}\n\nexport const map_wasm_imports = (g_imports: WasmImportsExtension) => ({\n\ta: {\n\t\tf: g_imports.abort,\n\t\te: g_imports.memcpy,\n\t\tc: g_imports.resize,\n\t\td: () => 52, // _fd_close,\n\t\tb: () => 70, // _fd_seek,\n\t\ta: g_imports.write,\n\t},\n});\n\nexport const map_wasm_exports = <\n\tg_extension extends WasmExportsExtension=WasmExportsExtension,\n>(g_exports: WebAssembly.Exports): g_extension => ({\n\tmalloc: g_exports['i'],\n\tfree: g_exports['j'],\n\tcontext_create: g_exports['l'],\n\tec_pubkey_parse: g_exports['m'],\n\tec_pubkey_serialize: g_exports['n'],\n\tecdsa_signature_parse_compact: g_exports['o'],\n\tecdsa_verify: g_exports['p'],\n\tec_seckey_verify: g_exports['q'],\n\tec_pubkey_create: g_exports['r'],\n\tec_seckey_tweak_add: g_exports['s'],\n\tec_pubkey_tweak_add: g_exports['t'],\n\tec_seckey_tweak_mul: g_exports['u'],\n\tec_pubkey_tweak_mul: g_exports['v'],\n\tcontext_randomize: g_exports['w'],\n\tecdh: g_exports['x'],\n\tecdsa_recoverable_signature_parse_compact: g_exports['y'],\n\tecdsa_recoverable_signature_serialize_compact: g_exports['z'],\n\tecdsa_sign_recoverable: g_exports['A'],\n\tecdsa_recover: g_exports['B'],\n\tmemory: g_exports['g'],\n\n\tinit: () => (g_exports['h'] as VoidFunction)(),\n} as g_extension);\n\n","import type {PointerNonceFn, PointerPubkey, PointerSeed, PointerSig, PointerSigRecoverable, RecoveryValue, Secp256k1WasmCore, Secp256k1WasmEcdh, Secp256k1WasmEcdsaRaw, Secp256k1WasmEcdsaRecovery, SignatureAndRecovery} from './secp256k1-types.js';\nimport type {ByteSize, Pointer} from '../types.js';\nimport type {Promisable} from '@blake.regalia/belt';\n\nimport {bytes} from '@blake.regalia/belt';\n\nimport {emsimp} from './emsimp.js';\nimport {BinaryResult, ByteLens, Flags} from './secp256k1-types.js';\nimport {map_wasm_exports, map_wasm_imports} from '../gen/wasm.js';\n\n\nconst S_TAG_ECDH = 'ECDH: ';\nconst S_TAG_ECDSA_VERIFY = 'ECDSA verify: ';\nconst S_TAG_TWEAK_ADD = 'k tweak add: ';\nconst S_TAG_TWEAK_MUL = 'k tweak mul: ';\n\nconst S_REASON_INVALID_SK = 'Invalid private key';\nconst S_REASON_INVALID_PK = 'Invalid public key';\nconst S_REASON_UNPARSEABLE_SIG = 'Unparseable signature';\n\nconst random_32 = () => crypto.getRandomValues(bytes(32));\n\n/**\n * Wrapper instance providing operations backed by libsecp256k1 WASM module\n */\nexport interface Secp256k1 {\n\t/**\n\t * Generates a new private key using crypto secure random bytes and without modulo bias\n\t * @returns a new private key (32 bytes)\n\t */\n\tgen_sk(): Uint8Array;\n\n\t/**\n\t * Asserts that the given private key is valid, throws otherwise\n\t * @param atu8_sk - the private key (32 bytes)\n\t * @returns the same `Uint8Array`\n\t */\n\tvalid_sk(atu8_sk: Uint8Array): Uint8Array;\n\n\t/**\n\t * Computes the public key for a given private key\n\t * @param atu8_sk - the private key (32 bytes)\n\t * @param b_uncompressed - optional flag to return the uncompressed (65 byte) public key\n\t * @returns the public key (compressed to 33 bytes by default, or 65 if uncompressed)\n\t */\n\tsk_to_pk(atu8_sk: Uint8Array, b_uncompressed?: boolean): Uint8Array;\n\n\t/**\n\t * Signs the given message hash using the given private key.\n\t * @param atu8_sk - the private key\n\t * @param atu8_hash - the message hash (32 bytes)\n\t * @param atu8_entropy - optional entropy to use\n\t * @returns compact signature (64 bytes) as concatenation of `r || s`\n\t */\n\tsign(atu8_sk: Uint8Array, atu8_hash: Uint8Array, atu8_ent?: Uint8Array): SignatureAndRecovery;\n\n\t/**\n\t * Verifies the signature is valid for the given message hash and public key\n\t * @param atu8_signature - compact signature in `r || s` form (64 bytes)\n\t * @param atu8_msg - the message hash (32 bytes)\n\t * @param atu8_pk - the public key\n\t */\n\tverify(atu8_signature: Uint8Array, atu8_hash: Uint8Array, atu8_pk: Uint8Array): boolean;\n\n\t/**\n\t * Recovers a public key from the given signature and recovery ID\n\t * @param atu8_signature - compact signature in `r || s` form (64 bytes)\n\t * @param xc_recovery - the recovery ID\n\t */\n\trecover(atu8_signature: Uint8Array, atu8_hash: Uint8Array, xc_recovery: number): Uint8Array;\n\n\t/**\n\t * ECDH key exchange. Computes a shared secret given a private key some public key\n\t * @param atu8_sk - the private key (32 bytes)\n\t * @param atu8_pk - the public key (33 or 65 bytes)\n\t * @returns the shared secret (32 bytes)\n\t */\n\tecdh(atu8_sk: Uint8Array, atu8_pk: Uint8Array): Uint8Array;\n\n\t/**\n\t * Tweak the given private key by adding to it\n\t * @param atu8_sk - the private key (32 bytes)\n\t * @param atu8_tweak - the tweak vector (32 bytes)\n\t * @returns the tweaked private key\n\t */\n\ttweak_sk_add(atu8_sk: Uint8Array, atu8_tweak: Uint8Array): Uint8Array;\n\n\t/**\n\t * Tweak the given private key by multiplying it\n\t * @param atu8_sk - the private key (32 bytes)\n\t * @param atu8_tweak - the tweak vector (32 bytes)\n\t * @returns the tweaked private key\n\t */\n\ttweak_sk_mul(atu8_sk: Uint8Array, atu8_tweak: Uint8Array): Uint8Array;\n\n\t/**\n\t * Tweak the given public key by adding to it\n\t * @param atu8_pk - the public key (33 or 65 bytes)\n\t * @param atu8_tweak - the tweak vector (32 bytes)\n\t * @returns the tweaked public key\n\t */\n\ttweak_pk_add(atu8_pk: Uint8Array, atu8_tweak: Uint8Array, b_uncompressed?: boolean): Uint8Array;\n\n\t/**\n\t * Tweak the given public key by multiplying it\n\t * @param atu8_pk - the public key (33 or 65 bytes)\n\t * @param atu8_tweak - the tweak vector (32 bytes)\n\t * @returns the tweaked public key\n\t */\n\ttweak_pk_mul(atu8_pk: Uint8Array, atu8_tweak: Uint8Array, b_uncompressed?: boolean): Uint8Array;\n}\n\n/**\n * Creates a new instance of the secp256k1 WASM and returns its ES wrapper\n * @param z_src - a Response containing the WASM binary, a Promise that resolves to one,\n * \tor the raw bytes to the WASM binary as a {@link BufferSource}\n * @returns the wrapper API\n */\nexport const WasmSecp256k1 = async(\n\tz_src: Promisable | BufferSource\n): Promise => {\n\t// prepare the runtime\n\tconst [g_imports, f_bind_heap] = emsimp(map_wasm_imports, 'wasm-secp256k1');\n\n\t// prep the wasm module\n\tlet d_wasm: WebAssembly.WebAssemblyInstantiatedSource;\n\n\t// instantiate wasm binary by streaming the response bytes\n\tif(z_src instanceof Response || z_src instanceof Promise) {\n\t\td_wasm = await WebAssembly.instantiateStreaming(z_src as Response, g_imports);\n\t}\n\t// instantiate using raw bianry\n\telse {\n\t\td_wasm = await WebAssembly.instantiate(z_src as BufferSource, g_imports);\n\t}\n\n\t// create the libsecp256k1 exports struct\n\tconst g_wasm = map_wasm_exports<\n\t\tSecp256k1WasmCore\n\t\t& Secp256k1WasmEcdh\n\t\t& Secp256k1WasmEcdsaRaw\n\t\t& Secp256k1WasmEcdsaRecovery\n\t>(d_wasm.instance.exports);\n\n\t// bind the heap and ref its view(s)\n\tconst [, ATU8_HEAP, ATU32_HEAP] = f_bind_heap(g_wasm.memory);\n\n\t// call into the wasm module's init method\n\tg_wasm.init();\n\n\t// ref malloc function\n\tconst malloc = g_wasm.malloc;\n\n\tconst ip_sk = malloc(ByteLens.PRIVATE_KEY);\n\tconst ip_ent = malloc(ByteLens.NONCE_ENTROPY);\n\tconst ip_seed = malloc(ByteLens.RANDOM_SEED);\n\tconst ip_sk_shared = malloc(ByteLens.ECDH_SHARED_SK);\n\tconst ip_msg_hash = malloc(ByteLens.MSG_HASH);\n\n\t// scratch spaces\n\tconst ip_sig_scratch = malloc(ByteLens.ECDSA_SIG_COMPACT);\n\tconst ip_pk_scratch = malloc(ByteLens.PUBLIC_KEY_MAX);\n\n\t// library handle: secp256k1_pubkey\n\tconst ip_pk_lib = malloc(ByteLens.PUBLIC_KEY_LIB);\n\n\t// library handle: secp256k1_ecdsa_signature\n\tconst ip_sig_lib = malloc(ByteLens.ECDSA_SIG_LIB);\n\n\t// library handle: secp256k1_ecdsa_signature\n\tconst ip_sig_rcvr_lib = malloc(ByteLens.ECDSA_SIG_RECOVERABLE);\n\n\t// recovery id byte\n\tconst ip_v = malloc(4);\n\n\t// create a reusable context\n\tconst ip_ctx = g_wasm.context_create(Flags.CONTEXT_SIGN | Flags.CONTEXT_VERIFY);\n\n\t// length specifier\n\tconst ip_len = g_wasm.malloc(4);\n\tconst ip32_len = ip_len >> 2;\n\n\n\n\t/**\n\t * Pads the given input data before copying it into the heap at the given location; throws if input\n\t * data exceeds expected size\n\t * @param atu8_data - the data to put into program memory\n\t * @param ib_write - the starting byte position to write into\n\t * @param nb_size - the size of the region\n\t */\n\tconst put_bytes = (atu8_data: Uint8Array, ip_write: Pointer, nb_size: ByteSize) => {\n\t\tconst atu8_buffer = bytes(nb_size);\n\t\tatu8_buffer.set(atu8_data);\n\t\tATU8_HEAP.set(atu8_buffer, ip_write);\n\t};\n\n\t/**\n\t * Randomizes the context for better protection against CPU side-channel attacks\n\t */\n\tconst randomize_context = () => {\n\t\t// put random seed bytes into place\n\t\tput_bytes(random_32(), ip_seed, ByteLens.RANDOM_SEED);\n\n\t\t// randomize context\n\t\tif(BinaryResult.SUCCESS !== g_wasm.context_randomize(ip_ctx, ip_seed)) {\n\t\t\tthrow Error('Failed to randomize context');\n\t\t}\n\t};\n\n\t/**\n\t * Parses the input public key in preparation for use by some method\n\t * @param atu8_sk - the private key\n\t * @returns `true` on success, `false` otherwise\n\t */\n\tconst parse_pubkey = (atu8_pk: Uint8Array): boolean => {\n\t\t// copy input bytes into place\n\t\tput_bytes(atu8_pk, ip_pk_scratch, ByteLens.PUBLIC_KEY_MAX);\n\n\t\t// parse public key\n\t\treturn BinaryResult.SUCCESS === g_wasm.ec_pubkey_parse(ip_ctx, ip_pk_lib, ip_pk_scratch, atu8_pk.length);\n\t};\n\n\t/**\n\t * Puts the given private key into program memory, runs the given callback, then zeroes out the key\n\t * @param atu8_sk - the private key\n\t * @param f_use - callback to use the key\n\t * @returns whatever the callback returns\n\t */\n\tconst with_sk = <\n\t\tw_return,\n\t>(atu8_sk: Uint8Array, f_use: () => w_return) => {\n\t\t// prep callback return\n\t\tlet w_return: w_return;\n\n\t\t// in case of any exception..\n\t\ttry {\n\t\t\t// copy input bytes into place\n\t\t\tput_bytes(atu8_sk, ip_sk, ByteLens.PRIVATE_KEY);\n\n\t\t\t// use private key\n\t\t\tw_return = f_use();\n\t\t}\n\t\tfinally {\n\t\t\t// zero-out private key\n\t\t\tATU8_HEAP.fill(0, ip_sk, ip_sk+ByteLens.PRIVATE_KEY);\n\t\t}\n\n\t\t// forward result\n\t\treturn w_return;\n\t};\n\n\t/**\n\t * Serializes the public key\n\t * @param b_uncompressed - whether or not the result should be in compressed form (33 bytes) or not (65 bytes)\n\t * @returns the public key as a buffer\n\t */\n\tconst get_pk = (b_uncompressed=false): Uint8Array => {\n\t\t// output length of public key\n\t\tconst nb_pk = b_uncompressed? ByteLens.PUBLIC_KEY_UNCOMPRESSED: ByteLens.PUBLIC_KEY_COMPRESSED;\n\n\t\t// // set target output length in little endian for WASM runtime\n\t\t// DV_HEAP.setUint32(ip_len, nb_pk, true);\n\n\t\t// set target output length (the Web has basically become LE-only)\n\t\tATU32_HEAP[ip32_len] = nb_pk;\n\n\t\t// prep compression flag\n\t\tconst xm_compression = b_uncompressed? Flags.COMPRESSION_UNCOMPRESSED: Flags.COMPRESSION_COMPRESSED;\n\n\t\t// serialize public key\n\t\tg_wasm.ec_pubkey_serialize(ip_ctx, ip_pk_scratch, ip_len, ip_pk_lib, xm_compression);\n\n\t\t// extract result\n\t\treturn ATU8_HEAP.slice(ip_pk_scratch, ip_pk_scratch+nb_pk);\n\t};\n\n\t/**\n\t * Asserts the private key is valid\n\t * @param atu8_sk - the private key (32 bytes)\n\t * @returns the valid private key, or throws if the caller somehow discovered an invalid sk\n\t */\n\tconst valid_sk = (atu8_sk: Uint8Array): Uint8Array => {\n\t\t// while using the private key, assert the length is valid and the point falls within curve order\n\t\tif(with_sk(atu8_sk, () => ByteLens.PRIVATE_KEY as number !== atu8_sk.length || BinaryResult.SUCCESS !== g_wasm.ec_seckey_verify(ip_ctx, ip_sk))) {\n\t\t\tthrow Error(S_REASON_INVALID_SK);\n\t\t}\n\n\t\t// return the valid sk\n\t\treturn atu8_sk;\n\t};\n\n\t/**\n\t * Creates a function to tweak a private key using either addition or multiplication\n\t * @param f_tweak - the tweak function\n\t * @param s_tag - the tag to use for error messages\n\t * @returns a tweak function\n\t */\n\tconst tweak_sk = (f_tweak: typeof g_wasm['ec_seckey_tweak_add'], s_tag: string) => (atu8_sk: Uint8Array, atu8_tweak: Uint8Array) => {\n\t\t// randomize context\n\t\trandomize_context();\n\n\t\t// copy input bytes into place\n\t\tput_bytes(atu8_sk, ip_sk, ByteLens.PRIVATE_KEY);\n\n\t\t// use message hash memory for tweak vector\n\t\tput_bytes(atu8_tweak, ip_msg_hash, ByteLens.MSG_HASH);\n\n\t\t// apply the given tweak to the private key\n\t\tif(BinaryResult.SUCCESS !== f_tweak(ip_ctx, ip_sk, ip_msg_hash)) {\n\t\t\t// manually clear the private key\n\t\t\tatu8_sk.fill(0);\n\n\t\t\tthrow Error('s'+s_tag+S_REASON_INVALID_SK);\n\t\t}\n\n\t\t// return tweaked private key\n\t\treturn ATU8_HEAP.slice(ip_sk, ip_sk+ByteLens.PRIVATE_KEY);\n\t};\n\n\t/**\n\t * Creates a function to tweak a public key using either addition or multiplication\n\t * @param f_tweak - the tweak function\n\t * @param s_tag - the tag to use for error messages\n\t * @returns a tweak function\n\t */\n\tconst tweak_pk = (f_tweak: typeof g_wasm['ec_pubkey_tweak_add'], s_tag: string) => (atu8_pk: Uint8Array, atu8_tweak: Uint8Array, b_uncompressed=false) => {\n\t\t// parse the public key\n\t\tif(!parse_pubkey(atu8_pk)) {\n\t\t\tthrow Error(S_TAG_ECDSA_VERIFY+S_REASON_INVALID_PK);\n\t\t}\n\n\t\t// copy input bytes into place\n\t\tput_bytes(atu8_pk, ip_pk_scratch, ByteLens.PUBLIC_KEY_MAX);\n\n\t\t// use message hash memory for tweak vector\n\t\tput_bytes(atu8_tweak, ip_msg_hash, ByteLens.MSG_HASH);\n\n\t\t// apply the given tweak to the public key\n\t\tif(BinaryResult.SUCCESS !== f_tweak(ip_ctx, ip_pk_lib, ip_msg_hash)) {\n\t\t\tthrow Error('p'+s_tag+S_REASON_INVALID_PK);\n\t\t}\n\n\t\t// return tweaked public key\n\t\treturn get_pk(b_uncompressed);\n\t};\n\n\treturn {\n\t\tgen_sk: () => valid_sk(crypto.getRandomValues(bytes(ByteLens.PRIVATE_KEY))),\n\n\t\tvalid_sk,\n\n\t\tsk_to_pk(atu8_sk, b_uncompressed=false) {\n\t\t\t// randomize context\n\t\t\trandomize_context();\n\n\t\t\t// while using the private key, compute its corresponding public key; from the docs:\n\t\t\tif(BinaryResult.SUCCESS !== with_sk(atu8_sk, () => g_wasm.ec_pubkey_create(ip_ctx, ip_pk_lib, ip_sk))) {\n\t\t\t\tthrow Error('sk_to_pk: '+S_REASON_INVALID_SK);\n\t\t\t}\n\n\t\t\t// serialize the public key\n\t\t\treturn get_pk(b_uncompressed);\n\t\t},\n\n\t\tsign(atu8_sk, atu8_hash, atu8_ent=random_32()) {\n\t\t\t// randomize context\n\t\t\trandomize_context();\n\n\t\t\t// copy message hash bytes into place\n\t\t\tput_bytes(atu8_hash, ip_msg_hash, ByteLens.MSG_HASH);\n\n\t\t\t// copy entropy bytes into place\n\t\t\tput_bytes(atu8_ent, ip_ent, ByteLens.NONCE_ENTROPY);\n\n\t\t\t// while using the private key, sign the given message hash\n\t\t\tif(BinaryResult.SUCCESS !== with_sk(atu8_sk, () => g_wasm.ecdsa_sign_recoverable(\n\t\t\t\tip_ctx,\n\t\t\t\tip_sig_rcvr_lib,\n\t\t\t\tip_msg_hash,\n\t\t\t\tip_sk,\n\t\t\t\t0 as PointerNonceFn,\n\t\t\t\tip_ent\n\t\t\t))) {\n\t\t\t\tthrow Error('ECDSA sign: '+S_REASON_INVALID_SK);\n\t\t\t}\n\n\t\t\t// serialize the signature in compact form as `r || s` (64 bytes)\n\t\t\tg_wasm.ecdsa_recoverable_signature_serialize_compact(ip_ctx, ip_sig_scratch, ip_v, ip_sig_rcvr_lib);\n\n\t\t\t// return serialized signature\n\t\t\treturn [\n\t\t\t\tATU8_HEAP.slice(ip_sig_scratch, ip_sig_scratch+ByteLens.ECDSA_SIG_COMPACT),\n\t\t\t\tATU8_HEAP.slice(ip_v, ip_v+4)[3] as RecoveryValue, // terminal byte of 32-bit uint\n\t\t\t];\n\t\t},\n\n\t\tverify(atu8_signature, atu8_hash, atu8_pk) {\n\t\t\t// copy signature bytes into place\n\t\t\tput_bytes(atu8_signature, ip_sig_scratch, ByteLens.ECDSA_SIG_COMPACT);\n\n\t\t\t// copy message hash bytes into place\n\t\t\tput_bytes(atu8_hash, ip_msg_hash, ByteLens.MSG_HASH);\n\n\t\t\t// parse the public key\n\t\t\tif(!parse_pubkey(atu8_pk)) {\n\t\t\t\tthrow Error(S_TAG_ECDSA_VERIFY+S_REASON_INVALID_PK);\n\t\t\t}\n\n\t\t\t// parse the signature\n\t\t\tif(BinaryResult.SUCCESS !== g_wasm.ecdsa_signature_parse_compact(ip_ctx, ip_sig_lib, ip_sig_scratch)) {\n\t\t\t\tthrow Error(S_TAG_ECDSA_VERIFY+S_REASON_UNPARSEABLE_SIG);\n\t\t\t}\n\n\t\t\t// verify the signature\n\t\t\treturn BinaryResult.SUCCESS === g_wasm.ecdsa_verify(ip_ctx, ip_sig_lib, ip_msg_hash, ip_pk_lib);\n\t\t},\n\n\t\trecover(atu8_signature, atu8_hash, xc_recovery, b_uncompressed=false) {\n\t\t\t// copy signature bytes into place\n\t\t\tput_bytes(atu8_signature, ip_sig_scratch, ByteLens.ECDSA_SIG_COMPACT);\n\n\t\t\t// parse the recoverable signature\n\t\t\tif(BinaryResult.SUCCESS !== g_wasm.ecdsa_recoverable_signature_parse_compact(ip_ctx, ip_sig_rcvr_lib, ip_sig_scratch, xc_recovery)) {\n\t\t\t\tthrow Error(S_TAG_ECDSA_VERIFY+S_REASON_UNPARSEABLE_SIG);\n\t\t\t}\n\n\t\t\t// copy message hash bytes into place\n\t\t\tput_bytes(atu8_hash, ip_msg_hash, ByteLens.MSG_HASH);\n\n\t\t\t// recover the public key\n\t\t\tif(BinaryResult.SUCCESS !== g_wasm.ecdsa_recover(ip_ctx, ip_pk_lib, ip_sig_rcvr_lib, ip_msg_hash)) {\n\t\t\t\tthrow Error(S_TAG_ECDSA_VERIFY+'Invalid signature');\n\t\t\t}\n\n\t\t\t// return recovered public key\n\t\t\treturn get_pk(b_uncompressed);\n\t\t},\n\n\t\tecdh(atu8_sk, atu8_pk) {\n\t\t\t// parse public key\n\t\t\tif(!parse_pubkey(atu8_pk)) throw Error(S_TAG_ECDH+S_REASON_INVALID_PK);\n\n\t\t\t// start using private key\n\t\t\treturn with_sk(atu8_sk, () => {\n\t\t\t\t// perform ecdh computation\n\t\t\t\tif(BinaryResult.SUCCESS !== g_wasm.ecdh(ip_ctx, ip_sk_shared, ip_pk_lib, ip_sk)) {\n\t\t\t\t\tthrow Error(S_TAG_ECDH+S_REASON_INVALID_SK);\n\t\t\t\t}\n\n\t\t\t\t// return copy of result bytes\n\t\t\t\treturn ATU8_HEAP.slice(ip_sk_shared, ip_sk_shared+ByteLens.ECDH_SHARED_SK);\n\t\t\t});\n\t\t},\n\n\t\ttweak_sk_add: tweak_sk(g_wasm.ec_seckey_tweak_add, S_TAG_TWEAK_ADD),\n\n\t\ttweak_sk_mul: tweak_sk(g_wasm.ec_seckey_tweak_mul, S_TAG_TWEAK_MUL),\n\n\t\ttweak_pk_add: tweak_pk(g_wasm.ec_pubkey_tweak_add, S_TAG_TWEAK_ADD),\n\n\t\ttweak_pk_mul: tweak_pk(g_wasm.ec_pubkey_tweak_mul, S_TAG_TWEAK_MUL),\n\t};\n};\n\n","import type {RecoveryValue} from '../api/secp256k1-types';\n\nimport {bytes_to_hex, hex_to_bytes, sha256, text_to_bytes} from '@blake.regalia/belt';\n\nimport {WasmSecp256k1} from '../api/secp256k1';\n\nconst elem = (si_id: string) => document.getElementById(si_id) as d_type;\n\nconst dm_sk = elem('sk');\nconst dm_pk = elem('pk');\nconst dm_v = elem('v');\nconst dm_msg = elem('msg');\nconst dm_hash = elem('hash');\nconst dm_sig_r = elem('sig_r');\nconst dm_sig_s = elem('sig_s');\nconst dm_verified = elem('verified');\n\n(async function load() {\n\tconst d_res = await fetch('out/secp256k1.wasm');\n\tconst k_secp = await WasmSecp256k1(d_res);\n\n\tlet atu8_sk: Uint8Array;\n\tlet atu8_pk: Uint8Array;\n\tlet atu8_hash: Uint8Array;\n\tlet atu8_sig: Uint8Array;\n\tlet xc_recovery: RecoveryValue;\n\n\tfunction sk_err(s_msg: string) {\n\t\tdm_pk.value = s_msg;\n\t\tdm_hash.value = dm_sig_r.value = dm_sig_s.value = dm_verified.value = '';\n\t}\n\n\tconst is_hex = (sb16: string) => /^[a-f0-9]+$/i.test(sb16);\n\n\tfunction reload_sk() {\n\t\tconst sb16_sk = dm_sk.value;\n\t\tif(sb16_sk.length < 64) {\n\t\t\treturn sk_err('Private key too short');\n\t\t}\n\t\telse if(sb16_sk.length > 64) {\n\t\t\treturn sk_err('Private key too long');\n\t\t}\n\t\telse if(!is_hex(sb16_sk)) {\n\t\t\treturn sk_err('Not hexadecimal');\n\t\t}\n\n\t\tatu8_sk = hex_to_bytes(sb16_sk);\n\n\t\ttry {\n\t\t\tatu8_pk = k_secp.sk_to_pk(atu8_sk);\n\t\t}\n\t\tcatch(e_convert) {\n\t\t\treturn sk_err((e_convert as Error).message);\n\t\t}\n\n\t\tdm_pk.value = bytes_to_hex(atu8_pk);\n\n\t\tvoid reload_sig();\n\t}\n\n\tasync function reload_sig() {\n\t\tatu8_hash = await sha256(text_to_bytes(dm_msg.value));\n\n\t\tdm_hash.value = bytes_to_hex(atu8_hash);\n\n\t\ttry {\n\t\t\t[atu8_sig, xc_recovery] = k_secp.sign(atu8_sk, atu8_hash);\n\t\t}\n\t\tcatch(e_convert) {\n\t\t\treturn dm_sig_r.value = (e_convert as Error).message;\n\t\t}\n\n\t\tdm_sig_r.value = bytes_to_hex(atu8_sig.subarray(0, 32));\n\t\tdm_sig_s.value = bytes_to_hex(atu8_sig.subarray(32));\n\t\tdm_v.value = xc_recovery+'';\n\n\t\ttry {\n\t\t\tk_secp.verify(atu8_sig, atu8_hash, atu8_pk);\n\t\t}\n\t\tcatch(e_verify) {\n\t\t\treturn dm_verified.value = (e_verify as Error).message;\n\t\t}\n\n\t\tdm_verified.value = 'Yes';\n\t}\n\n\t// generate random private key\n\tatu8_sk = k_secp.gen_sk();\n\n\t// set value in UI\n\tdm_sk.value = bytes_to_hex(atu8_sk);\n\n\t// bind to input events\n\tdm_sk.addEventListener('input', reload_sk);\n\tdm_msg.addEventListener('input', reload_sig);\n\n\t// init\n\treload_sk();\n})();\n"],"names":["ByteLens","Flags","BinaryResult"],"mappings":"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","x_google_ignoreList":[0]} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../../node_modules/.pnpm/@blake.regalia+belt@0.40.1/node_modules/@blake.regalia/belt/dist/mjs/data.js","../../src/api/emsimp.ts","../../src/api/secp256k1-types.ts","../../src/gen/wasm.ts","../../src/api/secp256k1.ts","../../src/demo/webapp.ts"],"sourcesContent":["import { XG_8, is_array, is_dict_es, is_string, entries, from_entries, die, try_sync } from './belt.js';\nexport const SI_HASH_ALGORITHM_SHA256 = 'SHA-256';\nexport const SI_HASH_ALGORITHM_SHA384 = 'SHA-384';\nexport const SI_HASH_ALGORITHM_SHA512 = 'SHA-512';\n// /**\n// * Alias of `Math.max`\n// */\n// export const max = Math.max;\n// /**\n// * Alias of `Math.min`\n// */\n// export const min = Math.min;\n// /**\n// * Alias of `Math.abs`\n// */\n// export const abs = Math.abs;\n/**\n * Returns the lesser of the two `bigint` values\n */\nexport const bigint_lesser = (xg_a, xg_b) => xg_a < xg_b ? xg_a : xg_b;\n/**\n * Returns the greater of the two `bigint` values\n */\nexport const bigint_greater = (xg_a, xg_b) => xg_a > xg_b ? xg_a : xg_b;\n/**\n * Returns the absolute value of the given `bigint` value, or the absolute value of the delta between\n * the two given values if the 2nd argument is provided\n */\nexport const bigint_abs = (xg_a, xg_b = 0n, xg_delta = xg_a - xg_b) => xg_delta < 0n ? -xg_delta : xg_delta;\n/**\n * Computes the maximum value among a list of `bigint` values\n * @param a_values - list of values\n * @returns the max value\n */\nexport const bigint_max = (a_values) => a_values.reduce(bigint_greater, 0n);\n/**\n * Computes the minimunm value among a list of `bigint` values\n * @param a_values - list of values\n * @returns the min value\n */\nexport const bigint_min = (a_values) => a_values.reduce(bigint_lesser, 0n);\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst S_UUID_V4 = 'xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx';\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst R_UUID_V4 = /[xy]/g;\n// @ts-expect-error in case crypto global is not defined\nexport const uuid_v4 = globalThis.crypto?.randomUUID ? () => crypto.randomUUID() : () => {\n let xt_now = Date.now();\n if ('undefined' !== typeof performance)\n xt_now += performance.now();\n return S_UUID_V4.replace(R_UUID_V4, (s) => {\n const x_r = (xt_now + (Math.random() * 16)) % 16 | 0;\n xt_now = Math.floor(xt_now / 16);\n return ('x' === s ? x_r : (x_r & 0x3) | 0x8).toString(16);\n });\n};\n/**\n * Creates a new function that wraps the given function in a `try_sync` and returns the result without throwing\n * @param f_attempt - the function to attempt\n * @returns\n */\nexport const safely_sync = (f_attempt) => (...a_args) => try_sync(_ => f_attempt(...a_args))[0];\n/**\n * Typed alias to `JSON.stringify`\n */\nexport const stringify_json = JSON.stringify;\n/**\n * Strongly typed alias to `JSON.parse`\n */\nexport const parse_json = JSON.parse;\n/**\n * Attempts to parse the given JSON string, returning `undefined` on parse error instead of throwing\n * @param sx_json\n * @returns\n */\nexport const parse_json_safe = (sx_json) => try_sync(_ => parse_json(sx_json))[0];\n/**\n * @deprecated Use {@link parse_json_safe} instead.\n */\nexport const safe_json = parse_json_safe;\n/**\n * Converts a JSON object (in memory) into its canonical form. Must be valid JSON with no cycles\n * and must not contain any non-JSON values. Objects are sorted by keys, arrays are not sorted\n * since order matters.\n * @param w_json JSON-compatible value to canonicalize\n * @returns canonicalized JSON value\n */\nexport const canonicalize_json = (w_json) => {\n // JSON object\n if (is_dict_es(w_json)) {\n // sort all keys\n const h_sorted = from_entries(entries(w_json).sort((a_a, a_b) => a_a[0] < a_b[0] ? -1 : 1));\n // traverse on children\n for (const si_key in h_sorted) {\n h_sorted[si_key] = canonicalize_json(h_sorted[si_key]);\n }\n w_json = h_sorted;\n }\n // JSON array\n else if (is_array(w_json)) {\n w_json = w_json.map(w_item => canonicalize_json(w_item));\n }\n // boolean, number, string, or null\n return w_json;\n};\n/**\n * Helps reduce codesize\n * @param a_args\n * @returns\n */\nexport const bytes = (...a_args) => new Uint8Array(...a_args);\n/**\n * Helps reduce codesize\n * @param a_args\n * @returns\n */\nexport const dataview = (...a_args) => new DataView(...a_args);\n/**\n * Performs SHA-256 hash on the given data.\n * @param atu8_data data to hash\n * @returns the hash digest\n */\nexport const sha256 = async (atu8_data) => bytes(await crypto.subtle.digest(SI_HASH_ALGORITHM_SHA256, atu8_data));\n/**\n * Performs SHA-256(SHA-256(data))\n * @param atu8_data data to hash\n * @returns the hash digest\n */\nexport const sha256d = async (atu8_data) => {\n const atu8_1 = await sha256(atu8_data);\n const atu8_2 = await sha256(atu8_1);\n zero_out(atu8_1);\n return atu8_2;\n};\n/**\n * Performs SHA-384 hash on the given data.\n * @param atu8_data data to hash\n * @returns the hash digest\n */\nexport const sha384 = async (atu8_data) => bytes(await crypto.subtle.digest(SI_HASH_ALGORITHM_SHA384, atu8_data));\n/**\n * Performs SHA-512 hash on the given data.\n * @param atu8_data data to hash\n * @returns the hash digest\n */\nexport const sha512 = async (atu8_data) => bytes(await crypto.subtle.digest(SI_HASH_ALGORITHM_SHA512, atu8_data));\n/**\n * Imports a {@link CryptoKey} from raw bytes\n * @param atu8_sk - the key's raw bytes\n * @param z_algo - the algorithm argument passed to `SubtleCrypto#importKey()`\n * @param da_usages - key usages argument\n * @returns the imported {@link CryptoKey}\n */\nexport const import_key = (atu8_sk, z_algo, da_usages, b_extractable = false) => crypto.subtle.importKey('raw', atu8_sk, z_algo, b_extractable, da_usages);\n/**\n * Performs HMAC signing of the given message, **not the digest**.\n * @param atu8_sk private key\n * @param atu8_message message to sign, **not the digest**.\n * @returns HMAC signature\n */\nexport const hmac = async (atu8_sk, atu8_message, si_algo = SI_HASH_ALGORITHM_SHA256) => {\n // import signing private key\n const dk_sign = await import_key(atu8_sk, {\n name: 'HMAC',\n hash: { name: si_algo },\n }, ['sign']);\n // construct hmac signature\n return bytes(await crypto.subtle.sign('HMAC', dk_sign, atu8_message));\n};\n/**\n * Performs HKDF on the given IKM\n * @param atu8_ikm - the input key material bytes\n * @param ni_bits - number of bits to target\n * @param atu8_salt - salt bytes\n * @param atu8_info - optional info bytes\n * @param si_algo - hashing algorithm to use\n */\nexport const hkdf = async (atu8_ikm, ni_bits, atu8_salt, atu8_info = bytes(), si_algo = SI_HASH_ALGORITHM_SHA256) => {\n // import deriving key\n const dk_derive = await import_key(atu8_ikm, 'HKDF', ['deriveBits']);\n // derive the bits\n return bytes(await crypto.subtle.deriveBits({\n name: 'HKDF',\n hash: si_algo,\n salt: atu8_salt,\n info: atu8_info,\n }, dk_derive, ni_bits));\n};\n/**\n * Wipe the contents of a buffer so that sensitive data does not outlive garbage collection.\n */\nexport const zero_out = (atu8_data) => {\n // overwrite the contents\n atu8_data.fill(0);\n // make sure the engine does not optimize away the above memory wipe instruction\n // @ts-expect-error signature IS compatible with both types\n if (0 !== atu8_data.reduce((c_sum, x_value) => c_sum + x_value, 0))\n die('Failed to zero out sensitive memory region');\n};\nexport const encode_length_prefix_u16 = (atu8_data) => {\n // prep buffer to serialize encoded extension\n const atu8_encoded = concat([\n bytes(2), // 2 bytes for length prefix\n atu8_data,\n ]);\n // use big-endian to encode length prefix\n new DataView(atu8_encoded.buffer).setUint16(atu8_encoded.byteOffset, atu8_data.byteLength, false);\n // return encoded buffer\n return atu8_encoded;\n};\nexport const decode_length_prefix_u16 = (atu8_encoded) => {\n // use big-endian to decode length prefix\n const ib_terminus = new DataView(atu8_encoded.buffer).getUint16(atu8_encoded.byteOffset, false) + 2;\n // return decoded payload buffer and everything after it\n return [atu8_encoded.subarray(2, ib_terminus), atu8_encoded.subarray(ib_terminus)];\n};\n/**\n * UTF-8 encodes the given text to an Uint8Array.\n * @param s_text text to encode\n * @returns UTF-8 encoded Uint8Array\n */\nexport const text_to_bytes = (s_text) => new TextEncoder().encode(s_text);\n/**\n * UTF-8 decodes the given Uint8Array to text.\n * @param atu8_text UTF-8 encoded data to decode\n * @returns text\n */\nexport const bytes_to_text = (atu8_text) => new TextDecoder().decode(atu8_text);\n/**\n * Converts the given base64-encoded string to a buffer, then UTF-8 decodes it.\n * @param sx_buffer input base64-encoded string\n * @returns text\n */\nexport const base64_to_text = (sx_buffer) => bytes_to_text(base64_to_bytes(sx_buffer));\n/**\n * UTF-8 encodes the given text, then converts it to a base64-encoded string.\n * @param s_text text to encode\n * @returns output base64-encoded string\n */\nexport const text_to_base64 = (s_text) => bytes_to_base64(text_to_bytes(s_text));\n/**\n * Attempts to JSON stringify the given primitive/object and subsequently UTF-8 encode it.\n * @param w_json JSON-compatible value to encode\n * @returns UTF-8 encoded Uint8Array\n */\nexport const json_to_bytes = (w_json) => text_to_bytes(stringify_json(w_json));\n/**\n * UTF-8 decodes the given Uint8Array and subsequently attempts to JSON parse it.\n * @param atu8_json UTF-8 encoded JSON string data\n * @returns parsed JSON value\n */\nexport const bytes_to_json = (atu8_json) => parse_json(bytes_to_text(atu8_json));\n/**\n * Encodes the given 32-bit unsigned integer in big-endian format to a new buffer.\n * @param xg_uint\n * @returns\n */\nexport const uint32_to_bytes_be = (xg_uint) => {\n // prep array buffer\n const ab_buffer = new Uint32Array(1).buffer;\n // write to buffer\n new DataView(ab_buffer).setUint32(0, Number(xg_uint), false);\n // wrap as uint8array\n return bytes(ab_buffer);\n};\n/**\n * Decodes a 32-bit unsigned integer in big-endian format from a buffer (optionally at the given position).\n * @param n_uint\n * @returns\n */\nexport const bytes_to_uint32_be = (atu8_buffer, ib_offset = 0) => new DataView(atu8_buffer.buffer).getUint32(atu8_buffer.byteOffset + ib_offset, false);\n/**\n * Encodes the given unsigned bigint in big-endian format to a new 32-byte buffer, or whatever size is given.\n * @param xg_value - the value to encode\n * @param nb_size - size of the buffer to create\n * @returns the encoded buffer\n */\nexport const biguint_to_bytes_be = (xg_value, nb_size = 32) => {\n // prep buffer of the appropriate size\n let atu8_out = bytes(nb_size);\n let ib_write = nb_size;\n while (xg_value > 0n) {\n atu8_out[--ib_write] = Number(xg_value & 0xffn);\n xg_value >>= XG_8;\n }\n return atu8_out;\n};\n/**\n * @deprecated Use {@link biguint_to_bytes_be} instead.\n */\nexport const bigint_to_bytes_be = biguint_to_bytes_be;\n/**\n * Decodes an unsigned bigint in big-endian format from a buffer\n * @param atu8_bytes\n * @returns\n */\nexport const bytes_to_biguint_be = (atu8_bytes) => atu8_bytes.reduce((xg_out, xb_value) => (xg_out << XG_8) | BigInt(xb_value), 0n);\n/**\n * @deprecated Use {@link bytes_to_biguint_be} instead.\n */\nexport const bytes_to_bigint_be = bytes_to_biguint_be;\n/**\n * Concatenate a sequence of Uint8Arrays.\n * @param a_buffers the data to concatenate in order\n * @returns the concatenated output Uint8Array\n */\nexport const concat = (a_buffers) => {\n const nb_out = a_buffers.reduce((c_bytes, atu8_each) => c_bytes + atu8_each.byteLength, 0);\n const atu8_out = bytes(nb_out);\n let ib_write = 0;\n for (const atu8_each of a_buffers) {\n atu8_out.set(atu8_each, ib_write);\n ib_write += atu8_each.byteLength;\n }\n return atu8_out;\n};\n/**\n * Concatenate two Uint8Arrays together.\n * @param atu8_buffer_a left side\n * @param atu8_buffer_b right side\n * @returns the concatenated output Uint8Array\n */\nexport const concat2 = (atu8_a, atu8_b) => {\n const atu8_out = bytes(atu8_a.length + atu8_b.length);\n atu8_out.set(atu8_a);\n atu8_out.set(atu8_b, atu8_a.length);\n return atu8_out;\n};\n// // cache function reference\n// const sfcc = String.fromCharCode;\n/**\n * Converts the given buffer to a hex string format in lowercase.\n * @param atu8_buffer input buffer\n * @returns output hex string\n */\nexport const bytes_to_hex = (atu8_buffer) => atu8_buffer.reduce((s_out, xb_byte) => s_out + xb_byte.toString(16).padStart(2, '0'), '');\n/**\n * Converts the given hex string into a buffer.\n * @param sx_hex input hex string\n * @returns output buffer\n */\nexport const hex_to_bytes = (sx_hex) => bytes(sx_hex.length / 2)\n .map((xb_ignore, i_char) => parseInt(sx_hex.slice(i_char * 2, (i_char * 2) + 2), 16));\n/**\n * Converts the given buffer to a base64-encoded string using minimal code but at the expense of performance.\n * @param atu8_buffer input buffer\n * @returns output base64-encoded string\n */\nexport const bytes_to_base64_slim = (atu8_buffer) => btoa(Array.from(atu8_buffer).map(xb => String.fromCharCode(xb)).join(''));\n/**\n * Converts the given base64-encoded string to a buffer using minimal code but at the expense of performance.\n * @param sx_buffer input base64-encoded string\n * @returns output buffer\n */\nexport const base64_to_bytes_slim = (sx_buffer) => bytes(atob(sx_buffer.replace(/=+$/, '')).split('').map(s => s.charCodeAt(0)));\nconst SX_CHARS_BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// adapted from \n/* eslint-disable no-multi-spaces */\n/**\n * Converts the given buffer to a base64-encoded string.\n * @param atu8_buffer input buffer\n * @returns output base64-encoded string\n */\nexport const bytes_to_base64 = (atu8_buffer) => {\n let s_out = '';\n const nb_buffer = atu8_buffer.byteLength;\n const nb_remainder = nb_buffer % 3;\n const nb_main = nb_buffer - nb_remainder;\n let xb_a = 0;\n let xb_b = 0;\n let xb_c = 0;\n let xb_d = 0;\n let xn_chunk = 0;\n // Main loop deals with bytes in chunks of 3\n for (let ib_offset = 0; ib_offset < nb_main; ib_offset += 3) {\n // Combine the three bytes into a single integer\n xn_chunk = (atu8_buffer[ib_offset] << 16) | (atu8_buffer[ib_offset + 1] << 8) | atu8_buffer[ib_offset + 2];\n // Use bitmasks to extract 6-bit segments from the triplet\n xb_a = (xn_chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18\n xb_b = (xn_chunk & 258048) >> 12; // 258048 = (2^6 - 1) << 12\n xb_c = (xn_chunk & 4032) >> 6; // 4032 = (2^6 - 1) << 6\n xb_d = xn_chunk & 63; // 63 = 2^6 - 1\n // Convert the raw binary segments to the appropriate ASCII encoding\n s_out += SX_CHARS_BASE64[xb_a] + SX_CHARS_BASE64[xb_b] + SX_CHARS_BASE64[xb_c] + SX_CHARS_BASE64[xb_d];\n }\n // Deal with the remaining bytes and padding\n if (1 === nb_remainder) {\n xn_chunk = atu8_buffer[nb_main];\n xb_a = (xn_chunk & 252) >> 2; // 252 = (2^6 - 1) << 2\n // Set the 4 least significant bits to zero\n xb_b = (xn_chunk & 3) << 4; // 3 = 2^2 - 1\n s_out += SX_CHARS_BASE64[xb_a] + SX_CHARS_BASE64[xb_b] + '==';\n }\n else if (2 === nb_remainder) {\n xn_chunk = (atu8_buffer[nb_main] << 8) | atu8_buffer[nb_main + 1];\n xb_a = (xn_chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10\n xb_b = (xn_chunk & 1008) >> 4; // 1008 = (2^6 - 1) << 4\n // Set the 2 least significant bits to zero\n xb_c = (xn_chunk & 15) << 2; // 15 = 2^4 - 1\n s_out += SX_CHARS_BASE64[xb_a] + SX_CHARS_BASE64[xb_b] + SX_CHARS_BASE64[xb_c] + '=';\n }\n return s_out;\n};\n/* eslint-enable */\n/**\n * Converts the given base64-encoded string to a buffer.\n * @param sb64_data input base64-encoded string\n * @returns output buffer\n */\nexport const base64_to_bytes = (sb64_data) => {\n // remove padding from string\n sb64_data = sb64_data.replace(/=+$/, '');\n // a buffer to store decoded sextets\n let xb_work = 0;\n // number of bits in the buffer\n let nb_buffer = 0;\n // prep output values\n const a_out = [];\n // each character\n for (const s_char of sb64_data) {\n // decode character value\n const xb_char = SX_CHARS_BASE64.indexOf(s_char);\n // invalid base64-encoding\n if (-1 === xb_char)\n die('Invalid base64 string');\n // add 6 bits from index to buffer\n xb_work = (xb_work << 6) | xb_char;\n // increase size of buffer which checking if a whole byte exists in the buffer\n if ((nb_buffer += 6) >= 8) {\n // move byte out of buffer\n a_out.push(xb_work >>> (nb_buffer -= 8));\n // trim the buffer\n xb_work &= (1 << nb_buffer) - 1;\n }\n }\n return bytes(a_out);\n};\n/**\n * Converts the given raw string (no encoding) to bytes.\n * @param sx_buffer input string\n * @returns output buffer\n */\nexport const string8_to_bytes = (sx_buffer) => {\n const nl_chars = sx_buffer.length;\n const atu8_buffer = bytes(nl_chars);\n for (let i_read = 0; i_read < nl_chars; i_read++) {\n atu8_buffer[i_read] = sx_buffer.charCodeAt(i_read);\n }\n return atu8_buffer;\n};\n/**\n * Converts the given bytes to a raw string (no encoding).\n * @param at8u_bytes input bytes\n * @returns output string\n */\nexport const bytes_to_string8 = (atu8_bytes) => {\n let sx_buffer = '';\n for (const xb_value of atu8_bytes) {\n sx_buffer += String.fromCharCode(xb_value);\n }\n return sx_buffer;\n};\n// inspired by \n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst SX_CHARS_BASE93 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&'()*+,-./:;<=>?@[]^_`{|}~ \";\n/**\n * Converts the given buffer to a base93-encoded string.\n * @param atu8_buffer input buffer\n * @returns output base93-encoded string\n */\nexport const bytes_to_base93 = (atu8_buffer) => {\n let s_out = '';\n const nb_buffer = atu8_buffer.byteLength;\n let xb_encode = 0;\n let ni_shift = 0;\n for (let ib_each = 0; ib_each < nb_buffer; ib_each++) {\n const xb_each = atu8_buffer[ib_each];\n xb_encode |= xb_each << ni_shift;\n ni_shift += 8;\n if (ni_shift > 13) {\n let xb_local = xb_encode & 0x1fff;\n if (xb_local > 456) {\n xb_encode >>= 13;\n ni_shift -= 13;\n }\n else {\n xb_local = xb_encode & 0x3fff;\n xb_encode >>= 14;\n ni_shift -= 14;\n }\n s_out += SX_CHARS_BASE93[xb_local % 93] + SX_CHARS_BASE93[(xb_local / 93) | 0];\n }\n }\n if (ni_shift > 0) {\n s_out += SX_CHARS_BASE93[xb_encode % 93];\n if (ni_shift > 7 || xb_encode > 92) {\n s_out += SX_CHARS_BASE93[(xb_encode / 93) | 0];\n }\n }\n return s_out;\n};\n/**\n * Converts the given base93-encoded string to a buffer.\n * @param sb93_data input base93-encoded string\n * @returns output buffer\n */\nexport const base93_to_bytes = (sb93_data) => {\n const a_out = [];\n let xb_decode = 0;\n let ni_shift = 0;\n let xb_work = -1;\n for (const s_char of sb93_data) {\n const xb_char = SX_CHARS_BASE93.indexOf(s_char);\n if (-1 === xb_char)\n die('Invalid base93 string');\n if (-1 === xb_work) {\n xb_work = xb_char;\n continue;\n }\n xb_work += xb_char * 93;\n xb_decode |= xb_work << ni_shift;\n ni_shift += (xb_work & 0x1fff) > 456 ? 13 : 14;\n do {\n a_out.push(xb_decode & 0xff);\n xb_decode >>= 8;\n ni_shift -= 8;\n } while (ni_shift > 7);\n xb_work = -1;\n }\n if (-1 !== xb_work)\n a_out.push(xb_decode | (xb_work << ni_shift));\n return Uint8Array.from(a_out.slice(0, Math.ceil(sb93_data.length * 7 / 8)));\n};\n// inspired by \n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst SX_CHARS_BASE58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst A_CHARS_BASE58 = /*#__PURE__*/ (() => {\n const a_out = Array(256).fill(-1);\n let i_char = 0;\n // eslint-disable-next-line prefer-const\n for (let s_char of SX_CHARS_BASE58) {\n a_out[s_char.charCodeAt(0)] = i_char++;\n }\n return a_out;\n})();\nexport const bytes_to_base58 = (atu8_buffer) => {\n const a_out = [];\n for (const xb_char of atu8_buffer) {\n let xb_carry = xb_char;\n for (let ib_sweep = 0; ib_sweep < a_out.length; ++ib_sweep) {\n const xb_value = (A_CHARS_BASE58[a_out[ib_sweep]] << 8) + xb_carry;\n a_out[ib_sweep] = SX_CHARS_BASE58.charCodeAt(xb_value % 58);\n xb_carry = (xb_value / 58) | 0;\n }\n while (xb_carry) {\n a_out.push(SX_CHARS_BASE58.charCodeAt(xb_carry % 58));\n xb_carry = (xb_carry / 58) | 0;\n }\n }\n for (const xb_char of atu8_buffer) {\n if (xb_char) {\n break;\n }\n else {\n a_out.push('1'.charCodeAt(0));\n }\n }\n a_out.reverse();\n return String.fromCharCode(...a_out);\n};\nexport const base58_to_bytes = (sb58_buffer) => {\n if (!sb58_buffer || !is_string(sb58_buffer)) {\n die(`Expected base58 string but got “${sb58_buffer}”`);\n }\n const m_invalid = sb58_buffer.match(/[IOl0]/gmu);\n if (m_invalid) {\n die(`Invalid base58 character “${String(m_invalid)}”`);\n }\n const m_lz = sb58_buffer.match(/^1+/gmu);\n const nl_psz = m_lz ? m_lz[0].length : 0;\n const nb_out = (((sb58_buffer.length - nl_psz) * (Math.log(58) / Math.log(256))) + 1) >>> 0;\n return bytes([\n ...bytes(nl_psz),\n ...sb58_buffer\n .match(/.{1}/gmu)\n .map(sxb58 => SX_CHARS_BASE58.indexOf(sxb58))\n .reduce((atu8_out, ib_pos) => atu8_out.map((xb_char) => {\n const xb_tmp = (xb_char * 58) + ib_pos;\n ib_pos = xb_tmp >> 8;\n return xb_tmp;\n }), bytes(nb_out))\n .reverse()\n .filter((b_last => xb_each => (b_last = b_last || !!xb_each))(false)),\n ]);\n};\n/**\n * Cryptographically strong random bytes\n * @param nb_len - number of bytes to fill\n */\nexport const crypto_random_bytes = (nb_len = 32) => crypto.getRandomValues(bytes(nb_len));\n/**\n * Cryptographically strong random number in the range [0, 1)\n */\nexport const crypto_random_unit_double = () => crypto_random_bytes(1)[0] / (2 ** 32);\n/**\n * @deprecated Replace with {@link crypto_random_unit_double}\n */\nexport const crypto_random = crypto_random_unit_double;\n/**\n * Generate a cryptographically strong random int within a given range\n */\nexport const crypto_random_int = (x_a, x_b = 0) => {\n const x_min = Math.floor(Math.min(x_a, x_b));\n const x_max = Math.ceil(Math.max(x_a, x_b));\n // confine to range\n return Math.floor(crypto_random_unit_double() * (x_max - x_min)) + x_min;\n};\n//# sourceMappingURL=data.js.map","import type {ImportMapper} from '../types';\n\nexport const emsimp = (f_map_imports: ImportMapper, s_tag: string) => {\n\ts_tag += ': ';\n\n\tlet AB_HEAP: ArrayBuffer;\n\tlet ATU8_HEAP: Uint8Array;\n\tlet ATU32_HEAP: Uint32Array;\n\n\t// eslint-disable-next-line no-console\n\tconst console_out = (s_channel: Extract, s_out: string) => console[s_channel](s_tag+s_out.replace(/\\0/g, '\\n'));\n\n\tlet s_error = '';\n\n\tconst h_fds: Record void> = {\n\t\t// stdout\n\t\t1(s_out) {\n\t\t\tconsole_out('debug', s_out);\n\t\t},\n\n\t\t// stderr\n\t\t2(s_out) {\n\t\t\tconsole_out('error', s_error=s_out);\n\t\t},\n\t};\n\n\tconst g_imports = f_map_imports({\n\t\tabort() {\n\t\t\tthrow Error(s_tag+(s_error || 'An unknown error occurred'));\n\t\t},\n\n\t\tmemcpy: (ip_dst, ip_src, nb_size) => ATU8_HEAP.copyWithin(ip_dst, ip_src, ip_src+nb_size),\n\n\t\tresize(nb_size) {\n\t\t\tthrow Error(s_tag+'Out of memory');\n\t\t},\n\n\t\twrite(i_fd, ip_iov, nl_iovs, ip_written) {\n\t\t\t// output string\n\t\t\tlet s_out = '';\n\n\t\t\t// track number of bytes read from buffers\n\t\t\tlet cb_read = 0;\n\n\t\t\t// each pending iov\n\t\t\tfor(let i_iov=0; i_iov> 2];\n\n\t\t\t\t// size of buffer\n\t\t\t\tconst nb_len = ATU32_HEAP[ip_iov + 4 >> 2];\n\n\t\t\t\t// next iov\n\t\t\t\t(ip_iov as number) += 8;\n\n\t\t\t\t// extract text from buffer\n\t\t\t\ts_out += new TextDecoder().decode(ATU8_HEAP.subarray(ip_start, ip_start+nb_len));\n\n\t\t\t\t// update number of bytes read\n\t\t\t\tcb_read += nb_len;\n\t\t\t}\n\n\t\t\t// route to fd\n\t\t\tif(h_fds[i_fd]) {\n\t\t\t\th_fds[i_fd](s_out);\n\t\t\t}\n\t\t\t// no fd found\n\t\t\telse {\n\t\t\t\tthrow new Error(`libsecp256k1 tried writing to non-open file descriptor: ${i_fd}\\n${s_out}`);\n\t\t\t}\n\n\t\t\t// write bytes read\n\t\t\tATU32_HEAP[ip_written >> 2] = cb_read;\n\n\t\t\t// no error\n\t\t\treturn 0;\n\t\t},\n\t});\n\n\treturn [g_imports, (d_memory: WebAssembly.Memory) => [\n\t\tAB_HEAP = d_memory.buffer,\n\t\tATU8_HEAP = new Uint8Array(AB_HEAP),\n\t\tATU32_HEAP = new Uint32Array(AB_HEAP),\n\t] as const] as const;\n};\n","import type {WasmExportsExtension} from '../gen/wasm.js';\nimport type {ByteSize, Pointer} from '../types.js';\n\nexport type PointerContext = Pointer<'context'>;\nexport type PointerSeed = Pointer<'seed'>;\nexport type PointerPubkey = Pointer<'pubkey'>;\nexport type PointerSig = Pointer<'ecdsa_signature'>;\nexport type PointerSigRecoverable = Pointer<'ecdsa_recoverable_signature'>;\nexport type PointerNonceFn = Pointer<'nonce_function'>;\n\nexport type PointerSha256 = Pointer<'sha256'>;\n\nexport type RecoveryValue = 0 | 1 | 2 | 3;\n\nexport type SignatureAndRecovery = [\n\tatu8_signature: Uint8Array,\n\txc_recovery: RecoveryValue,\n];\n\n\n/* eslint-disable @typescript-eslint/no-duplicate-enum-values, @typescript-eslint/prefer-literal-enum-member */\nexport const enum ByteLens {\n\tRANDOM_SEED = 32, // when randomizing context\n\n\tPRIVATE_KEY = 32,\n\tECDH_SHARED_SK = 32,\n\n\tPUBLIC_KEY_COMPRESSED = 33,\n\tPUBLIC_KEY_LIB = 64, // secp256k1_pubkey: char [64];\n\tPUBLIC_KEY_UNCOMPRESSED = 65,\n\tPUBLIC_KEY_MAX = 65, // uncompressed public key is largest\n\n\tECDSA_SIG_COMPACT = 64,\n\tECDSA_SIG_LIB = 64, // secp256k1_ecdsa_signature: char [64];\n\tECDSA_SIG_RECOVERABLE = 65, // secp256k1_ecdsa_recoverable_signature: char [65];\n\n\tMSG_HASH = 32,\n\tNONCE_ENTROPY = 32,\n\n\t/**\n\t * From the source:\n\t * ```\n\t * typedef struct {\n\t * uint32_t s[8];\n\t * unsigned char buf[64];\n\t * uint64_t bytes;\n\t * } secp256k1_sha256;\n\t * ```\n\t */\n\tSHA256 = (4 * 8) + 64 + 8,\n}\n\n// ##### From secp256k1.h: #####\n// /* All flags' lower 8 bits indicate what they're for. Do not use directly. */\n// #define SECP256K1_FLAGS_TYPE_MASK ((1 << 8) - 1)\n// #define SECP256K1_FLAGS_TYPE_CONTEXT (1 << 0)\n// #define SECP256K1_FLAGS_TYPE_COMPRESSION (1 << 1)\n// /* The higher bits contain the actual data. Do not use directly. */\n// #define SECP256K1_FLAGS_BIT_CONTEXT_VERIFY (1 << 8)\n// #define SECP256K1_FLAGS_BIT_CONTEXT_SIGN (1 << 9)\n// #define SECP256K1_FLAGS_BIT_CONTEXT_DECLASSIFY (1 << 10)\n// #define SECP256K1_FLAGS_BIT_COMPRESSION (1 << 8)\n\n/* eslint-disable @typescript-eslint/prefer-literal-enum-member, no-multi-spaces */\nexport const enum Flags {\n\tCONTEXT_NONE = (1 << 0) | 0,\n\tCONTEXT_VERIFY = (1 << 0) | (1 << 8),\n\tCONTEXT_SIGN = (1 << 0) | (1 << 9),\n\tCONTEXT_DECLASSIFY = (1 << 0) | (1 << 10),\n\n\tCOMPRESSION_UNCOMPRESSED = (1 << 1) | 0,\n\tCOMPRESSION_COMPRESSED = (1 << 1) | (1 << 8),\n}\n/* eslint-enable */\n\n\nexport const enum BinaryResult {\n\tSUCCESS = 1,\n\tFAILURE = 0,\n}\n\nexport interface Secp256k1WasmCore extends WasmExportsExtension {\n\t/** Create a secp256k1 context object (in dynamically allocated memory).\n\t *\n\t * This function uses malloc to allocate memory. It is guaranteed that malloc is\n\t * called at most once for every call of this function. If you need to avoid dynamic\n\t * memory allocation entirely, see secp256k1_context_static and the functions in\n\t * secp256k1_preallocated.h.\n\t *\n\t * Returns: a newly created context object.\n\t * In: flags: Always set to SECP256K1_CONTEXT_NONE (see below).\n\t */\n\tcontext_create(\n\t\txm_flags: Flags,\n\t): PointerContext;\n\n\n\t/** Randomizes the context to provide enhanced protection against side-channel leakage.\n\t *\n\t * Returns: 1: randomization successful\n\t * 0: error\n\t * Args: ctx: pointer to a context object (not secp256k1_context_static).\n\t * In: seed32: pointer to a 32-byte random seed (NULL resets to initial state).\n\t */\n\tcontext_randomize(\n\t\tip_ctx: PointerContext,\n\t\tip_seed: PointerSeed,\n\t): BinaryResult;\n\n\n\t/** Compute the public key for a secret key.\n\t *\n\t * Returns: 1: secret was valid, public key stores.\n\t * 0: secret was invalid, try again.\n\t * Args: ctx: pointer to a context object (not secp256k1_context_static).\n\t * Out: pubkey: pointer to the created public key.\n\t * In: seckey: pointer to a 32-byte secret key.\n\t */\n\tec_pubkey_create(\n\t\tip_ctx: PointerContext,\n\t\tip_pk_out: PointerPubkey,\n\t\tip_sk_in: Pointer<32>,\n\t): BinaryResult;\n\n\n\t/** Verify an ECDSA secret key.\n\t *\n\t * A secret key is valid if it is not 0 and less than the secp256k1 curve order\n\t * when interpreted as an integer (most significant byte first). The\n\t * probability of choosing a 32-byte string uniformly at random which is an\n\t * invalid secret key is negligible.\n\t *\n\t * Returns: 1: secret key is valid\n\t * 0: secret key is invalid\n\t * Args: ctx: pointer to a context object.\n\t * In: seckey: pointer to a 32-byte secret key.\n\t */\n\tec_seckey_verify(\n\t\tip_ctx: PointerContext,\n\t\tip_sk_in: Pointer<32>,\n\t): BinaryResult;\n\n\n\t/** Parse a variable-length public key into the pubkey object.\n\t *\n\t * Returns: 1 if the public key was fully valid.\n\t * 0 if the public key could not be parsed or is invalid.\n\t * Args: ctx: a secp256k1 context object.\n\t * Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a\n\t * parsed version of input. If not, its value is undefined.\n\t * In: input: pointer to a serialized public key\n\t * inputlen: length of the array pointed to by input\n\t */\n\tec_pubkey_parse(\n\t\tip_ctx: PointerContext,\n\t\tip_pk_out: PointerPubkey,\n\t\tip_pk_in: Pointer<65>,\n\t\tnb_len: ByteSize,\n\t): BinaryResult;\n\n\n\t/** Serialize a pubkey object into a serialized byte sequence.\n\t *\n\t * Returns: 1 always.\n\t * Args: ctx: a secp256k1 context object.\n\t * Out: output: a pointer to a 65-byte (if compressed==0) or 33-byte (if\n\t * compressed==1) byte array to place the serialized key\n\t * in.\n\t * In/Out: outputlen: a pointer to an integer which is initially set to the\n\t * size of output, and is overwritten with the written\n\t * size.\n\t * In: pubkey: a pointer to a secp256k1_pubkey containing an\n\t * initialized public key.\n\t * flags: SECP256K1_EC_COMPRESSED if serialization should be in\n\t * compressed format, otherwise SECP256K1_EC_UNCOMPRESSED.\n\t */\n\tec_pubkey_serialize(\n\t\tip_ctx: PointerContext,\n\t\tip_pk_out: Pointer<65>,\n\t\tip_len_inout: Pointer<4>,\n\t\tip_pk_in: PointerPubkey,\n\t\txm_flags: Flags,\n\t): BinaryResult.SUCCESS;\n\n\n\t/** Tweak a secret key by adding tweak to it.\n\t *\n\t * Returns: 0 if the arguments are invalid or the resulting secret key would be\n\t * invalid (only when the tweak is the negation of the secret key). 1\n\t * otherwise.\n\t * Args: ctx: pointer to a context object.\n\t * In/Out: seckey: pointer to a 32-byte secret key. If the secret key is\n\t * invalid according to secp256k1_ec_seckey_verify, this\n\t * function returns 0. seckey will be set to some unspecified\n\t * value if this function returns 0.\n\t * In: tweak32: pointer to a 32-byte tweak, which must be valid according to\n\t * secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly\n\t * random 32-byte tweaks, the chance of being invalid is\n\t * negligible (around 1 in 2^128).\n\t */\n\tec_seckey_tweak_add(\n\t\tthis: void,\n\t\tip_ctx: PointerContext,\n\t\tip_sk_inout: Pointer<32>,\n\t\tip_tweak_in: Pointer<32>,\n\t): BinaryResult.SUCCESS;\n\n\n\t/** Tweak a secret key by multiplying it by a tweak.\n\t *\n\t * Returns: 0 if the arguments are invalid. 1 otherwise.\n\t * Args: ctx: pointer to a context object.\n\t * In/Out: seckey: pointer to a 32-byte secret key. If the secret key is\n\t * invalid according to secp256k1_ec_seckey_verify, this\n\t * function returns 0. seckey will be set to some unspecified\n\t * value if this function returns 0.\n\t * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to\n\t * secp256k1_ec_seckey_verify, this function returns 0. For\n\t * uniformly random 32-byte arrays the chance of being invalid\n\t * is negligible (around 1 in 2^128).\n\t */\n\tec_seckey_tweak_mul(\n\t\tthis: void,\n\t\tip_ctx: PointerContext,\n\t\tip_sk_inout: Pointer<32>,\n\t\tip_tweak_in: Pointer<32>,\n\t): BinaryResult.SUCCESS;\n\n\n\t/** Tweak a public key by adding tweak times the generator to it.\n\t *\n\t * Returns: 0 if the arguments are invalid or the resulting public key would be\n\t * invalid (only when the tweak is the negation of the corresponding\n\t * secret key). 1 otherwise.\n\t * Args: ctx: pointer to a context object.\n\t * In/Out: pubkey: pointer to a public key object. pubkey will be set to an\n\t * invalid value if this function returns 0.\n\t * In: tweak32: pointer to a 32-byte tweak, which must be valid according to\n\t * secp256k1_ec_seckey_verify or 32 zero bytes. For uniformly\n\t * random 32-byte tweaks, the chance of being invalid is\n\t * negligible (around 1 in 2^128).\n\t */\n\tec_pubkey_tweak_add(\n\t\tthis: void,\n\t\tip_ctx: PointerContext,\n\t\tip_pk_inout: PointerPubkey,\n\t\tip_tweak_in: Pointer<32>,\n\t): BinaryResult.SUCCESS;\n\n\n\t/** Tweak a public key by multiplying it by a tweak value.\n\t *\n\t * Returns: 0 if the arguments are invalid. 1 otherwise.\n\t * Args: ctx: pointer to a context object.\n\t * In/Out: pubkey: pointer to a public key object. pubkey will be set to an\n\t * invalid value if this function returns 0.\n\t * In: tweak32: pointer to a 32-byte tweak. If the tweak is invalid according to\n\t * secp256k1_ec_seckey_verify, this function returns 0. For\n\t * uniformly random 32-byte arrays the chance of being invalid\n\t * is negligible (around 1 in 2^128).\n\t */\n\tec_pubkey_tweak_mul(\n\t\tthis: void,\n\t\tip_ctx: PointerContext,\n\t\tip_pk_inout: PointerPubkey,\n\t\tip_tweak_in: Pointer<32>,\n\t): BinaryResult.SUCCESS;\n}\n\n\nexport interface Secp256k1WasmEcdh {\n\t/** Compute an EC Diffie-Hellman secret in constant time\n\t *\n\t * Returns: 1: exponentiation was successful\n\t * 0: scalar was invalid (zero or overflow) or hashfp returned 0\n\t * Args: ctx: pointer to a context object.\n\t * Out: output: pointer to an array to be filled by hashfp.\n\t * In: pubkey: a pointer to a secp256k1_pubkey containing an initialized public key.\n\t * seckey: a 32-byte scalar with which to multiply the point.\n\t * hashfp: pointer to a hash function. If NULL,\n\t * secp256k1_ecdh_hash_function_sha256 is used\n\t * (in which case, 32 bytes will be written to output).\n\t * data: arbitrary data pointer that is passed through to hashfp\n\t * (can be NULL for secp256k1_ecdh_hash_function_sha256).\n\t */\n\tecdh(\n\t\tip_ctx: PointerContext,\n\t\tip_shared_out: Pointer<32>,\n\t\tip_pk_in: PointerPubkey,\n\t\tip_sk_in: Pointer<32>,\n\t\tip_noncefn_in?: PointerNonceFn,\n\t\tip_ent_in?: Pointer<32>,\n\t): BinaryResult;\n}\n\n\nexport interface Secp256k1WasmEcdsaRaw {\n\t/** Parse an ECDSA signature in compact (64 bytes) format.\n\t *\n\t * Returns: 1 when the signature could be parsed, 0 otherwise.\n\t * Args: ctx: a secp256k1 context object\n\t * Out: sig: a pointer to a signature object\n\t * In: input64: a pointer to the 64-byte array to parse\n\t *\n\t * The signature must consist of a 32-byte big endian R value, followed by a\n\t * 32-byte big endian S value. If R or S fall outside of [0..order-1], the\n\t * encoding is invalid. R and S with value 0 are allowed in the encoding.\n\t *\n\t * After the call, sig will always be initialized. If parsing failed or R or\n\t * S are zero, the resulting sig value is guaranteed to fail verification for\n\t * any message and public key.\n\t */\n\tecdsa_signature_parse_compact(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_out: PointerSig,\n\t\tip_sig_in: Pointer<64>,\n\t): BinaryResult;\n\n\n\t/** Serialize an ECDSA signature in compact (64 byte) format.\n\t *\n\t * Returns: 1\n\t * Args: ctx: a secp256k1 context object\n\t * Out: output64: a pointer to a 64-byte array to store the compact serialization\n\t * In: sig: a pointer to an initialized signature object\n\t *\n\t * See secp256k1_ecdsa_signature_parse_compact for details about the encoding.\n\t */\n\tecdsa_signature_serialize_compact(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_out: Pointer<64>,\n\t\tip_sig_in: PointerSig,\n\t): BinaryResult.SUCCESS;\n\n\n\t/** Create an ECDSA signature.\n\t *\n\t * Returns: 1: signature created\n\t * 0: the nonce generation function failed, or the secret key was invalid.\n\t * Args: ctx: pointer to a context object (not secp256k1_context_static).\n\t * Out: sig: pointer to an array where the signature will be placed.\n\t * In: msghash32: the 32-byte message hash being signed.\n\t * seckey: pointer to a 32-byte secret key.\n\t * noncefp: pointer to a nonce generation function. If NULL,\n\t * secp256k1_nonce_function_default is used.\n\t * ndata: pointer to arbitrary data used by the nonce generation function\n\t * (can be NULL). If it is non-NULL and\n\t * secp256k1_nonce_function_default is used, then ndata must be a\n\t * pointer to 32-bytes of additional data.\n\t *\n\t * The created signature is always in lower-S form. See\n\t * secp256k1_ecdsa_signature_normalize for more details.\n\t */\n\tecdsa_sign(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_out: PointerSig,\n\t\tip_hash_in: Pointer<32>,\n\t\tip_sk: Pointer<32>,\n\t\tip_noncefn?: PointerNonceFn,\n\t\tip_ent?: Pointer<32>,\n\t): BinaryResult;\n\n\n\t/** Verify an ECDSA signature.\n\t *\n\t * Returns: 1: correct signature\n\t * 0: incorrect or unparseable signature\n\t * Args: ctx: a secp256k1 context object.\n\t * In: sig: the signature being verified.\n\t * msghash32: the 32-byte message hash being verified.\n\t * The verifier must make sure to apply a cryptographic\n\t * hash function to the message by itself and not accept an\n\t * msghash32 value directly. Otherwise, it would be easy to\n\t * create a \"valid\" signature without knowledge of the\n\t * secret key. See also\n\t * https://bitcoin.stackexchange.com/a/81116/35586 for more\n\t * background on this topic.\n\t * pubkey: pointer to an initialized public key to verify with.\n\t */\n\tecdsa_verify(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_in: PointerSig,\n\t\tip_hash_in: Pointer<32>,\n\t\tip_pk_in: PointerPubkey,\n\t): BinaryResult;\n}\n\n\nexport interface Secp256k1WasmEcdsaRecovery {\n\t/** Parse a compact ECDSA signature (64 bytes + recovery id).\n\t *\n\t * Returns: 1 when the signature could be parsed, 0 otherwise\n\t * Args: ctx: a secp256k1 context object\n\t * Out: sig: a pointer to a signature object\n\t * In: input64: a pointer to a 64-byte compact signature\n\t * recid: the recovery id (0, 1, 2 or 3)\n\t */\n\tecdsa_recoverable_signature_parse_compact(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_out: PointerSigRecoverable,\n\t\tip_sig_in: Pointer<64>,\n\t\txb_v_in: number,\n\t): BinaryResult;\n\n\n\t/** Serialize an ECDSA signature in compact format (64 bytes + recovery id).\n\t *\n\t * Returns: 1\n\t * Args: ctx: a secp256k1 context object.\n\t * Out: output64: a pointer to a 64-byte array of the compact signature.\n\t * recid: a pointer to an integer to hold the recovery id.\n\t * In: sig: a pointer to an initialized signature object.\n\t */\n\tecdsa_recoverable_signature_serialize_compact(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_out: Pointer<64>,\n\t\tip_v_out: Pointer<4>,\n\t\tip_sig_in: PointerSigRecoverable,\n\t): BinaryResult.SUCCESS;\n\n\n\t/** Create a recoverable ECDSA signature.\n\t *\n\t * Returns: 1: signature created\n\t * 0: the nonce generation function failed, or the secret key was invalid.\n\t * Args: ctx: pointer to a context object (not secp256k1_context_static).\n\t * Out: sig: pointer to an array where the signature will be placed.\n\t * In: msghash32: the 32-byte message hash being signed.\n\t * seckey: pointer to a 32-byte secret key.\n\t * noncefp: pointer to a nonce generation function. If NULL,\n\t * secp256k1_nonce_function_default is used.\n\t * ndata: pointer to arbitrary data used by the nonce generation function\n\t * (can be NULL for secp256k1_nonce_function_default).\n\t */\n\tecdsa_sign_recoverable(\n\t\tip_ctx: PointerContext,\n\t\tip_sig_out: PointerSigRecoverable,\n\t\tip_hash_in: Pointer<32>,\n\t\tip_sk_in: Pointer<32>,\n\t\tip_noncefn_in: PointerNonceFn,\n\t\tip_ent_in: Pointer<32>,\n\t): BinaryResult;\n\n\n\t/** Recover an ECDSA public key from a signature.\n\t *\n\t * Returns: 1: public key successfully recovered (which guarantees a correct signature).\n\t * 0: otherwise.\n\t * Args: ctx: pointer to a context object.\n\t * Out: pubkey: pointer to the recovered public key.\n\t * In: sig: pointer to initialized signature that supports pubkey recovery.\n\t * msghash32: the 32-byte message hash assumed to be signed.\n\t */\n\tecdsa_recover(\n\t\tip_ctx: PointerContext,\n\t\tip_pk_out: PointerPubkey,\n\t\tip_sig_in: PointerSigRecoverable,\n\t\tip_hash_in: Pointer<32>,\n\t): BinaryResult;\n}\n\n\nexport interface Secp256k1WasmSha256 {\n\tsha256_initialize(\n\t\tip_hash: PointerSha256,\n\t): void;\n\n\tsha256_write(\n\t\tip_hash: PointerSha256,\n\t\tip_data_in: Pointer,\n\t\tnb_data_in: number,\n\t): void;\n\n\tsha256_finalize(\n\t\tip_hash: PointerSha256,\n\t\tip_digest_out: Pointer<32>,\n\t): void;\n}\n","\n/*\n* ================================\n* GENERATED FILE WARNING\n* Do not edit this file manually.\n* ================================\n*/\n\n/* eslint-disable @typescript-eslint/no-unused-vars, unused-imports/no-unused-imports, no-trailing-spaces */\n\nimport type {\n\tPointer,\n\tByteSize,\n\tByteDelta,\n\tByteOffset,\n\tFileDescriptor,\n\tSeekWhence,\n\tWasmImports,\n\tWasmExports,\n} from '../types.js';\n\nexport interface WasmImportsExtension extends WasmImports {\n\t\n}\n\nexport interface WasmExportsExtension extends WasmExports {\n\tcontext_create: Function;\n\tec_pubkey_parse: Function;\n\tec_pubkey_serialize: Function;\n\tecdsa_signature_parse_compact: Function;\n\tecdsa_verify: Function;\n\tec_seckey_verify: Function;\n\tec_pubkey_create: Function;\n\tec_seckey_tweak_add: Function;\n\tec_pubkey_tweak_add: Function;\n\tec_seckey_tweak_mul: Function;\n\tec_pubkey_tweak_mul: Function;\n\tcontext_randomize: Function;\n\tecdh: Function;\n\tecdsa_recoverable_signature_parse_compact: Function;\n\tecdsa_recoverable_signature_serialize_compact: Function;\n\tecdsa_sign_recoverable: Function;\n\tecdsa_recover: Function;\n}\n\nexport const map_wasm_imports = (g_imports: WasmImportsExtension) => ({\n\ta: {\n\t\tf: g_imports.abort,\n\t\te: g_imports.memcpy,\n\t\tc: g_imports.resize,\n\t\td: () => 52, // _fd_close,\n\t\tb: () => 70, // _fd_seek,\n\t\ta: g_imports.write,\n\t},\n});\n\nexport const map_wasm_exports = <\n\tg_extension extends WasmExportsExtension=WasmExportsExtension,\n>(g_exports: WebAssembly.Exports): g_extension => ({\n\tmalloc: g_exports['i'],\n\tfree: g_exports['j'],\n\tcontext_create: g_exports['l'],\n\tec_pubkey_parse: g_exports['m'],\n\tec_pubkey_serialize: g_exports['n'],\n\tecdsa_signature_parse_compact: g_exports['o'],\n\tecdsa_verify: g_exports['p'],\n\tec_seckey_verify: g_exports['q'],\n\tec_pubkey_create: g_exports['r'],\n\tec_seckey_tweak_add: g_exports['s'],\n\tec_pubkey_tweak_add: g_exports['t'],\n\tec_seckey_tweak_mul: g_exports['u'],\n\tec_pubkey_tweak_mul: g_exports['v'],\n\tcontext_randomize: g_exports['w'],\n\tecdh: g_exports['x'],\n\tecdsa_recoverable_signature_parse_compact: g_exports['y'],\n\tecdsa_recoverable_signature_serialize_compact: g_exports['z'],\n\tecdsa_sign_recoverable: g_exports['A'],\n\tecdsa_recover: g_exports['B'],\n\tmemory: g_exports['g'],\n\n\tinit: () => (g_exports['h'] as VoidFunction)(),\n} as g_extension);\n\n","import type {PointerNonceFn, PointerPubkey, PointerSeed, PointerSig, PointerSigRecoverable, RecoveryValue, Secp256k1WasmCore, Secp256k1WasmEcdh, Secp256k1WasmEcdsaRaw, Secp256k1WasmEcdsaRecovery, SignatureAndRecovery} from './secp256k1-types.js';\nimport type {ByteSize, Pointer} from '../types.js';\nimport type {Promisable} from '@blake.regalia/belt';\n\nimport {bytes} from '@blake.regalia/belt';\n\nimport {emsimp} from './emsimp.js';\nimport {BinaryResult, ByteLens, Flags} from './secp256k1-types.js';\nimport {map_wasm_exports, map_wasm_imports} from '../gen/wasm.js';\n\n\nconst S_TAG_ECDH = 'ECDH: ';\nconst S_TAG_ECDSA_VERIFY = 'ECDSA verify: ';\nconst S_TAG_TWEAK_ADD = 'k tweak add: ';\nconst S_TAG_TWEAK_MUL = 'k tweak mul: ';\n\nconst S_REASON_INVALID_SK = 'Invalid private key';\nconst S_REASON_INVALID_PK = 'Invalid public key';\nconst S_REASON_UNPARSEABLE_SIG = 'Unparseable signature';\n\nconst random_32 = () => crypto.getRandomValues(bytes(32));\n\n/**\n * Wrapper instance providing operations backed by libsecp256k1 WASM module\n */\nexport interface Secp256k1 {\n\t/**\n\t * Generates a new private key using crypto secure random bytes and without modulo bias\n\t * @returns a new private key (32 bytes)\n\t */\n\tgen_sk(): Uint8Array;\n\n\t/**\n\t * Asserts that the given private key is valid, throws otherwise\n\t * @param atu8_sk - the private key (32 bytes)\n\t * @returns the same `Uint8Array`\n\t */\n\tvalid_sk(atu8_sk: Uint8Array): Uint8Array;\n\n\t/**\n\t * Computes the public key for a given private key\n\t * @param atu8_sk - the private key (32 bytes)\n\t * @param b_uncompressed - optional flag to return the uncompressed (65 byte) public key\n\t * @returns the public key (compressed to 33 bytes by default, or 65 if uncompressed)\n\t */\n\tsk_to_pk(atu8_sk: Uint8Array, b_uncompressed?: boolean): Uint8Array;\n\n\t/**\n\t * Signs the given message hash using the given private key.\n\t * @param atu8_sk - the private key\n\t * @param atu8_hash - the message hash (32 bytes)\n\t * @param atu8_entropy - optional entropy to use\n\t * @returns tuple of [compact signature (64 bytes) as concatenation of `r || s`, recovery ID byte]\n\t */\n\tsign(atu8_sk: Uint8Array, atu8_hash: Uint8Array, atu8_ent?: Uint8Array): SignatureAndRecovery;\n\n\t/**\n\t * Verifies the signature is valid for the given message hash and public key\n\t * @param atu8_signature - compact signature in `r || s` form (64 bytes)\n\t * @param atu8_msg - the message hash (32 bytes)\n\t * @param atu8_pk - the public key\n\t */\n\tverify(atu8_signature: Uint8Array, atu8_hash: Uint8Array, atu8_pk: Uint8Array): boolean;\n\n\t/**\n\t * Recovers a public key from the given signature and recovery ID\n\t * @param atu8_signature - compact signature in `r || s` form (64 bytes)\n\t * @param xc_recovery - the recovery ID\n\t */\n\trecover(atu8_signature: Uint8Array, atu8_hash: Uint8Array, xc_recovery: number): Uint8Array;\n\n\t/**\n\t * ECDH key exchange. Computes a shared secret given a private key some public key\n\t * @param atu8_sk - the private key (32 bytes)\n\t * @param atu8_pk - the public key (33 or 65 bytes)\n\t * @returns the shared secret (32 bytes)\n\t */\n\tecdh(atu8_sk: Uint8Array, atu8_pk: Uint8Array): Uint8Array;\n\n\t/**\n\t * Tweak the given private key by adding to it\n\t * @param atu8_sk - the private key (32 bytes)\n\t * @param atu8_tweak - the tweak vector (32 bytes)\n\t * @returns the tweaked private key\n\t */\n\ttweak_sk_add(atu8_sk: Uint8Array, atu8_tweak: Uint8Array): Uint8Array;\n\n\t/**\n\t * Tweak the given private key by multiplying it\n\t * @param atu8_sk - the private key (32 bytes)\n\t * @param atu8_tweak - the tweak vector (32 bytes)\n\t * @returns the tweaked private key\n\t */\n\ttweak_sk_mul(atu8_sk: Uint8Array, atu8_tweak: Uint8Array): Uint8Array;\n\n\t/**\n\t * Tweak the given public key by adding to it\n\t * @param atu8_pk - the public key (33 or 65 bytes)\n\t * @param atu8_tweak - the tweak vector (32 bytes)\n\t * @returns the tweaked public key\n\t */\n\ttweak_pk_add(atu8_pk: Uint8Array, atu8_tweak: Uint8Array, b_uncompressed?: boolean): Uint8Array;\n\n\t/**\n\t * Tweak the given public key by multiplying it\n\t * @param atu8_pk - the public key (33 or 65 bytes)\n\t * @param atu8_tweak - the tweak vector (32 bytes)\n\t * @returns the tweaked public key\n\t */\n\ttweak_pk_mul(atu8_pk: Uint8Array, atu8_tweak: Uint8Array, b_uncompressed?: boolean): Uint8Array;\n}\n\n/**\n * Creates a new instance of the secp256k1 WASM and returns its ES wrapper\n * @param z_src - a Response containing the WASM binary, a Promise that resolves to one,\n * \tor the raw bytes to the WASM binary as a {@link BufferSource}\n * @returns the wrapper API\n */\nexport const WasmSecp256k1 = async(\n\tz_src: Promisable | BufferSource\n): Promise => {\n\t// prepare the runtime\n\tconst [g_imports, f_bind_heap] = emsimp(map_wasm_imports, 'wasm-secp256k1');\n\n\t// prep the wasm module\n\tlet d_wasm: WebAssembly.WebAssemblyInstantiatedSource;\n\n\t// instantiate wasm binary by streaming the response bytes\n\tif(z_src instanceof Response || z_src instanceof Promise) {\n\t\td_wasm = await WebAssembly.instantiateStreaming(z_src as Response, g_imports);\n\t}\n\t// instantiate using raw bianry\n\telse {\n\t\td_wasm = await WebAssembly.instantiate(z_src as BufferSource, g_imports);\n\t}\n\n\t// create the libsecp256k1 exports struct\n\tconst g_wasm = map_wasm_exports<\n\t\tSecp256k1WasmCore\n\t\t& Secp256k1WasmEcdh\n\t\t& Secp256k1WasmEcdsaRaw\n\t\t& Secp256k1WasmEcdsaRecovery\n\t>(d_wasm.instance.exports);\n\n\t// bind the heap and ref its view(s)\n\tconst [, ATU8_HEAP, ATU32_HEAP] = f_bind_heap(g_wasm.memory);\n\n\t// call into the wasm module's init method\n\tg_wasm.init();\n\n\t// ref malloc function\n\tconst malloc = g_wasm.malloc;\n\n\tconst ip_sk = malloc(ByteLens.PRIVATE_KEY);\n\tconst ip_ent = malloc(ByteLens.NONCE_ENTROPY);\n\tconst ip_seed = malloc(ByteLens.RANDOM_SEED);\n\tconst ip_sk_shared = malloc(ByteLens.ECDH_SHARED_SK);\n\tconst ip_msg_hash = malloc(ByteLens.MSG_HASH);\n\n\t// scratch spaces\n\tconst ip_sig_scratch = malloc(ByteLens.ECDSA_SIG_COMPACT);\n\tconst ip_pk_scratch = malloc(ByteLens.PUBLIC_KEY_MAX);\n\n\t// library handle: secp256k1_pubkey\n\tconst ip_pk_lib = malloc(ByteLens.PUBLIC_KEY_LIB);\n\n\t// library handle: secp256k1_ecdsa_signature\n\tconst ip_sig_lib = malloc(ByteLens.ECDSA_SIG_LIB);\n\n\t// library handle: secp256k1_ecdsa_signature\n\tconst ip_sig_rcvr_lib = malloc(ByteLens.ECDSA_SIG_RECOVERABLE);\n\n\t// recovery id byte\n\tconst ip_v = malloc(4);\n\n\t// create a reusable context\n\tconst ip_ctx = g_wasm.context_create(Flags.CONTEXT_SIGN | Flags.CONTEXT_VERIFY);\n\n\t// length specifier\n\tconst ip_len = g_wasm.malloc(4);\n\tconst ip32_len = ip_len >> 2;\n\n\n\n\t/**\n\t * Pads the given input data before copying it into the heap at the given location; throws if input\n\t * data exceeds expected size\n\t * @param atu8_data - the data to put into program memory\n\t * @param ib_write - the starting byte position to write into\n\t * @param nb_size - the size of the region\n\t */\n\tconst put_bytes = (atu8_data: Uint8Array, ip_write: Pointer, nb_size: ByteSize) => {\n\t\tconst atu8_buffer = bytes(nb_size);\n\t\tatu8_buffer.set(atu8_data);\n\t\tATU8_HEAP.set(atu8_buffer, ip_write);\n\t};\n\n\t/**\n\t * Randomizes the context for better protection against CPU side-channel attacks\n\t */\n\tconst randomize_context = () => {\n\t\t// put random seed bytes into place\n\t\tput_bytes(random_32(), ip_seed, ByteLens.RANDOM_SEED);\n\n\t\t// randomize context\n\t\tif(BinaryResult.SUCCESS !== g_wasm.context_randomize(ip_ctx, ip_seed)) {\n\t\t\tthrow Error('Failed to randomize context');\n\t\t}\n\t};\n\n\t/**\n\t * Parses the input public key in preparation for use by some method\n\t * @param atu8_sk - the private key\n\t * @returns `true` on success, `false` otherwise\n\t */\n\tconst parse_pubkey = (atu8_pk: Uint8Array): boolean => {\n\t\t// copy input bytes into place\n\t\tput_bytes(atu8_pk, ip_pk_scratch, ByteLens.PUBLIC_KEY_MAX);\n\n\t\t// parse public key\n\t\treturn BinaryResult.SUCCESS === g_wasm.ec_pubkey_parse(ip_ctx, ip_pk_lib, ip_pk_scratch, atu8_pk.length);\n\t};\n\n\t/**\n\t * Puts the given private key into program memory, runs the given callback, then zeroes out the key\n\t * @param atu8_sk - the private key\n\t * @param f_use - callback to use the key\n\t * @returns whatever the callback returns\n\t */\n\tconst with_sk = <\n\t\tw_return,\n\t>(atu8_sk: Uint8Array, f_use: () => w_return) => {\n\t\t// prep callback return\n\t\tlet w_return: w_return;\n\n\t\t// in case of any exception..\n\t\ttry {\n\t\t\t// copy input bytes into place\n\t\t\tput_bytes(atu8_sk, ip_sk, ByteLens.PRIVATE_KEY);\n\n\t\t\t// use private key\n\t\t\tw_return = f_use();\n\t\t}\n\t\tfinally {\n\t\t\t// zero-out private key\n\t\t\tATU8_HEAP.fill(0, ip_sk, ip_sk+ByteLens.PRIVATE_KEY);\n\t\t}\n\n\t\t// forward result\n\t\treturn w_return;\n\t};\n\n\t/**\n\t * Serializes the public key\n\t * @param b_uncompressed - whether or not the result should be in compressed form (33 bytes) or not (65 bytes)\n\t * @returns the public key as a buffer\n\t */\n\tconst get_pk = (b_uncompressed=false): Uint8Array => {\n\t\t// output length of public key\n\t\tconst nb_pk = b_uncompressed? ByteLens.PUBLIC_KEY_UNCOMPRESSED: ByteLens.PUBLIC_KEY_COMPRESSED;\n\n\t\t// // set target output length in little endian for WASM runtime\n\t\t// DV_HEAP.setUint32(ip_len, nb_pk, true);\n\n\t\t// set target output length (the Web has basically become LE-only)\n\t\tATU32_HEAP[ip32_len] = nb_pk;\n\n\t\t// prep compression flag\n\t\tconst xm_compression = b_uncompressed? Flags.COMPRESSION_UNCOMPRESSED: Flags.COMPRESSION_COMPRESSED;\n\n\t\t// serialize public key\n\t\tg_wasm.ec_pubkey_serialize(ip_ctx, ip_pk_scratch, ip_len, ip_pk_lib, xm_compression);\n\n\t\t// extract result\n\t\treturn ATU8_HEAP.slice(ip_pk_scratch, ip_pk_scratch+nb_pk);\n\t};\n\n\t/**\n\t * Asserts the private key is valid\n\t * @param atu8_sk - the private key (32 bytes)\n\t * @returns the valid private key, or throws if the caller somehow discovered an invalid sk\n\t */\n\tconst valid_sk = (atu8_sk: Uint8Array): Uint8Array => {\n\t\t// while using the private key, assert the length is valid and the point falls within curve order\n\t\tif(with_sk(atu8_sk, () => ByteLens.PRIVATE_KEY as number !== atu8_sk.length || BinaryResult.SUCCESS !== g_wasm.ec_seckey_verify(ip_ctx, ip_sk))) {\n\t\t\tthrow Error(S_REASON_INVALID_SK);\n\t\t}\n\n\t\t// return the valid sk\n\t\treturn atu8_sk;\n\t};\n\n\t/**\n\t * Creates a function to tweak a private key using either addition or multiplication\n\t * @param f_tweak - the tweak function\n\t * @param s_tag - the tag to use for error messages\n\t * @returns a tweak function\n\t */\n\tconst tweak_sk = (f_tweak: typeof g_wasm['ec_seckey_tweak_add'], s_tag: string) => (atu8_sk: Uint8Array, atu8_tweak: Uint8Array) => {\n\t\t// randomize context\n\t\trandomize_context();\n\n\t\t// copy input bytes into place\n\t\tput_bytes(atu8_sk, ip_sk, ByteLens.PRIVATE_KEY);\n\n\t\t// use message hash memory for tweak vector\n\t\tput_bytes(atu8_tweak, ip_msg_hash, ByteLens.MSG_HASH);\n\n\t\t// apply the given tweak to the private key\n\t\tif(BinaryResult.SUCCESS !== f_tweak(ip_ctx, ip_sk, ip_msg_hash)) {\n\t\t\t// manually clear the private key\n\t\t\tatu8_sk.fill(0);\n\n\t\t\tthrow Error('s'+s_tag+S_REASON_INVALID_SK);\n\t\t}\n\n\t\t// return tweaked private key\n\t\treturn ATU8_HEAP.slice(ip_sk, ip_sk+ByteLens.PRIVATE_KEY);\n\t};\n\n\t/**\n\t * Creates a function to tweak a public key using either addition or multiplication\n\t * @param f_tweak - the tweak function\n\t * @param s_tag - the tag to use for error messages\n\t * @returns a tweak function\n\t */\n\tconst tweak_pk = (f_tweak: typeof g_wasm['ec_pubkey_tweak_add'], s_tag: string) => (atu8_pk: Uint8Array, atu8_tweak: Uint8Array, b_uncompressed=false) => {\n\t\t// parse the public key\n\t\tif(!parse_pubkey(atu8_pk)) {\n\t\t\tthrow Error(S_TAG_ECDSA_VERIFY+S_REASON_INVALID_PK);\n\t\t}\n\n\t\t// copy input bytes into place\n\t\tput_bytes(atu8_pk, ip_pk_scratch, ByteLens.PUBLIC_KEY_MAX);\n\n\t\t// use message hash memory for tweak vector\n\t\tput_bytes(atu8_tweak, ip_msg_hash, ByteLens.MSG_HASH);\n\n\t\t// apply the given tweak to the public key\n\t\tif(BinaryResult.SUCCESS !== f_tweak(ip_ctx, ip_pk_lib, ip_msg_hash)) {\n\t\t\tthrow Error('p'+s_tag+S_REASON_INVALID_PK);\n\t\t}\n\n\t\t// return tweaked public key\n\t\treturn get_pk(b_uncompressed);\n\t};\n\n\treturn {\n\t\tgen_sk: () => valid_sk(crypto.getRandomValues(bytes(ByteLens.PRIVATE_KEY))),\n\n\t\tvalid_sk,\n\n\t\tsk_to_pk(atu8_sk, b_uncompressed=false) {\n\t\t\t// randomize context\n\t\t\trandomize_context();\n\n\t\t\t// while using the private key, compute its corresponding public key; from the docs:\n\t\t\tif(BinaryResult.SUCCESS !== with_sk(atu8_sk, () => g_wasm.ec_pubkey_create(ip_ctx, ip_pk_lib, ip_sk))) {\n\t\t\t\tthrow Error('sk_to_pk: '+S_REASON_INVALID_SK);\n\t\t\t}\n\n\t\t\t// serialize the public key\n\t\t\treturn get_pk(b_uncompressed);\n\t\t},\n\n\t\tsign(atu8_sk, atu8_hash, atu8_ent=random_32()) {\n\t\t\t// randomize context\n\t\t\trandomize_context();\n\n\t\t\t// copy message hash bytes into place\n\t\t\tput_bytes(atu8_hash, ip_msg_hash, ByteLens.MSG_HASH);\n\n\t\t\t// copy entropy bytes into place\n\t\t\tput_bytes(atu8_ent, ip_ent, ByteLens.NONCE_ENTROPY);\n\n\t\t\t// while using the private key, sign the given message hash\n\t\t\tif(BinaryResult.SUCCESS !== with_sk(atu8_sk, () => g_wasm.ecdsa_sign_recoverable(\n\t\t\t\tip_ctx,\n\t\t\t\tip_sig_rcvr_lib,\n\t\t\t\tip_msg_hash,\n\t\t\t\tip_sk,\n\t\t\t\t0 as PointerNonceFn,\n\t\t\t\tip_ent\n\t\t\t))) {\n\t\t\t\tthrow Error('ECDSA sign: '+S_REASON_INVALID_SK);\n\t\t\t}\n\n\t\t\t// serialize the signature in compact form as `r || s` (64 bytes)\n\t\t\tg_wasm.ecdsa_recoverable_signature_serialize_compact(ip_ctx, ip_sig_scratch, ip_v, ip_sig_rcvr_lib);\n\n\t\t\t// return serialized signature\n\t\t\treturn [\n\t\t\t\tATU8_HEAP.slice(ip_sig_scratch, ip_sig_scratch+ByteLens.ECDSA_SIG_COMPACT),\n\t\t\t\tATU8_HEAP[ip_v] as RecoveryValue, // terminal byte of 32-bit uint\n\t\t\t];\n\t\t},\n\n\t\tverify(atu8_signature, atu8_hash, atu8_pk) {\n\t\t\t// copy signature bytes into place\n\t\t\tput_bytes(atu8_signature, ip_sig_scratch, ByteLens.ECDSA_SIG_COMPACT);\n\n\t\t\t// copy message hash bytes into place\n\t\t\tput_bytes(atu8_hash, ip_msg_hash, ByteLens.MSG_HASH);\n\n\t\t\t// parse the public key\n\t\t\tif(!parse_pubkey(atu8_pk)) {\n\t\t\t\tthrow Error(S_TAG_ECDSA_VERIFY+S_REASON_INVALID_PK);\n\t\t\t}\n\n\t\t\t// parse the signature\n\t\t\tif(BinaryResult.SUCCESS !== g_wasm.ecdsa_signature_parse_compact(ip_ctx, ip_sig_lib, ip_sig_scratch)) {\n\t\t\t\tthrow Error(S_TAG_ECDSA_VERIFY+S_REASON_UNPARSEABLE_SIG);\n\t\t\t}\n\n\t\t\t// verify the signature\n\t\t\treturn BinaryResult.SUCCESS === g_wasm.ecdsa_verify(ip_ctx, ip_sig_lib, ip_msg_hash, ip_pk_lib);\n\t\t},\n\n\t\trecover(atu8_signature, atu8_hash, xc_recovery, b_uncompressed=false) {\n\t\t\t// copy signature bytes into place\n\t\t\tput_bytes(atu8_signature, ip_sig_scratch, ByteLens.ECDSA_SIG_COMPACT);\n\n\t\t\t// parse the recoverable signature\n\t\t\tif(BinaryResult.SUCCESS !== g_wasm.ecdsa_recoverable_signature_parse_compact(ip_ctx, ip_sig_rcvr_lib, ip_sig_scratch, xc_recovery)) {\n\t\t\t\tthrow Error(S_TAG_ECDSA_VERIFY+S_REASON_UNPARSEABLE_SIG);\n\t\t\t}\n\n\t\t\t// copy message hash bytes into place\n\t\t\tput_bytes(atu8_hash, ip_msg_hash, ByteLens.MSG_HASH);\n\n\t\t\t// recover the public key\n\t\t\tif(BinaryResult.SUCCESS !== g_wasm.ecdsa_recover(ip_ctx, ip_pk_lib, ip_sig_rcvr_lib, ip_msg_hash)) {\n\t\t\t\tthrow Error(S_TAG_ECDSA_VERIFY+'Invalid signature');\n\t\t\t}\n\n\t\t\t// return recovered public key\n\t\t\treturn get_pk(b_uncompressed);\n\t\t},\n\n\t\tecdh(atu8_sk, atu8_pk) {\n\t\t\t// parse public key\n\t\t\tif(!parse_pubkey(atu8_pk)) throw Error(S_TAG_ECDH+S_REASON_INVALID_PK);\n\n\t\t\t// start using private key\n\t\t\treturn with_sk(atu8_sk, () => {\n\t\t\t\t// perform ecdh computation\n\t\t\t\tif(BinaryResult.SUCCESS !== g_wasm.ecdh(ip_ctx, ip_sk_shared, ip_pk_lib, ip_sk)) {\n\t\t\t\t\tthrow Error(S_TAG_ECDH+S_REASON_INVALID_SK);\n\t\t\t\t}\n\n\t\t\t\t// return copy of result bytes\n\t\t\t\treturn ATU8_HEAP.slice(ip_sk_shared, ip_sk_shared+ByteLens.ECDH_SHARED_SK);\n\t\t\t});\n\t\t},\n\n\t\ttweak_sk_add: tweak_sk(g_wasm.ec_seckey_tweak_add, S_TAG_TWEAK_ADD),\n\n\t\ttweak_sk_mul: tweak_sk(g_wasm.ec_seckey_tweak_mul, S_TAG_TWEAK_MUL),\n\n\t\ttweak_pk_add: tweak_pk(g_wasm.ec_pubkey_tweak_add, S_TAG_TWEAK_ADD),\n\n\t\ttweak_pk_mul: tweak_pk(g_wasm.ec_pubkey_tweak_mul, S_TAG_TWEAK_MUL),\n\t};\n};\n\n","import type {RecoveryValue} from '../api/secp256k1-types';\n\nimport {bytes_to_hex, hex_to_bytes, sha256, text_to_bytes} from '@blake.regalia/belt';\n\nimport {WasmSecp256k1} from '../api/secp256k1';\n\nconst elem = (si_id: string) => document.getElementById(si_id) as d_type;\n\nconst dm_sk = elem('sk');\nconst dm_pk = elem('pk');\nconst dm_pkr = elem('pkr');\nconst dm_v = elem('v');\nconst dm_msg = elem('msg');\nconst dm_hash = elem('hash');\nconst dm_sig_r = elem('sig_r');\nconst dm_sig_s = elem('sig_s');\nconst dm_verified = elem('verified');\n\n(async function load() {\n\tconst d_res = await fetch('out/secp256k1.wasm');\n\tconst k_secp = await WasmSecp256k1(d_res);\n\n\tlet atu8_sk: Uint8Array;\n\tlet atu8_pk: Uint8Array;\n\tlet atu8_hash: Uint8Array;\n\tlet atu8_sig: Uint8Array;\n\tlet xc_recovery: RecoveryValue;\n\tlet atu8_pkr: Uint8Array;\n\n\tfunction sk_err(s_msg: string) {\n\t\tdm_pk.value = s_msg;\n\t\tdm_hash.value = dm_sig_r.value = dm_sig_s.value = dm_verified.value = '';\n\t}\n\n\tconst is_hex = (sb16: string) => /^[a-f0-9]+$/i.test(sb16);\n\n\tfunction reload_sk() {\n\t\tconst sb16_sk = dm_sk.value;\n\t\tif(sb16_sk.length < 64) {\n\t\t\treturn sk_err('Private key too short');\n\t\t}\n\t\telse if(sb16_sk.length > 64) {\n\t\t\treturn sk_err('Private key too long');\n\t\t}\n\t\telse if(!is_hex(sb16_sk)) {\n\t\t\treturn sk_err('Not hexadecimal');\n\t\t}\n\n\t\tatu8_sk = hex_to_bytes(sb16_sk);\n\n\t\ttry {\n\t\t\tatu8_pk = k_secp.sk_to_pk(atu8_sk);\n\t\t}\n\t\tcatch(e_convert) {\n\t\t\treturn sk_err((e_convert as Error).message);\n\t\t}\n\n\t\tdm_pk.value = bytes_to_hex(atu8_pk);\n\n\t\tvoid reload_sig();\n\t}\n\n\tasync function reload_sig() {\n\t\tatu8_hash = await sha256(text_to_bytes(dm_msg.value));\n\n\t\tdm_hash.value = bytes_to_hex(atu8_hash);\n\n\t\ttry {\n\t\t\t[atu8_sig, xc_recovery] = k_secp.sign(atu8_sk, atu8_hash);\n\t\t}\n\t\tcatch(e_convert) {\n\t\t\treturn dm_sig_r.value = (e_convert as Error).message;\n\t\t}\n\n\t\tdm_sig_r.value = bytes_to_hex(atu8_sig.subarray(0, 32));\n\t\tdm_sig_s.value = bytes_to_hex(atu8_sig.subarray(32));\n\t\tdm_v.value = xc_recovery+'';\n\n\t\ttry {\n\t\t\tk_secp.verify(atu8_sig, atu8_hash, atu8_pk);\n\t\t}\n\t\tcatch(e_verify) {\n\t\t\treturn dm_verified.value = (e_verify as Error).message;\n\t\t}\n\n\t\ttry {\n\t\t\tatu8_pkr = k_secp.recover(atu8_sig, atu8_hash, xc_recovery);\n\t\t}\n\t\tcatch(e_recover) {\n\t\t\treturn dm_verified.value = (e_recover as Error).message;\n\t\t}\n\n\t\tif(bytes_to_hex(atu8_pk) !== bytes_to_hex(atu8_pkr)) {\n\t\t\treturn dm_verified.value = `Recovered public keys do not match!`;\n\t\t}\n\n\t\tdm_pkr.value = bytes_to_hex(atu8_pkr);\n\n\t\tdm_verified.value = 'Yes';\n\t}\n\n\t// generate random private key\n\tatu8_sk = k_secp.gen_sk();\n\n\t// set value in UI\n\tdm_sk.value = bytes_to_hex(atu8_sk);\n\n\t// bind to input events\n\tdm_sk.addEventListener('input', reload_sk);\n\tdm_msg.addEventListener('input', reload_sig);\n\n\t// init\n\treload_sk();\n})();\n"],"names":["ByteLens","Flags","BinaryResult"],"mappings":"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","x_google_ignoreList":[0]} \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 9416db4..38dd297 100644 --- a/docs/index.html +++ b/docs/index.html @@ -77,6 +77,16 @@

+ + + + + + + + + +