crypto.mjs raw

   1  // TinyJS Runtime — secp256k1 Crypto Bridge (WASM)
   2  // init() must be called (and awaited) before any crypto operations.
   3  
   4  import { Slice } from './builtin.mjs';
   5  
   6  let _secp = null;
   7  
   8  // init loads and initializes the secp256k1 WASM module.
   9  // Called from $entry.mjs before main().
  10  // Gracefully skips if WASM module is not available (e.g. app delegates crypto to extension).
  11  export async function init() {
  12    // Crypto is handled by schnorr.mjs (jsbridge) — no WASM module needed.
  13  }
  14  
  15  function sliceToU8(s) {
  16    if (s instanceof Uint8Array) return s;
  17    const u = new Uint8Array(s.$length);
  18    for (let i = 0; i < s.$length; i++) {
  19      u[i] = s.$array[s.$offset + i];
  20    }
  21    return u;
  22  }
  23  
  24  function u8ToSlice(u8) {
  25    if (u8 === null || u8 === undefined) return null;
  26    const arr = new Array(u8.length);
  27    for (let i = 0; i < u8.length; i++) arr[i] = u8[i];
  28    return new Slice(arr, 0, u8.length, u8.length);
  29  }
  30  
  31  export function PubKeyFromSecKey(seckey) {
  32    const result = _secp.getPublicKey(sliceToU8(seckey));
  33    return u8ToSlice(result);
  34  }
  35  
  36  export function SignSchnorr(seckey, msg, auxRand) {
  37    const result = _secp.sign(sliceToU8(seckey), sliceToU8(msg), sliceToU8(auxRand));
  38    if (result === null || result === undefined) return null;
  39    return u8ToSlice(result);
  40  }
  41  
  42  export function VerifySchnorr(pubkey, msg, sig) {
  43    return _secp.verify(sliceToU8(pubkey), sliceToU8(msg), sliceToU8(sig));
  44  }
  45