diff --git a/static/js/dom.js b/static/js/dom.js index 90eac1d..e8bfebf 100644 --- a/static/js/dom.js +++ b/static/js/dom.js @@ -7,6 +7,10 @@ function lockMapDom() { } function updateDom() { + if (gameState !== WAITING) { + document.querySelector("#ready-button").style.display = "none"; + } + updatePlayerDom(); updateMapDom(); } @@ -20,7 +24,9 @@ function updateMapDom() { for (let region of Object.values(REGIONS)) { const element = document.querySelector(`.node[data-name=${region.name}]`); - element.querySelector(".strength").textContent = region.strength || "U"; + element.querySelector(".strength").textContent = region.strength || ""; + element.style.backgroundColor = + region.owner === null ? "white" : region.owner.getColor(); } } @@ -48,6 +54,7 @@ function updatePlayerDom() { } let idSpan = document.createElement("span"); + idSpan.style.color = player.getColor(); if (playerId === ID) { idSpan.textContent = `${playerId} (you)`; } else { @@ -82,7 +89,6 @@ document.addEventListener("DOMContentLoaded", () => { el.addEventListener("click", (ev) => { let region = ev.target.closest(".node").dataset.name; socket.emit("message", Packet.createRegionClaim(region)); - us.claim(); }) ); }); diff --git a/static/js/index.js b/static/js/index.js index 6b25659..00e76ab 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -11,8 +11,6 @@ const PRE_GAME = 1; const PLAYING = 2; const POST_GAME = 3; -const COLORS = ["#FF0000", "#00FF00", "#0000FF", "#FF00FF", "#FFFF00", "#00FFFF"]; - let gameState = WAITING; let socket; @@ -38,13 +36,11 @@ document.addEventListener("DOMContentLoaded", () => { }); socket.on("message", async (data) => { - // Ignore any messages that originate from us. - if (data.author === ID) { - return; - } - switch (data.type) { case "ANNOUNCE": + if (data.author === ID) { + return; + } playerConnected(data); break; @@ -53,27 +49,47 @@ document.addEventListener("DOMContentLoaded", () => { break; case "KEEPALIVE": + if (data.author === ID) { + return; + } keepAlive(data); break; case "READY": + if (data.author === ID) { + return; + } await setReady(data); break; case "RANDOM": + if (data.author === ID) { + return; + } await random.processCooperativeRandom(data); break; case "BARRIER": + if (data.author === ID) { + return; + } barrier.resolve(data); break; case "CLAIM": - // TODO: block out of order plays. + if (data.author !== currentPlayer().id) { + return; + } + // Claim a region in the pregame. - currentPlayer().claim(data); - // Increment to next player. - currentPlayer().endTurn(); + if (currentPlayer().claim(data)) { + // Increment to next player. + currentPlayer().endTurn(); + } + + if (allRegionsClaimed()) { + console.log("switching to initial reinforcements"); + } updateDom(); break; } diff --git a/static/js/map.js b/static/js/map.js index 5d625c5..4174dc9 100644 --- a/static/js/map.js +++ b/static/js/map.js @@ -60,3 +60,7 @@ const G = new Region("G", WEST); const H = new Region("H", WEST); const I = new Region("I", WEST); const E = new Region("E", WEST); + +function allRegionsClaimed() { + return Object.values(REGIONS).find((region) => region.owner === null) === undefined; +} diff --git a/static/js/paillier.js b/static/js/paillier.js index f2d1f49..a1772bf 100644 --- a/static/js/paillier.js +++ b/static/js/paillier.js @@ -1,12 +1,28 @@ -let p, q; +let p, q, pubKey, privKey; -document.addEventListener("readystatechange", () => { - if (document.readyState === "interactive") { - addInfoMessage("Generating private key p..."); - p = generate_prime(); - addInfoMessage("Generated!"); - addInfoMessage("Generating private key q..."); - q = generate_prime(); - addInfoMessage("Generated!"); +class PubKey { + constructor(n, g) { + this.n = n; + this.g = g; } +} + +class PrivKey { + constructor(lambda, mu) { + this.lambda = lambda; + this.mu = mu; + } +} + +document.addEventListener("DOMContentLoaded", () => { + return; + + p = generate_prime(); + q = generate_prime(); + + let n = p * q; + let lambda = (p - 1n) * (q - 1n); + + pubKey = new PubKey(n, n + 1n); + privKey = new PrivKey(lambda, fastModularExponentiation(lambda, lambda - 1n, n)); }); diff --git a/static/js/player.js b/static/js/player.js index 21305c8..5aca1d3 100644 --- a/static/js/player.js +++ b/static/js/player.js @@ -5,6 +5,9 @@ class Player { this.id = id; this.ready = false; this.isPlaying = false; + + let randomColor = Math.random() * 360; + this.color = `hsl(${randomColor} 57% 50%)`; } resetTimeout() { @@ -20,17 +23,26 @@ class Player { }, TIMEOUT); } + /** + * Get our color as used on the board. + */ + getColor() { + return this.color; + } + /** * Claim a region of the map. * * @param data Data received via socket. */ claim(data) { - console.log(data.region); let region = Region.getRegion(data.region); if (region.owner === null) { region.claim(this); + return true; + } else { + return false; } } @@ -58,7 +70,7 @@ class Player { nextPlayer() { let sorted = Object.values(players).sort((a, b) => (a.id < b.id ? -1 : 1)); - let ourIndex = sorted.findIndex((player) => player.id === ID); + let ourIndex = sorted.findIndex((player) => player.id === this.id); return sorted[(ourIndex + 1) % sorted.length]; } diff --git a/whitepaper/demonstration/presentation.pdf b/whitepaper/demonstration/presentation.pdf index 5ab5437..e5f7c63 100644 Binary files a/whitepaper/demonstration/presentation.pdf and b/whitepaper/demonstration/presentation.pdf differ diff --git a/whitepaper/demonstration/presentation.tex b/whitepaper/demonstration/presentation.tex index ca488ce..9d60e96 100644 --- a/whitepaper/demonstration/presentation.tex +++ b/whitepaper/demonstration/presentation.tex @@ -30,17 +30,40 @@ \item In the untrusted setup, the same guarantees should be made as the trusted setup, but on a peer-to-peer network. \end{itemize} \end{frame} -\begin{frame}{Proposition} +\begin{frame}{Rationale} \begin{itemize} - \item Zero-knowledge proofs. \begin{itemize} - \item + \item \textbf{Federation} \begin{itemize} + \item Federated platforms can have longer lifespans than centralised platforms. + \item Federated platforms are more resistant to censorship and can help promote anonymity and privacy. \end{itemize} - \item Asymmetric encryption. \begin{itemize} - \item - \end{itemize} - \item Hashing. \begin{itemize} - \item + \item \textbf{Security} \begin{itemize} + \item Constantly looking for ways to secure against threats specific to federated and decentralised infrastructures. + \item Security issues can be devastating even to decentralised infrastructures. \end{itemize} \end{itemize} \end{frame} +\begin{frame}{State of the art} + \begin{itemize} + \item Private key encryption. + \item Signatures. + \item Additive homomorphic encryption. + \item \textbf{Web platform}. Rapidly evolving. + \item \textbf{Monero, Zcash}. Decentralised ledgers respectively using the \textit{Bulletproof} and \textit{ZK-SNARK} zero-knowledge proof systems. + \end{itemize} +\end{frame} +\begin{frame}{Results} + Emulated P2P environment using WebSockets. +\end{frame} +\begin{frame}{Results} + Produce shared random values without beacons using commitment schemes. +\end{frame} +\begin{frame}{Results} + Generating large primes using ECMAScript \texttt{BigInt} and Rabin-Miller. +\end{frame} +\begin{frame}{Results} + Implementation of the Paillier additive homomorphic cryptosystem. +\end{frame} +\begin{frame}{Results} + Implementation of Risk. +\end{frame} \end{document}