prove and verify rounds
This commit is contained in:
@ -21,31 +21,12 @@ function cryptoShuffle(l) {
|
||||
return out;
|
||||
}
|
||||
|
||||
window.cryptoShuffle = cryptoShuffle;
|
||||
|
||||
const ROUNDS = 24;
|
||||
|
||||
function proveRegions(regions) {
|
||||
// Construct prover coins
|
||||
let coins = [];
|
||||
|
||||
let regionNames = Object.keys(regions);
|
||||
for (let x = 0; x < ROUNDS; x++) {
|
||||
let psi = cryptoShuffle(structuredClone(regionNames)).join("");
|
||||
let newRegions = structuredClone(regions);
|
||||
// rearrange keys
|
||||
for (let index = 0; index < regionNames.length; index++) {
|
||||
let c = regions[psi[index]].clone();
|
||||
// re-blind
|
||||
c.update(c.pubKey.encrypt(0n));
|
||||
newRegions[regionNames[index]] = c;
|
||||
}
|
||||
coins.push(newRegions);
|
||||
}
|
||||
|
||||
function getCoins(text) {
|
||||
// Construct verifier coins
|
||||
let hasher = new jsSHA("SHA3-256", "TEXT");
|
||||
hasher.update(JSON.stringify(coins));
|
||||
hasher.update(text);
|
||||
let hash = hasher.getHash("UINT8ARRAY");
|
||||
|
||||
let verifierCoins = [];
|
||||
@ -57,14 +38,129 @@ function proveRegions(regions) {
|
||||
}
|
||||
}
|
||||
|
||||
return verifierCoins;
|
||||
}
|
||||
|
||||
window.cryptoShuffle = cryptoShuffle;
|
||||
|
||||
function proveRegions(regions) {
|
||||
// Construct prover coins
|
||||
let proofs = [];
|
||||
let privateInputs = [];
|
||||
|
||||
let regionNames = Object.keys(regions).sort();
|
||||
for (let x = 0; x < ROUNDS; x++) {
|
||||
let psi = cryptoShuffle(structuredClone(regionNames)).join("");
|
||||
let newRegions = structuredClone(regions);
|
||||
|
||||
// Rearrange keys
|
||||
for (let index = 0; index < regionNames.length; index++) {
|
||||
newRegions[regionNames[index]] = regions[psi[index]].pubKey.encrypt(
|
||||
regions[psi[index]].plainText * -1n
|
||||
);
|
||||
}
|
||||
|
||||
proofs.push(newRegions);
|
||||
privateInputs.push(psi);
|
||||
}
|
||||
|
||||
let verifierCoins = getCoins(JSON.stringify(proofs));
|
||||
|
||||
let verifications = [];
|
||||
|
||||
// Construct prover proofs
|
||||
for (let coin of verifierCoins) {
|
||||
for (let i = 0; i < ROUNDS; i++) {
|
||||
let coin = verifierCoins[i];
|
||||
let proof = proofs[i];
|
||||
let privateInput = privateInputs[i];
|
||||
|
||||
if (coin === 1) {
|
||||
// Reveal bijection and proof for zero
|
||||
let zeroProofs = {};
|
||||
|
||||
for (let i = 0; i < regionNames.length; i++) {
|
||||
let name = regionNames[i];
|
||||
let psiName = privateInput[i];
|
||||
|
||||
let c = proof[name].clone();
|
||||
c.update(regions[psiName]);
|
||||
zeroProofs[name] = c.proveNI();
|
||||
}
|
||||
|
||||
let ver = {
|
||||
psi: privateInput,
|
||||
zeroProofs: zeroProofs,
|
||||
};
|
||||
verifications.push(ver);
|
||||
} else {
|
||||
// Reveal proof for plaintext
|
||||
let valueProofs = {};
|
||||
|
||||
for (let name of regionNames) {
|
||||
valueProofs[name] = proof[name].proveNI();
|
||||
}
|
||||
|
||||
verifications.push({ valueProofs: valueProofs });
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
regions: regions,
|
||||
proofs: proofs,
|
||||
verifications: verifications,
|
||||
};
|
||||
}
|
||||
|
||||
window.proveRegions = proveRegions;
|
||||
|
||||
export function verifyRegions(obj, key) {
|
||||
let verifierCoins = getCoins(JSON.stringify(obj.proofs));
|
||||
let regions = obj.regions;
|
||||
let regionNames = Object.keys(regions).sort();
|
||||
|
||||
for (let i = 0; i < ROUNDS; i++) {
|
||||
let proof = obj.proofs[i];
|
||||
let verification = obj.verifications[i];
|
||||
|
||||
if (verifierCoins[i] === 1) {
|
||||
for (let regionName of regionNames) {
|
||||
// Undo psi
|
||||
let originalRegion = proof[regionName];
|
||||
|
||||
// Compute product
|
||||
let c = new ReadOnlyCiphertext(key, BigInt(regions[regionName]));
|
||||
c.update(new ReadOnlyCiphertext(key, BigInt(originalRegion)));
|
||||
|
||||
// Check ciphertext is zero
|
||||
let plaintext = c.verifyNI(verification.zeroProofs[regionName]);
|
||||
|
||||
if (plaintext !== 0n) {
|
||||
console.log(plaintext);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let foundOne = false;
|
||||
|
||||
for (let name of Object.keys(verification.valueProofs)) {
|
||||
let ciphertext = new ReadOnlyCiphertext(key, BigInt(proof[name]));
|
||||
let plaintext = ciphertext.verifyNI(verification.valueProofs[name]);
|
||||
if (plaintext === null) {
|
||||
return false;
|
||||
} else if (plaintext === 1n) {
|
||||
if (foundOne) {
|
||||
return false;
|
||||
} else {
|
||||
foundOne = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
window.verifyRegions = verifyRegions;
|
||||
|
||||
// verifyRegions(proveRegions({A:paillier.pubKey.encrypt(0n),B:paillier.pubKey.encrypt(1n),C:paillier.pubKey.encrypt(0n),D:paillier.pubKey.encrypt(0n),E:paillier.pubKey.encrypt(0n)}), paillier.pubKey)
|
||||
|
Reference in New Issue
Block a user