<!DOCTYPE html> <html lang="en"> <head> <title>Riskless</title> <link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet"> <script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script> <script src="{{ url_for('static', filename='js/lz-string.min.js') }}"></script> <script src="{{ url_for('static', filename='js/sha3.js') }}"></script> <script src="{{ url_for('static', filename='js/modules/interface/main.js') }}" type="module"></script> <script src="{{ url_for('static', filename='js/modules/crypto/main.js') }}" type="module"></script> </head> <body> <div id="modal" class="hidden modal"> <div class="modal-content"> <div> <label> Amount <input type="number" class="amount"> </label> </div> <div> <label> Target <select class="target"></select> </label> </div> <div class="button-row"> <button class="submit-modal">Submit</button> <button class="cancel-modal">Cancel</button> </div> </div> </div> <div id="defense-modal" class="hidden modal"> <div class="modal-content"> <div> <h2>Defending region <span class="region-tag">R</span></h2> <label> Defense amount <input type="number" class="amount"> </label> </div> <button class="submit-modal">Submit</button> </div> </div> <div id="players-div"> <strong>Players</strong> <ul id="playerList"> </ul> <button id="shuffleColors">Shuffle colours</button> </div> <div id="remaining-reinforcements"> </div> <div id="info"> </div> <div id="map"> <svg id="map-back" viewBox="-520 -520 1000 1000" width="1000" height="1000"> <line x1="0" y1="0" x2="160" y2="0" stroke="black"></line> <line x1="160" y1="0" x2="260" y2="0" stroke="black"></line> <line x1="160" y1="0" x2="220" y2="-200" stroke="black"></line> <line x1="280" y1="0" x2="220" y2="-200" stroke="black"></line> <line x1="220" y1="-200" x2="380" y2="-200" stroke="black"></line> <line x1="220" y1="-200" x2="-40" y2="-140" stroke="black"></line> <line x1="0" y1="0" x2="-40" y2="-140" stroke="black"></line> <line x1="0" y1="0" x2="-40" y2="140" stroke="black"></line> <line x1="-280" y1="80" x2="-40" y2="140" stroke="black"></line> <line x1="-280" y1="-80" x2="-40" y2="-140" stroke="black"></line> <line x1="-280" y1="80" x2="-180" y2="0" stroke="black"></line> <line x1="-280" y1="-80" x2="-180" y2="0" stroke="black"></line> <line x1="-180" y1="0" x2="-40" y2="140" stroke="black"></line> <path d="M -280 80 Q -360 0 -280 -80" stroke="black" fill="transparent"></path> </svg> <div class="node east" data-name="A" style="left: 280px;"> <div class="strength"></div> <div class="label">A</div> <div class="actions"> <button class="claim">Claim</button> <button class="reinforce">Reinf.</button> <button class="attack">Attack</button> <button class="fortify">Fortify</button> </div> </div> <div class="node east" data-name="B" style="left: 160px;"> <div class="strength"></div> <div class="label">B</div> <div class="actions"> <button class="claim">Claim</button> <button class="reinforce">Reinf.</button> <button class="attack">Attack</button> <button class="fortify">Fortify</button> </div> </div> <div class="node east" data-name="C" style="left: 220px; top: -200px;"> <div class="strength"></div> <div class="label">C</div> <div class="actions"> <button class="claim">Claim</button> <button class="reinforce">Reinf.</button> <button class="attack">Attack</button> <button class="fortify">Fortify</button> </div> </div> <div class="node east" data-name="D" style="left: 380px; top: -200px;"> <div class="strength"></div> <div class="label">D</div> <div class="actions"> <button class="claim">Claim</button> <button class="reinforce">Reinf.</button> <button class="attack">Attack</button> <button class="fortify">Fortify</button> </div> </div> <div class="node west" data-name="E" style="left: -40px; top: 140px;"> <div class="strength"></div> <div class="label">E</div> <div class="actions"> <button class="claim">Claim</button> <button class="reinforce">Reinf.</button> <button class="attack">Attack</button> <button class="fortify">Fortify</button> </div> </div> <div class="node west" data-name="F" style="left: -40px; top: -140px;"> <div class="strength"></div> <div class="label">F</div> <div class="actions"> <button class="claim">Claim</button> <button class="reinforce">Reinf.</button> <button class="attack">Attack</button> <button class="fortify">Fortify</button> </div> </div> <div class="node west" data-name="G" style="left: -280px; top: -80px;"> <div class="strength"></div> <div class="label">G</div> <div class="actions"> <button class="claim">Claim</button> <button class="reinforce">Reinf.</button> <button class="attack">Attack</button> <button class="fortify">Fortify</button> </div> </div> <div class="node west" data-name="H" style="left: -280px; top: 80px;"> <div class="strength"></div> <div class="label">H</div> <div class="actions"> <button class="claim">Claim</button> <button class="reinforce">Reinf.</button> <button class="attack">Attack</button> <button class="fortify">Fortify</button> </div> </div> <div class="node west" data-name="I" style="left: -180px;"> <div class="strength"></div> <div class="label">I</div> <div class="actions"> <button class="claim">Claim</button> <button class="reinforce">Reinf.</button> <button class="attack">Attack</button> <button class="fortify">Fortify</button> </div> </div> <div class="node east" data-name="J" style=""> <div class="strength"></div> <div class="label">J</div> <div class="actions"> <button class="claim">Claim</button> <button class="reinforce">Reinf.</button> <button class="attack">Attack</button> <button class="fortify">Fortify</button> </div> </div> </div> <div id="ready"> <button id="ready-button">Not ready</button> <button id="end-turn" class="hidden">End Turn</button> </div> <!-- Benchmarking script --> <script> function RSABench() { console.log("Warming up") const ROUNDS = 10000; for (let i = 0n; i < 100n; i++) { window.rsa.pubKey.encrypt(i); } console.log("Benching") performance.mark("rsa-start") for (let i = 0n; i < BigInt(ROUNDS); i++) { window.rsa.pubKey.encrypt(i); } performance.mark("rsa-end") console.log(`Bench done. Time per encrypt: ${performance.measure("rsa-duration", "rsa-start", "rsa-end").duration / ROUNDS}`) } function PaillierBench() { console.log("Warming up") const ROUNDS = 500 for (let i = 0n; i < 100n; i++) { window.paillier.pubKey.encrypt(i); } console.log("Benching") performance.mark("paillier-start") for (let i = 0n; i < BigInt(ROUNDS); i++) { window.paillier.pubKey.encrypt(i); } performance.mark("paillier-end") console.log(`Bench done. Time per encrypt: ${performance.measure("paillier-duration", "paillier-start", "paillier-end").duration / ROUNDS}`) } function ZeroProofBench() { console.log("Warming up") const cipherText = paillier.pubKey.encrypt(0n) const ROUNDS = 50; for (let i = 0; i < 5; i++) { cipherText.proveNI(); } console.log("Benching") performance.mark("paillier-start") for (let i = 0; i < ROUNDS; i++) { cipherText.proveNI() } performance.mark("paillier-end") console.log(`Bench done. Time per proof: ${performance.measure("paillier-duration", "paillier-start", "paillier-end").duration / ROUNDS}`) } function ZeroProofVerifierBench() { console.log("Warming up") const ROUNDS = 50 const cipherText = paillier.pubKey.encrypt(1n) const readOnly = cipherText.asReadOnlyCiphertext(); const proof = cipherText.proveNI() for (let i = 0; i < 5; i++) { readOnly.verifyNI(proof) } console.log("Benching") performance.mark("paillier-start") for (let i = 0; i < ROUNDS; i++) { readOnly.verifyNI(proof) } performance.mark("paillier-end") console.log(`Bench done. Time per verification: ${performance.measure("paillier-duration", "paillier-start", "paillier-end").duration / ROUNDS}`) } function Protocol4Bench() { console.log("Warming up") const regions = { A: paillier.pubKey.encrypt(0n), B: paillier.pubKey.encrypt(1n), C: paillier.pubKey.encrypt(0n), D: paillier.pubKey.encrypt(0n), E: paillier.pubKey.encrypt(0n) } const ROUNDS = 20; for (let i = 0; i < 5; i++) { proveRegions(regions) } console.log("Benching") performance.mark("p4-start") for (let i = 0; i < ROUNDS; i++) { proveRegions(regions) } performance.mark("p4-end") console.log(`Bench done. Time per proof: ${performance.measure("p4-duration", "p4-start", "p4-end").duration / ROUNDS}`) } function Protocol4VerifierBench() { console.log("Warming up") const ROUNDS = 20; const regions = { A: paillier.pubKey.encrypt(0n), B: paillier.pubKey.encrypt(1n), C: paillier.pubKey.encrypt(0n), D: paillier.pubKey.encrypt(0n), E: paillier.pubKey.encrypt(0n) } let proof = proveRegions(regions) for (let i = 0; i < 5; i++) { verifyRegions(proof, paillier.pubKey) } console.log("Benching") performance.mark("pv-start") for (let i = 0; i < ROUNDS; i++) { verifyRegions(proof, paillier.pubKey) } performance.mark("pv-end") console.log(`Bench done. Time per verification: ${performance.measure("pv-duration", "pv-start", "pv-end").duration / ROUNDS}`) } function BitLengthProofBench() { console.log("Warming up") const ct = paillier.pubKey.encrypt(5n) const ROUNDS = 20; for (let i = 0; i < 5; i++) { proveBitLength(ct) } console.log("Benching") performance.mark("rp-start") for (let i = 0; i < ROUNDS; i++) { proveBitLength(ct) } performance.mark("rp-end") console.log(`Bench done. Time per proof: ${performance.measure("rp-duration", "rp-start", "rp-end").duration / ROUNDS}`) } function BitLengthVerifierBench() { console.log("Warming up") const ROUNDS = 20; const ct = paillier.pubKey.encrypt(5n) let proof = proveBitLength(ct) for (let i = 0; i < 5; i++) { verifyBitLength(proof, paillier.pubKey) } console.log("Benching") performance.mark("rv-start") for (let i = 0; i < ROUNDS; i++) { verifyBitLength(proof, paillier.pubKey) } performance.mark("rv-end") console.log(`Bench done. Time per verification: ${performance.measure("rv-duration", "rv-start", "rv-end").duration / ROUNDS}`) } function FortifyProofBench() { console.log("Warming up") const ct = { A: paillier.pubKey.encrypt(0n), B: paillier.pubKey.encrypt(3n), C: paillier.pubKey.encrypt(-3n), D: paillier.pubKey.encrypt(0n), E: paillier.pubKey.encrypt(0n) } const ROUNDS = 20; for (let i = 0; i < 5; i++) { proveFortify(ct) } console.log("Benching") performance.mark("fp-start") for (let i = 0; i < ROUNDS; i++) { proveFortify(ct) } performance.mark("fp-end") console.log(`Bench done. Time per proof: ${performance.measure("fp-duration", "fp-start", "fp-end").duration / ROUNDS}`) } function FortifyVerifierBench() { console.log("Warming up") const ROUNDS = 20; const ct = { A: paillier.pubKey.encrypt(0n), B: paillier.pubKey.encrypt(3n), C: paillier.pubKey.encrypt(-3n), D: paillier.pubKey.encrypt(0n), E: paillier.pubKey.encrypt(0n) } let proof = proveFortify(ct) for (let i = 0; i < 5; i++) { verifyFortify(proof, paillier.pubKey) } console.log("Benching") performance.mark("rv-start") for (let i = 0; i < ROUNDS; i++) { verifyFortify(proof, paillier.pubKey) } performance.mark("rv-end") console.log(`Bench done. Time per verification: ${performance.measure("rv-duration", "rv-start", "rv-end").duration / ROUNDS}`) } function PrimeBench() { const ROUNDS = 20; for (let i = 0; i < 2; i++) { generate_safe_prime() } console.log("Benching") performance.mark("p-start") for (let i = 0; i < ROUNDS; i++) { generate_safe_prime() } performance.mark("p-end") console.log(`Bench done. Time per generation: ${performance.measure("p-duration", "p-start", "p-end").duration / ROUNDS}`) } // https://gist.github.com/kawanet/352a2ed1d1656816b2bc function string_to_buffer(src) { return (new Uint16Array([].map.call(src, function(c) { return c.charCodeAt(0) }))).buffer; } function Protocol4Size() { const regions = { A: paillier.pubKey.encrypt(0n), B: paillier.pubKey.encrypt(1n), C: paillier.pubKey.encrypt(0n), D: paillier.pubKey.encrypt(0n), E: paillier.pubKey.encrypt(0n) } let ROUNDS = 10; let size = 0; let compressedSize = 0; for (let x = 0; x < ROUNDS; x++) { let s = JSON.stringify(proveRegions(regions)); size += string_to_buffer(s).byteLength; compressedSize += LZString.compressToUint8Array(s).length; } return { size: size / ROUNDS, compressedSize: compressedSize / ROUNDS }; } function FortifySize() { const regions = { A: paillier.pubKey.encrypt(0n), B: paillier.pubKey.encrypt(3n), C: paillier.pubKey.encrypt(-3n), D: paillier.pubKey.encrypt(0n), E: paillier.pubKey.encrypt(0n) } let ROUNDS = 10; let size = 0; let compressedSize = 0; for (let x = 0; x < ROUNDS; x++) { let s = JSON.stringify(proveFortify(regions)); size += string_to_buffer(s).byteLength; compressedSize += LZString.compressToUint8Array(s).length; } return { size: size / ROUNDS, compressedSize: compressedSize / ROUNDS }; } function BitLengthSize() { const ct = paillier.pubKey.encrypt(5n) let ROUNDS = 10; let size = 0; let compressedSize = 0; for (let x = 0; x < ROUNDS; x++) { let s = JSON.stringify(proveBitLength(ct)); size += string_to_buffer(s).byteLength; compressedSize += LZString.compressToUint8Array(s).length; } return { size: size / ROUNDS, compressedSize: compressedSize / ROUNDS }; } function ZeroProofSize() { const ROUNDS = 100; const cipherText = paillier.pubKey.encrypt(0n) let size = 0; let compressedSize = 0; for (let x = 0; x < ROUNDS; x++) { let s = JSON.stringify(cipherText.proveNI()); size += string_to_buffer(s).byteLength; compressedSize += LZString.compressToUint8Array(s).length; } return { size: size / ROUNDS, compressedSize: compressedSize / ROUNDS }; } </script> </body> </html>