Fix bit length proof
This commit is contained in:
parent
574287d07b
commit
6005cd6aff
@ -1,6 +1,6 @@
|
|||||||
import { mod_exp } from "./math.js";
|
import { mod_exp } from "./math.js";
|
||||||
|
|
||||||
export const KEY_SIZE = 512;
|
export const KEY_SIZE = 2048;
|
||||||
|
|
||||||
export function cryptoRandom(bits) {
|
export function cryptoRandom(bits) {
|
||||||
if (bits === undefined) {
|
if (bits === undefined) {
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
proveFortify,
|
proveFortify,
|
||||||
proveRange,
|
proveRange,
|
||||||
proveRegions,
|
proveRegions,
|
||||||
|
verifyBitLength,
|
||||||
verifyFortify,
|
verifyFortify,
|
||||||
verifyRegions,
|
verifyRegions,
|
||||||
} from "./proofs.js";
|
} from "./proofs.js";
|
||||||
@ -208,12 +209,24 @@ export class Player {
|
|||||||
for (let regionName of Object.keys(data.fortify.fortify)) {
|
for (let regionName of Object.keys(data.fortify.fortify)) {
|
||||||
let region = Region.getRegion(regionName);
|
let region = Region.getRegion(regionName);
|
||||||
|
|
||||||
region.reinforce(
|
let c1 = region.strength.cipherText.clone();
|
||||||
new ReadOnlyCiphertext(
|
let c2 = new ReadOnlyCiphertext(
|
||||||
this.paillierPubKey,
|
this.paillierPubKey,
|
||||||
BigInt(data.fortify.fortify[regionName])
|
BigInt(data.fortify.fortify[regionName])
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
c1.update(c2);
|
||||||
|
|
||||||
|
let v = verifyBitLength({
|
||||||
|
...data.fortify.rangeProofs[regionName],
|
||||||
|
cipherText: c1,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (v !== null && v <= 8) {
|
||||||
|
region.reinforce(c2);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// request proofs
|
// request proofs
|
||||||
|
@ -45,6 +45,11 @@ function cryptoShuffle(l) {
|
|||||||
|
|
||||||
const ROUNDS = 24;
|
const ROUNDS = 24;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* R-S transform.
|
||||||
|
*
|
||||||
|
* Uses the hash of the proof content to produce verifier coins
|
||||||
|
*/
|
||||||
function getCoins(text) {
|
function getCoins(text) {
|
||||||
// Construct verifier coins
|
// Construct verifier coins
|
||||||
let hasher = new jsSHA("SHA3-256", "TEXT");
|
let hasher = new jsSHA("SHA3-256", "TEXT");
|
||||||
@ -186,6 +191,9 @@ 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)
|
// 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)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BCDG Range proof
|
||||||
|
*/
|
||||||
export function proveRange(cipherText, rangeUpper) {
|
export function proveRange(cipherText, rangeUpper) {
|
||||||
if (cipherText.readOnly) {
|
if (cipherText.readOnly) {
|
||||||
throw "Cannot prove range of ReadOnlyCiphertext";
|
throw "Cannot prove range of ReadOnlyCiphertext";
|
||||||
@ -322,6 +330,18 @@ export function proveBitLength(cipherText) {
|
|||||||
m >>= 1n;
|
m >>= 1n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pad out
|
||||||
|
while (bitCommitments.length < 8) {
|
||||||
|
let c = key.encrypt(0n);
|
||||||
|
bitCommitments.push(c);
|
||||||
|
|
||||||
|
let c2 = c.clone();
|
||||||
|
c2.mul(e);
|
||||||
|
prod.update(c2);
|
||||||
|
|
||||||
|
e <<= 1n;
|
||||||
|
}
|
||||||
|
|
||||||
let bitProofs = [];
|
let bitProofs = [];
|
||||||
|
|
||||||
for (let bitCommitment of bitCommitments) {
|
for (let bitCommitment of bitCommitments) {
|
||||||
@ -394,7 +414,13 @@ function proveOneOfTwo(cipherText) {
|
|||||||
cProofs: proof.cs.map((p) => p.proveNI()),
|
cProofs: proof.cs.map((p) => p.proveNI()),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let c1Index = proof.cs.findIndex((c) => c.plainText === 1n);
|
let c1Index;
|
||||||
|
if (cipherText.plainText === paillier.pubKey.n2 - 1n) {
|
||||||
|
c1Index = proof.cs.findIndex((c) => c.plainText === 1n);
|
||||||
|
} else {
|
||||||
|
c1Index = proof.cs.findIndex((c) => c.plainText === 0n);
|
||||||
|
}
|
||||||
|
|
||||||
let c1 = proof.cs[c1Index].clone();
|
let c1 = proof.cs[c1Index].clone();
|
||||||
c1.update(cipherText);
|
c1.update(cipherText);
|
||||||
|
|
||||||
@ -699,8 +725,6 @@ export function verifyFortify(obj, key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO verify range proofs
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,43 +325,43 @@
|
|||||||
console.log(`Bench done. Time per verification: ${performance.measure("pv-duration", "pv-start", "pv-end").duration / ROUNDS}`)
|
console.log(`Bench done. Time per verification: ${performance.measure("pv-duration", "pv-start", "pv-end").duration / ROUNDS}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function RangeProofBench() {
|
function BitLengthProofBench() {
|
||||||
console.log("Warming up")
|
console.log("Warming up")
|
||||||
|
|
||||||
const ct = paillier.pubKey.encrypt(5n)
|
const ct = paillier.pubKey.encrypt(5n)
|
||||||
const ROUNDS = 20;
|
const ROUNDS = 20;
|
||||||
|
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
proveRange(ct, 10n)
|
proveBitLength(ct)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Benching")
|
console.log("Benching")
|
||||||
|
|
||||||
performance.mark("rp-start")
|
performance.mark("rp-start")
|
||||||
for (let i = 0; i < ROUNDS; i++) {
|
for (let i = 0; i < ROUNDS; i++) {
|
||||||
proveRange(ct, 10n)
|
proveBitLength(ct)
|
||||||
}
|
}
|
||||||
performance.mark("rp-end")
|
performance.mark("rp-end")
|
||||||
|
|
||||||
console.log(`Bench done. Time per proof: ${performance.measure("rp-duration", "rp-start", "rp-end").duration / ROUNDS}`)
|
console.log(`Bench done. Time per proof: ${performance.measure("rp-duration", "rp-start", "rp-end").duration / ROUNDS}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function RangeVerifierBench() {
|
function BitLengthVerifierBench() {
|
||||||
console.log("Warming up")
|
console.log("Warming up")
|
||||||
|
|
||||||
const ROUNDS = 20;
|
const ROUNDS = 20;
|
||||||
const ct = paillier.pubKey.encrypt(5n)
|
const ct = paillier.pubKey.encrypt(5n)
|
||||||
let proof = proveRange(ct, 10n)
|
let proof = proveBitLength(ct)
|
||||||
|
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
verifyRange(proof, paillier.pubKey)
|
verifyBitLength(proof, paillier.pubKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Benching")
|
console.log("Benching")
|
||||||
|
|
||||||
performance.mark("rv-start")
|
performance.mark("rv-start")
|
||||||
for (let i = 0; i < ROUNDS; i++) {
|
for (let i = 0; i < ROUNDS; i++) {
|
||||||
verifyRange(proof, paillier.pubKey)
|
verifyBitLength(proof, paillier.pubKey)
|
||||||
}
|
}
|
||||||
performance.mark("rv-end")
|
performance.mark("rv-end")
|
||||||
|
|
||||||
@ -400,7 +400,7 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function RangeSize() {
|
function BitLengthSize() {
|
||||||
const ct = paillier.pubKey.encrypt(5n)
|
const ct = paillier.pubKey.encrypt(5n)
|
||||||
let ROUNDS = 10;
|
let ROUNDS = 10;
|
||||||
|
|
||||||
@ -408,7 +408,7 @@
|
|||||||
let compressedSize = 0;
|
let compressedSize = 0;
|
||||||
|
|
||||||
for (let x = 0; x < ROUNDS; x++) {
|
for (let x = 0; x < ROUNDS; x++) {
|
||||||
let s = JSON.stringify(proveRange(ct, 10n));
|
let s = JSON.stringify(proveBitLength(ct));
|
||||||
size += string_to_buffer(s).byteLength;
|
size += string_to_buffer(s).byteLength;
|
||||||
compressedSize += LZString.compressToUint8Array(s).length;
|
compressedSize += LZString.compressToUint8Array(s).length;
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -1030,6 +1030,8 @@ The other proofs do not translate so trivially to this structure however. In fac
|
|||||||
|
|
||||||
\textbf{Optimising language.} An optimising language may be able to reduce the time taken to encrypt. On the browser, this could involve using WASM as a way to execute compiled code within the browser, although WASM does not always outperform JavaScript \cite{wasm}.
|
\textbf{Optimising language.} An optimising language may be able to reduce the time taken to encrypt. On the browser, this could involve using WASM as a way to execute compiled code within the browser, although WASM does not always outperform JavaScript \cite{wasm}.
|
||||||
|
|
||||||
|
Another approach is to use a web extension to communicate with a system daemon providing the relevant functionality. This is language-agnostic (except that the extension itself must be JavaScript), and the daemon could take advantage of other system features such as multiple cores. The multi-round proofs in particular are embarrassingly parallel, as each round is independent of the other rounds.
|
||||||
|
|
||||||
\subsection{Complexity results}
|
\subsection{Complexity results}
|
||||||
|
|
||||||
All measurements were taken on Brave 1.50.114 (Chromium 112.0.5615.49) 64-bit, using a Ryzen 5 3600 CPU: a consumer CPU from 2019. Absolute timings are extremely dependent on the browser engine: for example Firefox 111.0.1 was typically 4 times slower than the results shown.
|
All measurements were taken on Brave 1.50.114 (Chromium 112.0.5615.49) 64-bit, using a Ryzen 5 3600 CPU: a consumer CPU from 2019. Absolute timings are extremely dependent on the browser engine: for example Firefox 111.0.1 was typically 4 times slower than the results shown.
|
||||||
@ -1042,9 +1044,9 @@ All measurements were taken on Brave 1.50.114 (Chromium 112.0.5615.49) 64-bit, u
|
|||||||
\label{table1}
|
\label{table1}
|
||||||
\begin{tabularx}{\hsize}{c *4{>{\Centering}X}}
|
\begin{tabularx}{\hsize}{c *4{>{\Centering}X}}
|
||||||
\toprule
|
\toprule
|
||||||
Modulus size & Na\"ive encrypt & Jacobi encrypt & Jacobi encrypt with pre-computation & RSA encrypt \\
|
Modulus size & Paillier encrypt & Jurik encrypt & Jurik encrypt with pre-computation & RSA encrypt \\
|
||||||
\midrule
|
\midrule
|
||||||
$|n| = 1024$ & 6.0ms & 4ms & 1.4ms & 0.015ms \\
|
$|n| = 1024$ & 6.0ms & 4.0ms & 1.4ms & 0.015ms \\
|
||||||
$|n| = 2048$ & 34ms & 22ms & 7.6ms & 0.040ms \\
|
$|n| = 2048$ & 34ms & 22ms & 7.6ms & 0.040ms \\
|
||||||
$|n| = 4096$ & 189ms & 128ms & -- & 0.093ms \\
|
$|n| = 4096$ & 189ms & 128ms & -- & 0.093ms \\
|
||||||
\bottomrule
|
\bottomrule
|
||||||
@ -1053,20 +1055,21 @@ All measurements were taken on Brave 1.50.114 (Chromium 112.0.5615.49) 64-bit, u
|
|||||||
|
|
||||||
\begin{table}
|
\begin{table}
|
||||||
\fontsize{10pt}{10pt}\selectfont
|
\fontsize{10pt}{10pt}\selectfont
|
||||||
\caption{Time\parnote{$|n| = 4096$ uses a less-optimised encryption method, as the browser frequently timed out attempting to pre-compute for the more-optimised version.} to process proofs}
|
\caption{Time\parnote{$|n| = 4096$ uses a less-optimised encryption method, as the browser frequently timed out attempting to pre-compute for the more-optimised version.} to process non-interactive proofs}
|
||||||
\begin{tabularx}{\hsize}{c *6{>{\Centering}X}}
|
\begin{tabularx}{\hsize}{c *8{>{\Centering}X}}
|
||||||
\toprule
|
\toprule
|
||||||
\multirow{2}{*}{Modulus size} &
|
\multirow{2}{*}{Modulus size} &
|
||||||
\multicolumn{2}{c}{Proof-of-zero non-interactive} &
|
\multicolumn{2}{c}{Proof-of-zero} &
|
||||||
\multicolumn{2}{c}{\hyperref[protocol1]{Protocol~\ref*{protocol1}} with $t = 24$} &
|
\multicolumn{2}{c}{\hyperref[protocol1]{Protocol~\ref*{protocol1}} with $t = 24$} &
|
||||||
\multicolumn{2}{c}{BCDG Range with $t = 24$}
|
\multicolumn{2}{c}{BCDG Range with $t = 24$} &
|
||||||
|
\multicolumn{2}{c}{\hyperref[protocol1]{Protocol~\ref*{protocol4}} with $t = 24$}
|
||||||
\tabularnewline
|
\tabularnewline
|
||||||
\cmidrule(l){2-3}\cmidrule(l){4-5}\cmidrule(l){6-7}
|
\cmidrule(l){2-3}\cmidrule(l){4-5}\cmidrule(l){6-7}\cmidrule(l){8-9}
|
||||||
& Prover & Verifier & Prover & Verifier & Prover & Verifier \\
|
& Prover & Verifier & Prover & Verifier & Prover & Verifier & Prover & Verifier \\
|
||||||
\midrule
|
\midrule
|
||||||
$|n| = 1024$ & 10ms & 18ms & 1,420ms & 2,140ms & 443ms & 655ms \\
|
$|n| = 1024$ & 10ms & 18ms & 1,420ms & 2,140ms & 443ms & 655ms & 3,530ms & 5,310ms \\
|
||||||
$|n| = 2048$ & 44ms & 68ms & 6,390ms & 8,140ms & 1,980ms & 2,400ms \\
|
$|n| = 2048$ & 44ms & 68ms & 6,390ms & 8,140ms & 1,980ms & 2,400ms & 15,800ms & 19,000ms \\
|
||||||
$|n| = 4096$ & 225ms & 292ms & 41,500ms & 34,400ms & 14,300ms & 11,400ms \\
|
$|n| = 4096$ & 225ms & 292ms & 41,500ms & 34,400ms & 14,300ms & 11,400ms & & \\
|
||||||
\bottomrule
|
\bottomrule
|
||||||
\end{tabularx}
|
\end{tabularx}
|
||||||
\parnotes
|
\parnotes
|
||||||
@ -1074,18 +1077,18 @@ All measurements were taken on Brave 1.50.114 (Chromium 112.0.5615.49) 64-bit, u
|
|||||||
|
|
||||||
\begin{table}
|
\begin{table}
|
||||||
\fontsize{10pt}{10pt}\selectfont
|
\fontsize{10pt}{10pt}\selectfont
|
||||||
\caption{Byte size\parnote{1 UTF-16 character, as used by ECMAScript \cite[Section~6.1.4]{ecma2024262}, is 2 or more bytes.} of encoded proofs}
|
\caption{Byte size\parnote{1 UTF-16 character, as used by ECMAScript \cite[Section~6.1.4]{ecma2024262}, is 2 or more bytes.} of encoded non-interactive proofs}
|
||||||
\label{table3}
|
\label{table3}
|
||||||
\begin{tabularx}{\hsize}{c *6{>{\Centering}X}}
|
\begin{tabularx}{\hsize}{c *8{>{\Centering}X}}
|
||||||
\toprule
|
\toprule
|
||||||
\multirow{2}{*}{Modulus size} & \multicolumn{2}{c}{Proof-of-zero non-interactive} & \multicolumn{2}{c}{\hyperref[protocol1]{Protocol~\ref*{protocol1}} with $t = 24$} & \multicolumn{2}{c}{BCDG Range with $t = 24$}
|
\multirow{2}{*}{Modulus size} & \multicolumn{2}{c}{Proof-of-zero non-interactive} & \multicolumn{2}{c}{\hyperref[protocol1]{Protocol~\ref*{protocol1}} with $t = 24$} & \multicolumn{2}{c}{BCDG Range with $t = 24$} & \multicolumn{2}{c}{\hyperref[protocol1]{Protocol~\ref*{protocol4}} with $t = 24$}
|
||||||
\tabularnewline
|
\tabularnewline
|
||||||
\cmidrule(l){2-3}\cmidrule(l){4-5}\cmidrule(l){6-7}
|
\cmidrule(l){2-3}\cmidrule(l){4-5}\cmidrule(l){6-7}\cmidrule(l){8-9}
|
||||||
& JSON & with LZ-String & JSON & with LZ-String & JSON & with LZ-String \\
|
& JSON & with LZ-String & JSON & with LZ-String & JSON & with LZ-String & JSON & with LZ-String \\
|
||||||
\midrule
|
\midrule
|
||||||
$|n| = 1024$ & 1,617B & 576B & 338,902B & 95,738B & 123,354B & 34,857B \\
|
$|n| = 1024$ & 1,617B & 576B & 338,902B & 95,738B & 123,354B & 34,857B & 895,474B & 248,420B \\
|
||||||
$|n| = 2048$ & 3,153B & 1,050B & 662,233B & 187,333B & 252,230B & 70,868B \\
|
$|n| = 2048$ & 3,153B & 1,050B & 662,233B & 187,333B & 252,230B & 70,868B & 1,746,017B & 485,787B \\
|
||||||
$|n| = 4096$ & 6,226B & 1,999B & 1,315,027B & 368,646B & 484,117B & 135,990B \\
|
$|n| = 4096$ & 6,226B & 1,999B & 1,315,027B & 368,646B & 484,117B & 135,990B & & \\
|
||||||
\bottomrule
|
\bottomrule
|
||||||
\end{tabularx}
|
\end{tabularx}
|
||||||
\parnotes
|
\parnotes
|
||||||
|
Loading…
Reference in New Issue
Block a user