solutions/CCTF_Solutions_main/frontend/src/main.mjs

104 lines
3.1 KiB
JavaScript

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);
});
};