diff --git a/static/js/dom.js b/static/js/dom.js
index 05a3142..9d007ab 100644
--- a/static/js/dom.js
+++ b/static/js/dom.js
@@ -1,14 +1,15 @@
-export function updatePlayerDom() {
+function updatePlayerDom() {
let list = document.querySelector("#playerList");
list.replaceChildren();
let newDom = document.createElement("li");
- newDom.textContent = ID;
+ newDom.textContent = ID + " (you)";
+ newDom.style.color = "grey";
list.appendChild(newDom);
for (let playerId of Object.keys(players)) {
- let newDom = document.createElement("li");
if (playerId !== ID) {
+ let newDom = document.createElement("li");
newDom.textContent = playerId;
list.appendChild(newDom);
}
diff --git a/static/js/index.js b/static/js/index.js
index cbacc64..b539e72 100644
--- a/static/js/index.js
+++ b/static/js/index.js
@@ -1,5 +1,3 @@
-import { Player } from "./player.js";
-
const ID = window.crypto.randomUUID();
// Timeout to consider a player disconnected
const TIMEOUT = 30_000;
@@ -13,8 +11,10 @@ const POST_GAME = 3;
let game_state = WAITING;
+let socket;
+
document.addEventListener("DOMContentLoaded", () => {
- let socket = io();
+ socket = io();
socket.on("connect", () => {
console.log("Connected!");
@@ -36,7 +36,7 @@ document.addEventListener("DOMContentLoaded", () => {
switch (data.type) {
case "ANNOUNCE":
- playerConnected(socket, data);
+ playerConnected(data);
break;
case "KEEPALIVE":
@@ -48,7 +48,7 @@ document.addEventListener("DOMContentLoaded", () => {
break;
case "RANDOM":
- cooperativeRandom(data);
+ processCooperativeRandom(data);
break;
}
});
@@ -66,10 +66,9 @@ document.addEventListener("DOMContentLoaded", () => {
/**
* Process player connect packets: these inform that a new player has joined.
*
- * @param socket Socket instance used to announce ourselves to new player
* @param data Packet received
*/
-function playerConnected(socket, data) {
+function playerConnected(data) {
// Block players from joining mid-game
if (game_state !== WAITING) {
return;
@@ -130,22 +129,52 @@ function allPlayersReady() {
// Track ongoing random sessions.
const randomSessions = {};
+/**
+ * Start a cooperative random session.
+ */
+function coopRandom(n) {
+ const sessionId = window.crypto.randomUUID();
+
+ const noise = CryptoJS.lib.WordArray.random(8).toString();
+ const key = CryptoJS.lib.WordArray.random(32).toString();
+ const cipherText = CryptoJS.AES.encrypt(noise, key).toString();
+
+ randomSessions[sessionId] = {
+ range: n,
+ cipherTexts: {},
+ cipherKeys: {},
+ ourKey: key,
+ ourNoise: noise,
+ finalValue: -1,
+ };
+
+ socket.emit("message", {
+ type: "RANDOM",
+ author: ID,
+ session: sessionId,
+ range: n,
+ stage: "CIPHERTEXT",
+ cipherText: cipherText,
+ });
+}
+
/**
* Process cooperative random protocol.
*
- * @param socket Socket instance for communication
* @param data Packet received
*/
-function cooperativeRandom(socket, data) {
+function processCooperativeRandom(data) {
// Step 0: extract relevant information from data
let session = randomSessions[data.session];
const stage = data.stage;
if (session === undefined) {
- // Step 1: generate and encrypt our random value. 4 bytes = 32 bit integer
- const noise = CryptoJS.libs.WordArray.random(4);
- const key = CryptoJS.libs.WordArray.random(256);
- const cipherText = CryptoJS.AES.encrypt(noise, key);
+ // Step 1: generate and encrypt our random value. 8 bytes = 64 bit integer
+ const noise = CryptoJS.lib.WordArray.random(8).toString();
+ console.log(`our noise: ${noise}`);
+
+ const key = CryptoJS.lib.WordArray.random(32).toString();
+ const cipherText = CryptoJS.AES.encrypt(noise, key).toString();
randomSessions[data.session] = {
range: data.range,
@@ -161,6 +190,7 @@ function cooperativeRandom(socket, data) {
socket.emit("message", {
type: "RANDOM",
author: ID,
+ session: data.session,
stage: "CIPHERTEXT",
range: data.range,
cipherText: cipherText,
@@ -170,11 +200,12 @@ function cooperativeRandom(socket, data) {
if (stage === "CIPHERTEXT") {
session.cipherTexts[data.author] = data.cipherText;
- if (Object.keys(session.cipherTexts).length === Object.keys(players).length) {
+ if (Object.keys(session.cipherTexts).length === Object.keys(players).length - 1) {
// Step 3: release our key once all players have sent a ciphertext
socket.emit("message", {
type: "RANDOM",
author: ID,
+ session: data.session,
stage: "DECRYPT",
cipherKey: session.ourKey,
});
@@ -183,7 +214,7 @@ function cooperativeRandom(socket, data) {
session.cipherKeys[data.author] = data.cipherKey;
// Step 4: get final random value
- if (Object.keys(session.cipherKeys).length === Object.keys(players).length) {
+ if (Object.keys(session.cipherKeys).length === Object.keys(players).length - 1) {
let total = 0;
for (let participant of Object.keys(session.cipherKeys)) {
diff --git a/static/js/player.js b/static/js/player.js
index 14b804e..75790b9 100644
--- a/static/js/player.js
+++ b/static/js/player.js
@@ -1,6 +1,4 @@
-import { updatePlayerDom } from "./dom.js";
-
-export class Player {
+class Player {
constructor(id, name) {
this.name = name;
this.timeout = null;
@@ -10,7 +8,7 @@ export class Player {
resetTimeout() {
if (this.timeout !== null) {
- window.clearTimeout(players[data.author].timeout);
+ window.clearTimeout(this.timeout);
}
this.timeout = window.setTimeout(() => {
diff --git a/templates/index.html b/templates/index.html
index 0e81ac8..51b8e2e 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -7,7 +7,9 @@
-
+
+
+