Working now

This commit is contained in:
jude 2023-01-31 12:34:13 +00:00
parent 42e2514c82
commit bfb92e89b0
4 changed files with 55 additions and 23 deletions

View File

@ -1,14 +1,15 @@
export function updatePlayerDom() { function updatePlayerDom() {
let list = document.querySelector("#playerList"); let list = document.querySelector("#playerList");
list.replaceChildren(); list.replaceChildren();
let newDom = document.createElement("li"); let newDom = document.createElement("li");
newDom.textContent = ID; newDom.textContent = ID + " (you)";
newDom.style.color = "grey";
list.appendChild(newDom); list.appendChild(newDom);
for (let playerId of Object.keys(players)) { for (let playerId of Object.keys(players)) {
let newDom = document.createElement("li");
if (playerId !== ID) { if (playerId !== ID) {
let newDom = document.createElement("li");
newDom.textContent = playerId; newDom.textContent = playerId;
list.appendChild(newDom); list.appendChild(newDom);
} }

View File

@ -1,5 +1,3 @@
import { Player } from "./player.js";
const ID = window.crypto.randomUUID(); const ID = window.crypto.randomUUID();
// Timeout to consider a player disconnected // Timeout to consider a player disconnected
const TIMEOUT = 30_000; const TIMEOUT = 30_000;
@ -13,8 +11,10 @@ const POST_GAME = 3;
let game_state = WAITING; let game_state = WAITING;
let socket;
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
let socket = io(); socket = io();
socket.on("connect", () => { socket.on("connect", () => {
console.log("Connected!"); console.log("Connected!");
@ -36,7 +36,7 @@ document.addEventListener("DOMContentLoaded", () => {
switch (data.type) { switch (data.type) {
case "ANNOUNCE": case "ANNOUNCE":
playerConnected(socket, data); playerConnected(data);
break; break;
case "KEEPALIVE": case "KEEPALIVE":
@ -48,7 +48,7 @@ document.addEventListener("DOMContentLoaded", () => {
break; break;
case "RANDOM": case "RANDOM":
cooperativeRandom(data); processCooperativeRandom(data);
break; break;
} }
}); });
@ -66,10 +66,9 @@ document.addEventListener("DOMContentLoaded", () => {
/** /**
* Process player connect packets: these inform that a new player has joined. * 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 * @param data Packet received
*/ */
function playerConnected(socket, data) { function playerConnected(data) {
// Block players from joining mid-game // Block players from joining mid-game
if (game_state !== WAITING) { if (game_state !== WAITING) {
return; return;
@ -130,22 +129,52 @@ function allPlayersReady() {
// Track ongoing random sessions. // Track ongoing random sessions.
const randomSessions = {}; 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. * Process cooperative random protocol.
* *
* @param socket Socket instance for communication
* @param data Packet received * @param data Packet received
*/ */
function cooperativeRandom(socket, data) { function processCooperativeRandom(data) {
// Step 0: extract relevant information from data // Step 0: extract relevant information from data
let session = randomSessions[data.session]; let session = randomSessions[data.session];
const stage = data.stage; const stage = data.stage;
if (session === undefined) { if (session === undefined) {
// Step 1: generate and encrypt our random value. 4 bytes = 32 bit integer // Step 1: generate and encrypt our random value. 8 bytes = 64 bit integer
const noise = CryptoJS.libs.WordArray.random(4); const noise = CryptoJS.lib.WordArray.random(8).toString();
const key = CryptoJS.libs.WordArray.random(256); console.log(`our noise: ${noise}`);
const cipherText = CryptoJS.AES.encrypt(noise, key);
const key = CryptoJS.lib.WordArray.random(32).toString();
const cipherText = CryptoJS.AES.encrypt(noise, key).toString();
randomSessions[data.session] = { randomSessions[data.session] = {
range: data.range, range: data.range,
@ -161,6 +190,7 @@ function cooperativeRandom(socket, data) {
socket.emit("message", { socket.emit("message", {
type: "RANDOM", type: "RANDOM",
author: ID, author: ID,
session: data.session,
stage: "CIPHERTEXT", stage: "CIPHERTEXT",
range: data.range, range: data.range,
cipherText: cipherText, cipherText: cipherText,
@ -170,11 +200,12 @@ function cooperativeRandom(socket, data) {
if (stage === "CIPHERTEXT") { if (stage === "CIPHERTEXT") {
session.cipherTexts[data.author] = data.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 // Step 3: release our key once all players have sent a ciphertext
socket.emit("message", { socket.emit("message", {
type: "RANDOM", type: "RANDOM",
author: ID, author: ID,
session: data.session,
stage: "DECRYPT", stage: "DECRYPT",
cipherKey: session.ourKey, cipherKey: session.ourKey,
}); });
@ -183,7 +214,7 @@ function cooperativeRandom(socket, data) {
session.cipherKeys[data.author] = data.cipherKey; session.cipherKeys[data.author] = data.cipherKey;
// Step 4: get final random value // 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; let total = 0;
for (let participant of Object.keys(session.cipherKeys)) { for (let participant of Object.keys(session.cipherKeys)) {

View File

@ -1,6 +1,4 @@
import { updatePlayerDom } from "./dom.js"; class Player {
export class Player {
constructor(id, name) { constructor(id, name) {
this.name = name; this.name = name;
this.timeout = null; this.timeout = null;
@ -10,7 +8,7 @@ export class Player {
resetTimeout() { resetTimeout() {
if (this.timeout !== null) { if (this.timeout !== null) {
window.clearTimeout(players[data.author].timeout); window.clearTimeout(this.timeout);
} }
this.timeout = window.setTimeout(() => { this.timeout = window.setTimeout(() => {

View File

@ -7,7 +7,9 @@
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script> <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="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<script type="module" src="{{ url_for('static', filename='js/index.js') }}"></script> <script src="{{ url_for('static', filename='js/index.js') }}"></script>
<script src="{{ url_for('static', filename='js/player.js') }}"></script>
<script src="{{ url_for('static', filename='js/dom.js') }}"></script>
</head> </head>
<body> <body>