removed cryptojs from requirements
This commit is contained in:
@ -49,7 +49,10 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
let sig = BigInt(packet.sig);
|
||||
// decrypt and compare signature
|
||||
let dehash = sender.rsaPubKey.encrypt(sig);
|
||||
let hash = BigInt("0x" + CryptoJS.SHA3(JSON.stringify(data)).toString());
|
||||
|
||||
let hasher = new jsSHA("SHA3-256", "TEXT");
|
||||
hasher.update(JSON.stringify(data));
|
||||
let hash = BigInt("0x" + hasher.getHash("HEX"));
|
||||
if (dehash !== hash) {
|
||||
window.console.error(`Signature invalid! Ignoring packet ${data.id}.`);
|
||||
return;
|
||||
|
@ -12,16 +12,12 @@ export class Packet {
|
||||
|
||||
static _sign(data) {
|
||||
// compute hash of data
|
||||
let hash = CryptoJS.SHA3(JSON.stringify(data));
|
||||
let res = 0n;
|
||||
for (let word32 of hash.words) {
|
||||
// remove any sign
|
||||
let bi = BigInt.asUintN(32, BigInt(word32));
|
||||
res = (res << 32n) | bi;
|
||||
}
|
||||
let hasher = new jsSHA("SHA3-256", "TEXT");
|
||||
hasher.update(JSON.stringify(data));
|
||||
let hash = BigInt("0x" + hasher.getHash("HEX"));
|
||||
|
||||
// sign hash
|
||||
let sig = window.rsa.privKey.decrypt(res);
|
||||
let sig = window.rsa.privKey.decrypt(hash);
|
||||
|
||||
// return new packet
|
||||
return {
|
||||
@ -54,22 +50,23 @@ export class Packet {
|
||||
});
|
||||
}
|
||||
|
||||
static createRandomCyphertext(sessionId, range, cipherText) {
|
||||
static createRandomHMAC(sessionId, range, hmac, key) {
|
||||
return this._sign({
|
||||
...this._createBase("RANDOM"),
|
||||
session: sessionId,
|
||||
range: range,
|
||||
stage: "CIPHERTEXT",
|
||||
cipherText: cipherText,
|
||||
stage: "COMMIT",
|
||||
hmac: hmac,
|
||||
key: key,
|
||||
});
|
||||
}
|
||||
|
||||
static createRandomKey(sessionId, key) {
|
||||
static createRandomNoise(sessionId, noise) {
|
||||
return this._sign({
|
||||
...this._createBase("RANDOM"),
|
||||
session: sessionId,
|
||||
stage: "DECRYPT",
|
||||
cipherKey: key,
|
||||
stage: "REVEAL",
|
||||
noise: noise,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,24 @@
|
||||
import { socket, game } from "./main.js";
|
||||
import { Packet } from "./packet.js";
|
||||
import { cryptoRandom } from "../crypto/random_primes.js";
|
||||
|
||||
class RandomSession {
|
||||
constructor(range) {
|
||||
this.range = range;
|
||||
this.cipherTexts = {};
|
||||
this.cipherKeys = {};
|
||||
this.ourKey = CryptoJS.lib.WordArray.random(32).toString();
|
||||
this.ourNoise = CryptoJS.lib.WordArray.random(8);
|
||||
this.hmacs = {};
|
||||
this.keys = {};
|
||||
this.noises = {};
|
||||
this.ourKey = cryptoRandom(1024).toString(16);
|
||||
this.ourNoise = cryptoRandom(64);
|
||||
this.finalValue = null;
|
||||
this.resolvers = [];
|
||||
}
|
||||
|
||||
cipherText() {
|
||||
return CryptoJS.AES.encrypt(this.ourNoise, this.ourKey).toString();
|
||||
hmac() {
|
||||
let hasher = new jsSHA("SHA3-256", "HEX");
|
||||
hasher.update(this.ourKey);
|
||||
hasher.update(this.ourNoise.toString(16));
|
||||
return hasher.getHash("HEX");
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +63,7 @@ export class Random {
|
||||
|
||||
socket.emit(
|
||||
"message",
|
||||
Packet.createRandomCyphertext(sessionId, n, session.cipherText())
|
||||
Packet.createRandomHMAC(sessionId, n, session.hmac(), session.ourKey)
|
||||
);
|
||||
|
||||
return session;
|
||||
@ -78,41 +83,49 @@ export class Random {
|
||||
session = this.initialiseSession(data.range, data.session);
|
||||
}
|
||||
|
||||
if (stage === "CIPHERTEXT") {
|
||||
session.cipherTexts[data.author] = data.cipherText;
|
||||
if (stage === "COMMIT") {
|
||||
session.hmacs[data.author] = data.hmac;
|
||||
session.keys[data.author] = data.key;
|
||||
|
||||
if (
|
||||
Object.keys(session.cipherTexts).length ===
|
||||
Object.keys(session.hmacs).length ===
|
||||
Object.keys(game.players).length - 1
|
||||
) {
|
||||
// Step 3: release our key once all players have sent a ciphertext
|
||||
socket.emit(
|
||||
"message",
|
||||
Packet.createRandomKey(data.session, session.ourKey)
|
||||
Packet.createRandomNoise(
|
||||
data.session,
|
||||
"0x" + session.ourNoise.toString(16)
|
||||
)
|
||||
);
|
||||
}
|
||||
} else if (stage === "DECRYPT") {
|
||||
session.cipherKeys[data.author] = data.cipherKey;
|
||||
} else if (stage === "REVEAL") {
|
||||
// Check HMAC
|
||||
let noise = BigInt(data.noise) % 2n ** 64n;
|
||||
let hasher = new jsSHA("SHA3-256", "HEX");
|
||||
hasher.update(session.keys[data.author]);
|
||||
hasher.update(noise.toString(16));
|
||||
let hash = hasher.getHash("HEX");
|
||||
|
||||
if (hash === session.hmacs[data.author]) {
|
||||
session.noises[data.author] = noise;
|
||||
}
|
||||
|
||||
// Step 4: get final random value
|
||||
if (
|
||||
Object.keys(session.cipherKeys).length ===
|
||||
Object.keys(session.noises).length ===
|
||||
Object.keys(game.players).length - 1
|
||||
) {
|
||||
// Lock out wait calls as they may resolve to never-ending promises.
|
||||
await navigator.locks.request(`random-${data.session}`, () => {
|
||||
let total = BigInt("0x" + session.ourNoise.toString());
|
||||
let total = session.ourNoise;
|
||||
|
||||
for (let participant of Object.keys(session.cipherKeys)) {
|
||||
let decrypted = CryptoJS.AES.decrypt(
|
||||
session.cipherTexts[participant],
|
||||
session.cipherKeys[participant]
|
||||
).toString();
|
||||
|
||||
total += BigInt("0x" + decrypted);
|
||||
for (let noise of Object.values(session.noises)) {
|
||||
total += noise;
|
||||
}
|
||||
|
||||
// Find first good block of bits to avoid modular bias
|
||||
// Find first good block of bits
|
||||
let blockSize = BigInt(Math.ceil(Math.log2(session.range)));
|
||||
let blockMask = 2n ** blockSize - 1n;
|
||||
|
||||
|
Reference in New Issue
Block a user