import sha256 from 'crypto-js/sha256.js'; import { initialize } from 'zokrates-js'; window.addEventListener('load', () => { document.getElementById('submitFlagBtn') .addEventListener('click', () => { submitFlag(document.getElementById('flagbox').value); }); }); const ZEROSTR = '0'; /* Converts a string into a stringified hexadecimal number */ function str2hex(string) { return string.split('') .map(c => c.charCodeAt(0).toString(16).padStart(2, '0')) .join(''); } /* Converts a stringified hexadecimal number into a string */ function hex2str(hex) { return hex.split(/(\w\w)/g) .filter(p => !!p) .map(c => String.fromCharCode(parseInt(c, 16))) .join(''); } /* Prefix each element of a string a array with 0x */ function map_0xprefix(arr) { return arr.map(s => '0x' + s); } /* Convert a string to a byte array */ function str2asciiarr(s) { let charCodeArr = []; for (let i = 0; i < s.length; i++) { let code = s.charCodeAt(i); charCodeArr.push(code); } return charCodeArr; } /* Convert a byte array to a string */ function asciiarr2str(arr) { return String.fromCharCode(...arr); } /* * Expand a simple number into a stringified u32[8] array for ZoKrates. */ function expand_number(number) { const revstr = s => Array.from(s).reverse().join(''); const split8 = s => s.match(/.{1,8}/g); const parts = split8(revstr(number.toString(16))) .map(p => '0x' + revstr(p)) .map(p => parseInt(p, 16).toString()) .reverse(); return [...Array(8 - parts.length).fill(ZEROSTR), ...parts]; } const proving_key = await (await fetch('/zok_proving.key')).text(); const program = await (await fetch('/zok_program')).arrayBuffer(); const abi = await (await fetch('/zok_abi.json')).json(); /* Get the proving key from the local server */ const PROVING_KEY_URI = 'http://localhost:8080/proving.key'; const proving_key = await (await fetch(PROVING_KEY_URI)).text(); const artefacts = { program: new Uint8Array(program), abi: abi }; console.log(artefacts); function submitFlag(flag) { initialize().then((defaultProvider) => { const zokProvider = defaultProvider.withOptions({ backend: 'ark', scheme: 'gm17', }); const flag_ascii = str2asciiarr(flag); const flag_ascii_padded = flag_ascii.concat(new Array(64 - flag_ascii.length).fill(0)); const flag_padded = asciiarr2str(flag_ascii_padded); const hash = sha256(flag_padded).toString(); /* TODO get this from contract */ const addr = 'f6e3a49fca2eb57f286d516fa60154ebfd10d5ad'; /* TODO get this from metamask */ const flag_split = map_0xprefix(str2hex(flag).match(/.{1,2}/g)); const flag_split_padded = flag_split.concat(new Array(64 - flag_split.length).fill('0x0')); const hash_split = map_0xprefix(hash.match(/.{1,8}/g)); const addr_split = map_0xprefix(addr.match(/.{1,8}/g)); // witness computation console.log('witness'); const { witness, output } = zokProvider.computeWitness(artefacts, [hash_split, addr_split, flag_split_padded]); // generate proof console.log('proof'); const proof = zokProvider.generateProof(artefacts.program, witness, proving_key); console.log(proof); }); };