fortify working and verifying
This commit is contained in:
parent
9e4a57605d
commit
dee1da6fb1
@ -174,6 +174,8 @@ export class Region {
|
||||
}
|
||||
}
|
||||
|
||||
window.Region = Region;
|
||||
|
||||
const EAST = new Continent("East");
|
||||
const WEST = new Continent("West");
|
||||
|
||||
|
@ -103,11 +103,11 @@ export class Packet {
|
||||
});
|
||||
}
|
||||
|
||||
static createFortify(fortify, verification) {
|
||||
static createFortify(fortify) {
|
||||
return this._sign({
|
||||
...this._createBase("ACT"),
|
||||
action: "FORTIFY",
|
||||
fortify: fortify,
|
||||
verification: verification,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,13 @@ import { RsaPubKey } from "../crypto/rsa.js";
|
||||
import { PaillierPubKey, ReadOnlyCiphertext } from "../crypto/paillier.js";
|
||||
import { Region } from "./map.js";
|
||||
import { showDefenseDom } from "./dom.js";
|
||||
import { proveFortify, proveRange, proveRegions, verifyRegions } from "./proofs.js";
|
||||
import {
|
||||
proveFortify,
|
||||
proveRange,
|
||||
proveRegions,
|
||||
verifyFortify,
|
||||
verifyRegions,
|
||||
} from "./proofs.js";
|
||||
|
||||
// Timeout to consider a player disconnected
|
||||
const TIMEOUT = 30_000;
|
||||
@ -184,22 +190,40 @@ export class Player {
|
||||
* @param data Data received via socket
|
||||
*/
|
||||
fortify(data) {
|
||||
let sender = Region.getRegion(data.startRegion);
|
||||
let receiver = Region.getRegion(data.endRegion);
|
||||
let strength = parseInt(data.strength);
|
||||
|
||||
if (
|
||||
sender.owner === this &&
|
||||
receiver.owner === this &&
|
||||
sender.strength > strength &&
|
||||
strength > 0
|
||||
) {
|
||||
receiver.reinforce(strength);
|
||||
sender.strength -= strength;
|
||||
return true;
|
||||
} else {
|
||||
if (!verifyFortify(data.fortify, this.paillierPubKey)) {
|
||||
console.log("Failed to verify fortify!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
!Object.keys(data.fortify.fortify).reduce(
|
||||
(c, r) => c && Region.getRegion(r).owner === this,
|
||||
true
|
||||
)
|
||||
) {
|
||||
console.log("Invalid fortify");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let regionName of Object.keys(data.fortify.fortify)) {
|
||||
let region = Region.getRegion(regionName);
|
||||
|
||||
region.reinforce(
|
||||
new ReadOnlyCiphertext(
|
||||
this.paillierPubKey,
|
||||
BigInt(data.fortify.fortify[regionName])
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// request proofs
|
||||
for (let region of this.getRegions()) {
|
||||
if ([...region.neighbours.values()].find((r) => r.owner === game.us)) {
|
||||
region.requestProof();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
sendFortify(startRegion, endRegion, amount) {
|
||||
@ -209,12 +233,16 @@ export class Player {
|
||||
};
|
||||
|
||||
for (let r of this.getRegions()) {
|
||||
if (!fortify.hasOwnProperty(r)) {
|
||||
fortify[r] = new Ciphertext(this.paillierPubKey, 0n);
|
||||
if (!fortify.hasOwnProperty(r.name)) {
|
||||
fortify[r.name] = new Ciphertext(this.paillierPubKey, 0n);
|
||||
}
|
||||
}
|
||||
|
||||
socket.emit("message", Packet.createFortify(fortify, proveFortify(fortify)));
|
||||
for (let r of Object.keys(fortify)) {
|
||||
Region.getRegion(r).reinforce(fortify[r]);
|
||||
}
|
||||
|
||||
socket.emit("message", Packet.createFortify(proveFortify(fortify)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -253,7 +281,7 @@ export class Player {
|
||||
|
||||
if (data.action === "FORTIFY") {
|
||||
if (this === game.us) {
|
||||
return;
|
||||
return true;
|
||||
} else {
|
||||
return this.fortify(data);
|
||||
}
|
||||
|
@ -549,16 +549,18 @@ export function proveFortify(fortify) {
|
||||
|
||||
// Show pair is joined by edge
|
||||
let pairName = pair.sort();
|
||||
verification.pairEdgeSalt = input.edges.find(
|
||||
(e) => e.edge[0] === pairName[0] && e.edge[1] === pairName[1]
|
||||
).salt;
|
||||
verification.pairEdgeSalt =
|
||||
"0x" +
|
||||
input.edges
|
||||
.find((e) => e.edge[0] === pairName[0] && e.edge[1] === pairName[1])
|
||||
.salt.toString(16);
|
||||
|
||||
verifications.push(verification);
|
||||
} else {
|
||||
// Show isomorphism
|
||||
let edges = {};
|
||||
for (let e of input.edges) {
|
||||
edges[e.edge[0] + e.edge[1]] = e.salt;
|
||||
edges[e.edge[0] + e.edge[1]] = "0x" + e.salt.toString(16);
|
||||
}
|
||||
|
||||
let zeroProofs = {};
|
||||
@ -618,7 +620,7 @@ export function verifyFortify(obj, key) {
|
||||
// Check remaining pair sums to zero
|
||||
let pair = [...regions.values()].sort();
|
||||
let c = new ReadOnlyCiphertext(key, BigInt(proof.regions[pair[0]]));
|
||||
c.update(proof.regions[pair[1]]);
|
||||
c.update(new ReadOnlyCiphertext(key, BigInt(proof.regions[pair[1]])));
|
||||
let p = c.verifyNI(verification.pairCipherText);
|
||||
if (p !== 0n) {
|
||||
return false;
|
||||
@ -628,7 +630,7 @@ export function verifyFortify(obj, key) {
|
||||
let hasher = new jsSHA("SHA3-256", "TEXT");
|
||||
hasher.update(pair[0]);
|
||||
hasher.update(pair[1]);
|
||||
hasher.update(verification.pairEdgeSalt.toString(16));
|
||||
hasher.update(BigInt(verification.pairEdgeSalt).toString(16));
|
||||
let hash = hasher.getHash("HEX");
|
||||
|
||||
if (!proof.edges.includes(hash)) {
|
||||
@ -652,7 +654,7 @@ export function verifyFortify(obj, key) {
|
||||
// Ciphertexts match?
|
||||
for (let r of regionNames) {
|
||||
let c = new ReadOnlyCiphertext(key, BigInt(proof.regions[r]));
|
||||
c.update(fortify[psiMap[r]]);
|
||||
c.update(new ReadOnlyCiphertext(key, BigInt(fortify[psiMap[r]])));
|
||||
let p = c.verifyNI(verification.zeroProofs[r]);
|
||||
|
||||
if (p !== 0n) {
|
||||
@ -674,7 +676,7 @@ export function verifyFortify(obj, key) {
|
||||
let hasher = new jsSHA("SHA3-256", "TEXT");
|
||||
hasher.update(psiRegion);
|
||||
hasher.update(psiNeighbour);
|
||||
hasher.update(edgeSalt.toString(16));
|
||||
hasher.update(BigInt(edgeSalt).toString(16));
|
||||
let hash = hasher.getHash("HEX");
|
||||
|
||||
if (proverEdges.has(hash)) {
|
||||
|
Binary file not shown.
@ -806,6 +806,8 @@ Validating $E(m)$ is done with the proof of zero. Then it remains to prove that
|
||||
\end{enumerate}
|
||||
\end{protocol}
|
||||
|
||||
The downside of this proof over the BCDG proof \cite{bcdg1987} is that the time to perform and verify this proof grows linearly with $|m|$. However, in most cases $|m|$ should be small: i.e, $|m| \leq 5$.
|
||||
|
||||
Range proof is used in points (3), (4), and (5). In (3), this is to convince other players that the number of units is sufficient for the action. In (4), this is to show that the region is not totally depleted. In (5), this is to ensure the number of units being fortified is less than the strength of the region. All of these are performed using \hyperref[protocol4]{Protocol~\ref*{protocol4}} and by using the additive homomorphic property to subtract the lower range from $m$ first.
|
||||
|
||||
\subsection{Proving fortifications}
|
||||
|
Loading…
Reference in New Issue
Block a user