length proof working
This commit is contained in:
@ -322,16 +322,131 @@ export function proveBitLength(cipherText) {
|
||||
m >>= 1n;
|
||||
}
|
||||
|
||||
// TODO finish this
|
||||
let bitProofs = [];
|
||||
|
||||
for (let bitCommitment of bitCommitments) {
|
||||
let p = proveOneOfTwo(bitCommitment);
|
||||
bitProofs.push(p);
|
||||
}
|
||||
|
||||
return {
|
||||
cipherText: cipherText,
|
||||
bitCommitments: bitCommitments,
|
||||
bitProof: prod.proveNI(),
|
||||
prodProof: prod.proveNI(),
|
||||
bitProofs: bitProofs,
|
||||
};
|
||||
}
|
||||
|
||||
window.proveBitLength = proveBitLength;
|
||||
|
||||
export function verifyBitLength(obj, key) {
|
||||
// Check product is fine
|
||||
let prod = new ReadOnlyCiphertext(key, BigInt(obj.cipherText));
|
||||
let m = 1n;
|
||||
|
||||
for (let bit of obj.bitCommitments) {
|
||||
let cBit = new ReadOnlyCiphertext(key, BigInt(bit));
|
||||
cBit.mul(m);
|
||||
prod.update(cBit);
|
||||
|
||||
m >>= 1n;
|
||||
}
|
||||
|
||||
let p = prod.verifyNI(obj.prodProof);
|
||||
if (p !== 0n) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (let proof of obj.bitProofs) {
|
||||
let r = verifyOneOfTwo(proof, key);
|
||||
if (!r) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return obj.bitCommitments.length;
|
||||
}
|
||||
|
||||
window.verifyBitLength = verifyBitLength;
|
||||
|
||||
/**
|
||||
* Prove that a ciphertext is either a 0 or a -1
|
||||
*/
|
||||
function proveOneOfTwo(cipherText) {
|
||||
let key = cipherText.pubKey;
|
||||
let proofs = [];
|
||||
|
||||
for (let x = 0; x < ROUNDS; x++) {
|
||||
proofs.push({
|
||||
cs: cryptoShuffle([key.encrypt(0n), key.encrypt(1n)]),
|
||||
});
|
||||
}
|
||||
|
||||
let verifications = [];
|
||||
let coins = getCoins(JSON.stringify(proofs));
|
||||
|
||||
for (let x = 0; x < ROUNDS; x++) {
|
||||
let coin = coins[x];
|
||||
let proof = proofs[x];
|
||||
|
||||
if (coin === 1) {
|
||||
verifications.push({
|
||||
cProofs: proof.cs.map((p) => p.proveNI()),
|
||||
});
|
||||
} else {
|
||||
let c1Index = proof.cs.findIndex((c) => c.plainText === 1n);
|
||||
let c1 = proof.cs[c1Index].clone();
|
||||
c1.update(cipherText);
|
||||
|
||||
verifications.push({
|
||||
csIndex: c1Index,
|
||||
zeroProof: c1.proveNI(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
cipherText: cipherText,
|
||||
proofs: proofs,
|
||||
verifications: verifications,
|
||||
};
|
||||
}
|
||||
|
||||
window.proveOneOfTwo = proveOneOfTwo;
|
||||
|
||||
function verifyOneOfTwo(obj, key) {
|
||||
let coins = getCoins(JSON.stringify(obj.proofs));
|
||||
|
||||
for (let x = 0; x < ROUNDS; x++) {
|
||||
let coin = coins[x];
|
||||
let proof = obj.proofs[x];
|
||||
let verification = obj.verifications[x];
|
||||
|
||||
if (coin === 1) {
|
||||
let c1 = new ReadOnlyCiphertext(key, BigInt(proof.cs[0]));
|
||||
let p1 = c1.verifyNI(verification.cProofs[0]);
|
||||
|
||||
let c2 = new ReadOnlyCiphertext(key, BigInt(proof.cs[1]));
|
||||
let p2 = c2.verifyNI(verification.cProofs[1]);
|
||||
|
||||
if (!(p1 === 0n && p2 === 1n) && !(p2 === 0n && p1 === 1n)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
let c = new ReadOnlyCiphertext(key, BigInt(proof.cs[verification.csIndex]));
|
||||
c.update(obj.cipherText);
|
||||
let p = c.verifyNI(verification.zeroProof);
|
||||
if (p !== 0n) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
window.verifyOneOfTwo = verifyOneOfTwo;
|
||||
|
||||
/**
|
||||
* - We prove that the set contains |S| - 2 zeros, with the final pair summing to zero and sums with the original
|
||||
* set are zero.
|
||||
|
Reference in New Issue
Block a user