readme, benchmarks, fix verification
This commit is contained in:
parent
35dbf321e9
commit
ad26788927
31
README.md
Normal file
31
README.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Riskless
|
||||||
|
### Undergraduate dissertation
|
||||||
|
|
||||||
|
**Paper: https://judesouthworth.xyz/Dissertation.pdf**
|
||||||
|
|
||||||
|
## Running the demo
|
||||||
|
|
||||||
|
1. `pip install -r requirements.txt`
|
||||||
|
2. `python3 app.py`
|
||||||
|
3. Navigate browser to `http://localhost:5000`
|
||||||
|
|
||||||
|
### Running the benchmarks
|
||||||
|
|
||||||
|
1. Press F12
|
||||||
|
2. Type the name of the benchmark to run:
|
||||||
|
- `RSABench`
|
||||||
|
- `PaillierBench`
|
||||||
|
- `ZeroProofBench`
|
||||||
|
- `ZeroProofVerifierBench`
|
||||||
|
- `ZeroProofSizeBench`
|
||||||
|
- `Protocol4Bench`
|
||||||
|
- `Protocol4VerifierBench`
|
||||||
|
- `Protocol4SizeBench`
|
||||||
|
3. Wait for results to output in milliseconds
|
||||||
|
|
||||||
|
### Changing the key size
|
||||||
|
|
||||||
|
The key size is determined by the variable `KEY_SIZE` in `random_primes.js`. This
|
||||||
|
variable dictates the size of _each_ prime used in the modulus, so the total key size
|
||||||
|
is twice this value. Recommend selecting one of 512, 1024, or 2048. In fact, I recommend
|
||||||
|
selecting 512 if you want the program to run in less than 3-5 business days.
|
309
static/js/lz-string.js
Normal file
309
static/js/lz-string.js
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
var LZString = (function () {
|
||||||
|
var r = String.fromCharCode,
|
||||||
|
o = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
||||||
|
n = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$",
|
||||||
|
e = {};
|
||||||
|
function t(r, o) {
|
||||||
|
if (!e[r]) {
|
||||||
|
e[r] = {};
|
||||||
|
for (var n = 0; n < r.length; n++) e[r][r.charAt(n)] = n;
|
||||||
|
}
|
||||||
|
return e[r][o];
|
||||||
|
}
|
||||||
|
var i = {
|
||||||
|
compressToBase64: function (r) {
|
||||||
|
if (null == r) return "";
|
||||||
|
var n = i._compress(r, 6, function (r) {
|
||||||
|
return o.charAt(r);
|
||||||
|
});
|
||||||
|
switch (n.length % 4) {
|
||||||
|
default:
|
||||||
|
case 0:
|
||||||
|
return n;
|
||||||
|
case 1:
|
||||||
|
return n + "===";
|
||||||
|
case 2:
|
||||||
|
return n + "==";
|
||||||
|
case 3:
|
||||||
|
return n + "=";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
decompressFromBase64: function (r) {
|
||||||
|
return null == r
|
||||||
|
? ""
|
||||||
|
: "" == r
|
||||||
|
? null
|
||||||
|
: i._decompress(r.length, 32, function (n) {
|
||||||
|
return t(o, r.charAt(n));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
compressToUTF16: function (o) {
|
||||||
|
return null == o
|
||||||
|
? ""
|
||||||
|
: i._compress(o, 15, function (o) {
|
||||||
|
return r(o + 32);
|
||||||
|
}) + " ";
|
||||||
|
},
|
||||||
|
decompressFromUTF16: function (r) {
|
||||||
|
return null == r
|
||||||
|
? ""
|
||||||
|
: "" == r
|
||||||
|
? null
|
||||||
|
: i._decompress(r.length, 16384, function (o) {
|
||||||
|
return r.charCodeAt(o) - 32;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
compressToUint8Array: function (r) {
|
||||||
|
for (
|
||||||
|
var o = i.compress(r),
|
||||||
|
n = new Uint8Array(2 * o.length),
|
||||||
|
e = 0,
|
||||||
|
t = o.length;
|
||||||
|
e < t;
|
||||||
|
e++
|
||||||
|
) {
|
||||||
|
var s = o.charCodeAt(e);
|
||||||
|
(n[2 * e] = s >>> 8), (n[2 * e + 1] = s % 256);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
},
|
||||||
|
decompressFromUint8Array: function (o) {
|
||||||
|
if (null == o) return i.decompress(o);
|
||||||
|
for (var n = new Array(o.length / 2), e = 0, t = n.length; e < t; e++)
|
||||||
|
n[e] = 256 * o[2 * e] + o[2 * e + 1];
|
||||||
|
var s = [];
|
||||||
|
return (
|
||||||
|
n.forEach(function (o) {
|
||||||
|
s.push(r(o));
|
||||||
|
}),
|
||||||
|
i.decompress(s.join(""))
|
||||||
|
);
|
||||||
|
},
|
||||||
|
compressToEncodedURIComponent: function (r) {
|
||||||
|
return null == r
|
||||||
|
? ""
|
||||||
|
: i._compress(r, 6, function (r) {
|
||||||
|
return n.charAt(r);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
decompressFromEncodedURIComponent: function (r) {
|
||||||
|
return null == r
|
||||||
|
? ""
|
||||||
|
: "" == r
|
||||||
|
? null
|
||||||
|
: ((r = r.replace(/ /g, "+")),
|
||||||
|
i._decompress(r.length, 32, function (o) {
|
||||||
|
return t(n, r.charAt(o));
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
compress: function (o) {
|
||||||
|
return i._compress(o, 16, function (o) {
|
||||||
|
return r(o);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_compress: function (r, o, n) {
|
||||||
|
if (null == r) return "";
|
||||||
|
var e,
|
||||||
|
t,
|
||||||
|
i,
|
||||||
|
s = {},
|
||||||
|
u = {},
|
||||||
|
a = "",
|
||||||
|
p = "",
|
||||||
|
c = "",
|
||||||
|
l = 2,
|
||||||
|
f = 3,
|
||||||
|
h = 2,
|
||||||
|
d = [],
|
||||||
|
m = 0,
|
||||||
|
v = 0;
|
||||||
|
for (i = 0; i < r.length; i += 1)
|
||||||
|
if (
|
||||||
|
((a = r.charAt(i)),
|
||||||
|
Object.prototype.hasOwnProperty.call(s, a) ||
|
||||||
|
((s[a] = f++), (u[a] = !0)),
|
||||||
|
(p = c + a),
|
||||||
|
Object.prototype.hasOwnProperty.call(s, p))
|
||||||
|
)
|
||||||
|
c = p;
|
||||||
|
else {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(u, c)) {
|
||||||
|
if (c.charCodeAt(0) < 256) {
|
||||||
|
for (e = 0; e < h; e++)
|
||||||
|
(m <<= 1),
|
||||||
|
v == o - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++;
|
||||||
|
for (t = c.charCodeAt(0), e = 0; e < 8; e++)
|
||||||
|
(m = (m << 1) | (1 & t)),
|
||||||
|
v == o - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
|
||||||
|
(t >>= 1);
|
||||||
|
} else {
|
||||||
|
for (t = 1, e = 0; e < h; e++)
|
||||||
|
(m = (m << 1) | t),
|
||||||
|
v == o - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
|
||||||
|
(t = 0);
|
||||||
|
for (t = c.charCodeAt(0), e = 0; e < 16; e++)
|
||||||
|
(m = (m << 1) | (1 & t)),
|
||||||
|
v == o - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
|
||||||
|
(t >>= 1);
|
||||||
|
}
|
||||||
|
0 == --l && ((l = Math.pow(2, h)), h++), delete u[c];
|
||||||
|
} else
|
||||||
|
for (t = s[c], e = 0; e < h; e++)
|
||||||
|
(m = (m << 1) | (1 & t)),
|
||||||
|
v == o - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
|
||||||
|
(t >>= 1);
|
||||||
|
0 == --l && ((l = Math.pow(2, h)), h++),
|
||||||
|
(s[p] = f++),
|
||||||
|
(c = String(a));
|
||||||
|
}
|
||||||
|
if ("" !== c) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(u, c)) {
|
||||||
|
if (c.charCodeAt(0) < 256) {
|
||||||
|
for (e = 0; e < h; e++)
|
||||||
|
(m <<= 1),
|
||||||
|
v == o - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++;
|
||||||
|
for (t = c.charCodeAt(0), e = 0; e < 8; e++)
|
||||||
|
(m = (m << 1) | (1 & t)),
|
||||||
|
v == o - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
|
||||||
|
(t >>= 1);
|
||||||
|
} else {
|
||||||
|
for (t = 1, e = 0; e < h; e++)
|
||||||
|
(m = (m << 1) | t),
|
||||||
|
v == o - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
|
||||||
|
(t = 0);
|
||||||
|
for (t = c.charCodeAt(0), e = 0; e < 16; e++)
|
||||||
|
(m = (m << 1) | (1 & t)),
|
||||||
|
v == o - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
|
||||||
|
(t >>= 1);
|
||||||
|
}
|
||||||
|
0 == --l && ((l = Math.pow(2, h)), h++), delete u[c];
|
||||||
|
} else
|
||||||
|
for (t = s[c], e = 0; e < h; e++)
|
||||||
|
(m = (m << 1) | (1 & t)),
|
||||||
|
v == o - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
|
||||||
|
(t >>= 1);
|
||||||
|
0 == --l && ((l = Math.pow(2, h)), h++);
|
||||||
|
}
|
||||||
|
for (t = 2, e = 0; e < h; e++)
|
||||||
|
(m = (m << 1) | (1 & t)),
|
||||||
|
v == o - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
|
||||||
|
(t >>= 1);
|
||||||
|
for (;;) {
|
||||||
|
if (((m <<= 1), v == o - 1)) {
|
||||||
|
d.push(n(m));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
v++;
|
||||||
|
}
|
||||||
|
return d.join("");
|
||||||
|
},
|
||||||
|
decompress: function (r) {
|
||||||
|
return null == r
|
||||||
|
? ""
|
||||||
|
: "" == r
|
||||||
|
? null
|
||||||
|
: i._decompress(r.length, 32768, function (o) {
|
||||||
|
return r.charCodeAt(o);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_decompress: function (o, n, e) {
|
||||||
|
var t,
|
||||||
|
i,
|
||||||
|
s,
|
||||||
|
u,
|
||||||
|
a,
|
||||||
|
p,
|
||||||
|
c,
|
||||||
|
l = [],
|
||||||
|
f = 4,
|
||||||
|
h = 4,
|
||||||
|
d = 3,
|
||||||
|
m = "",
|
||||||
|
v = [],
|
||||||
|
g = { val: e(0), position: n, index: 1 };
|
||||||
|
for (t = 0; t < 3; t += 1) l[t] = t;
|
||||||
|
for (s = 0, a = Math.pow(2, 2), p = 1; p != a; )
|
||||||
|
(u = g.val & g.position),
|
||||||
|
(g.position >>= 1),
|
||||||
|
0 == g.position && ((g.position = n), (g.val = e(g.index++))),
|
||||||
|
(s |= (u > 0 ? 1 : 0) * p),
|
||||||
|
(p <<= 1);
|
||||||
|
switch (s) {
|
||||||
|
case 0:
|
||||||
|
for (s = 0, a = Math.pow(2, 8), p = 1; p != a; )
|
||||||
|
(u = g.val & g.position),
|
||||||
|
(g.position >>= 1),
|
||||||
|
0 == g.position && ((g.position = n), (g.val = e(g.index++))),
|
||||||
|
(s |= (u > 0 ? 1 : 0) * p),
|
||||||
|
(p <<= 1);
|
||||||
|
c = r(s);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
for (s = 0, a = Math.pow(2, 16), p = 1; p != a; )
|
||||||
|
(u = g.val & g.position),
|
||||||
|
(g.position >>= 1),
|
||||||
|
0 == g.position && ((g.position = n), (g.val = e(g.index++))),
|
||||||
|
(s |= (u > 0 ? 1 : 0) * p),
|
||||||
|
(p <<= 1);
|
||||||
|
c = r(s);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
for (l[3] = c, i = c, v.push(c); ; ) {
|
||||||
|
if (g.index > o) return "";
|
||||||
|
for (s = 0, a = Math.pow(2, d), p = 1; p != a; )
|
||||||
|
(u = g.val & g.position),
|
||||||
|
(g.position >>= 1),
|
||||||
|
0 == g.position && ((g.position = n), (g.val = e(g.index++))),
|
||||||
|
(s |= (u > 0 ? 1 : 0) * p),
|
||||||
|
(p <<= 1);
|
||||||
|
switch ((c = s)) {
|
||||||
|
case 0:
|
||||||
|
for (s = 0, a = Math.pow(2, 8), p = 1; p != a; )
|
||||||
|
(u = g.val & g.position),
|
||||||
|
(g.position >>= 1),
|
||||||
|
0 == g.position &&
|
||||||
|
((g.position = n), (g.val = e(g.index++))),
|
||||||
|
(s |= (u > 0 ? 1 : 0) * p),
|
||||||
|
(p <<= 1);
|
||||||
|
(l[h++] = r(s)), (c = h - 1), f--;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
for (s = 0, a = Math.pow(2, 16), p = 1; p != a; )
|
||||||
|
(u = g.val & g.position),
|
||||||
|
(g.position >>= 1),
|
||||||
|
0 == g.position &&
|
||||||
|
((g.position = n), (g.val = e(g.index++))),
|
||||||
|
(s |= (u > 0 ? 1 : 0) * p),
|
||||||
|
(p <<= 1);
|
||||||
|
(l[h++] = r(s)), (c = h - 1), f--;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
return v.join("");
|
||||||
|
}
|
||||||
|
if ((0 == f && ((f = Math.pow(2, d)), d++), l[c])) m = l[c];
|
||||||
|
else {
|
||||||
|
if (c !== h) return null;
|
||||||
|
m = i + i.charAt(0);
|
||||||
|
}
|
||||||
|
v.push(m),
|
||||||
|
(l[h++] = i + m.charAt(0)),
|
||||||
|
(i = m),
|
||||||
|
0 == --f && ((f = Math.pow(2, d)), d++);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return i;
|
||||||
|
})();
|
||||||
|
"function" == typeof define && define.amd
|
||||||
|
? define(function () {
|
||||||
|
return LZString;
|
||||||
|
})
|
||||||
|
: "undefined" != typeof module && null != module
|
||||||
|
? (module.exports = LZString)
|
||||||
|
: "undefined" != typeof angular &&
|
||||||
|
null != angular &&
|
||||||
|
angular.module("LZString", []).factory("LZString", function () {
|
||||||
|
return LZString;
|
||||||
|
});
|
@ -4,6 +4,25 @@ import { gcd, mod_exp } from "./math.js";
|
|||||||
const PAILLIER = 0;
|
const PAILLIER = 0;
|
||||||
const JURIK = 1;
|
const JURIK = 1;
|
||||||
|
|
||||||
|
function RSTransform(g, a, p) {
|
||||||
|
let plainText = p.toString(16);
|
||||||
|
if (plainText.length % 2 !== 0) {
|
||||||
|
plainText = "0" + plainText;
|
||||||
|
}
|
||||||
|
|
||||||
|
let aStr = a.toString(16);
|
||||||
|
if (aStr.length % 2 !== 0) {
|
||||||
|
aStr = "0" + aStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
let hasher = new jsSHA("SHAKE256", "HEX");
|
||||||
|
hasher.update(g.toString(16));
|
||||||
|
hasher.update(plainText);
|
||||||
|
hasher.update(aStr);
|
||||||
|
|
||||||
|
return BigInt("0x" + hasher.getHash("HEX", { outputLen: 2048 }));
|
||||||
|
}
|
||||||
|
|
||||||
class Ciphertext {
|
class Ciphertext {
|
||||||
constructor(key, plainText, r, set) {
|
constructor(key, plainText, r, set) {
|
||||||
if (set !== undefined) {
|
if (set !== undefined) {
|
||||||
@ -93,28 +112,12 @@ class Ciphertext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let a = mod_exp(rp, this.pubKey.n, this.pubKey.n2);
|
let a = mod_exp(rp, this.pubKey.n, this.pubKey.n2);
|
||||||
let hasher = new jsSHA("SHAKE256", "HEX");
|
|
||||||
|
|
||||||
let plainText = this.plainText.toString(16);
|
let challenge = RSTransform(this.pubKey.g, a, this.plainText);
|
||||||
if (plainText.length % 2 !== 0) {
|
|
||||||
plainText = "0" + plainText;
|
|
||||||
}
|
|
||||||
|
|
||||||
let aStr = a.toString(16);
|
|
||||||
if (aStr.length % 2 !== 0) {
|
|
||||||
aStr = "0" + aStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasher.update(this.pubKey.g.toString(16));
|
|
||||||
hasher.update(plainText);
|
|
||||||
hasher.update(aStr);
|
|
||||||
|
|
||||||
let challenge = BigInt("0x" + hasher.getHash("HEX", { outputLen: 2048 }));
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
plainText: "0x" + this.plainText.toString(16),
|
plainText: "0x" + this.plainText.toString(16),
|
||||||
a: "0x" + a.toString(16),
|
a: "0x" + a.toString(16),
|
||||||
challenge: "0x" + challenge.toString(16),
|
|
||||||
proof:
|
proof:
|
||||||
"0x" +
|
"0x" +
|
||||||
(
|
(
|
||||||
@ -195,11 +198,17 @@ export class ReadOnlyCiphertext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
verifyNI(statement) {
|
verifyNI(statement) {
|
||||||
|
let challenge = RSTransform(
|
||||||
|
this.pubKey.g,
|
||||||
|
BigInt(statement.a),
|
||||||
|
BigInt(statement.plainText)
|
||||||
|
);
|
||||||
|
|
||||||
let verifier = new ValueProofSessionVerifier(
|
let verifier = new ValueProofSessionVerifier(
|
||||||
this,
|
this,
|
||||||
BigInt(statement.plainText),
|
BigInt(statement.plainText),
|
||||||
BigInt(statement.a),
|
BigInt(statement.a),
|
||||||
BigInt(statement.challenge)
|
challenge
|
||||||
);
|
);
|
||||||
|
|
||||||
if (verifier.verify(BigInt(statement.proof))) {
|
if (verifier.verify(BigInt(statement.proof))) {
|
||||||
|
@ -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) {
|
||||||
|
@ -135,7 +135,6 @@ export function verifyRegions(obj, key) {
|
|||||||
let plaintext = c.verifyNI(verification.zeroProofs[regionName]);
|
let plaintext = c.verifyNI(verification.zeroProofs[regionName]);
|
||||||
|
|
||||||
if (plaintext !== 0n) {
|
if (plaintext !== 0n) {
|
||||||
console.log(plaintext);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
|
<script src="https://cdn.socket.io/4.5.4/socket.io.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
||||||
<script src="{{ url_for('static', filename='js/sha3.js') }}" type="module"></script>
|
<script src="{{ url_for('static', filename='js/lz-string.js') }}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/sha3.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/modules/interface/main.js') }}" type="module"></script>
|
<script src="{{ url_for('static', filename='js/modules/interface/main.js') }}" type="module"></script>
|
||||||
<script src="{{ url_for('static', filename='js/modules/crypto/main.js') }}" type="module"></script>
|
<script src="{{ url_for('static', filename='js/modules/crypto/main.js') }}" type="module"></script>
|
||||||
</head>
|
</head>
|
||||||
@ -188,6 +189,8 @@
|
|||||||
function RSABench() {
|
function RSABench() {
|
||||||
console.log("Warming up")
|
console.log("Warming up")
|
||||||
|
|
||||||
|
const ROUNDS = 250;
|
||||||
|
|
||||||
for (let i = 0n; i < 100n; i++) {
|
for (let i = 0n; i < 100n; i++) {
|
||||||
window.rsa.pubKey.encrypt(i);
|
window.rsa.pubKey.encrypt(i);
|
||||||
}
|
}
|
||||||
@ -195,17 +198,19 @@
|
|||||||
console.log("Benching")
|
console.log("Benching")
|
||||||
|
|
||||||
performance.mark("rsa-start")
|
performance.mark("rsa-start")
|
||||||
for (let i = 0n; i < 250n; i++) {
|
for (let i = 0n; i < BigInt(ROUNDS); i++) {
|
||||||
window.rsa.pubKey.encrypt(i);
|
window.rsa.pubKey.encrypt(i);
|
||||||
}
|
}
|
||||||
performance.mark("rsa-end")
|
performance.mark("rsa-end")
|
||||||
|
|
||||||
console.log(`Bench done. Duration: ${performance.measure("rsa-duration", "rsa-start", "rsa-end").duration}`)
|
console.log(`Bench done. Time per encrypt: ${performance.measure("rsa-duration", "rsa-start", "rsa-end").duration / ROUNDS}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function PaillierBench() {
|
function PaillierBench() {
|
||||||
console.log("Warming up")
|
console.log("Warming up")
|
||||||
|
|
||||||
|
const ROUNDS = 250
|
||||||
|
|
||||||
for (let i = 0n; i < 100n; i++) {
|
for (let i = 0n; i < 100n; i++) {
|
||||||
window.paillier.pubKey.encrypt(i);
|
window.paillier.pubKey.encrypt(i);
|
||||||
}
|
}
|
||||||
@ -213,12 +218,162 @@
|
|||||||
console.log("Benching")
|
console.log("Benching")
|
||||||
|
|
||||||
performance.mark("paillier-start")
|
performance.mark("paillier-start")
|
||||||
for (let i = 0n; i < 250n; i++) {
|
for (let i = 0n; i < BigInt(ROUNDS); i++) {
|
||||||
window.paillier.pubKey.encrypt(i);
|
window.paillier.pubKey.encrypt(i);
|
||||||
}
|
}
|
||||||
performance.mark("paillier-end")
|
performance.mark("paillier-end")
|
||||||
|
|
||||||
console.log(`Bench done. Duration: ${performance.measure("paillier-duration", "paillier-start", "paillier-end").duration}`)
|
console.log(`Bench done. Time per encrypt: ${performance.measure("paillier-duration", "paillier-start", "paillier-end").duration / ROUNDS}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ZeroProofBench() {
|
||||||
|
console.log("Warming up")
|
||||||
|
|
||||||
|
const cipherText = paillier.pubKey.encrypt(0n)
|
||||||
|
const ROUNDS = 20;
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
cipherText.proveNI();
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Benching")
|
||||||
|
|
||||||
|
performance.mark("paillier-start")
|
||||||
|
for (let i = 0; i < ROUNDS; i++) {
|
||||||
|
cipherText.proveNI()
|
||||||
|
}
|
||||||
|
performance.mark("paillier-end")
|
||||||
|
|
||||||
|
console.log(`Bench done. Time per proof: ${performance.measure("paillier-duration", "paillier-start", "paillier-end").duration / ROUNDS}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ZeroProofVerifierBench() {
|
||||||
|
console.log("Warming up")
|
||||||
|
const ROUNDS = 20
|
||||||
|
|
||||||
|
const cipherText = paillier.pubKey.encrypt(1n)
|
||||||
|
const readOnly = cipherText.asReadOnlyCiphertext();
|
||||||
|
const proof = cipherText.proveNI()
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
readOnly.verifyNI(proof)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Benching")
|
||||||
|
|
||||||
|
performance.mark("paillier-start")
|
||||||
|
for (let i = 0; i < ROUNDS; i++) {
|
||||||
|
readOnly.verifyNI(proof)
|
||||||
|
}
|
||||||
|
performance.mark("paillier-end")
|
||||||
|
|
||||||
|
console.log(`Bench done. Time per verification: ${performance.measure("paillier-duration", "paillier-start", "paillier-end").duration / ROUNDS}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Protocol4Bench() {
|
||||||
|
console.log("Warming up")
|
||||||
|
|
||||||
|
const regions = {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
const ROUNDS = 20;
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
proveRegions(regions)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Benching")
|
||||||
|
|
||||||
|
performance.mark("paillier-start")
|
||||||
|
for (let i = 0; i < ROUNDS; i++) {
|
||||||
|
proveRegions(regions)
|
||||||
|
}
|
||||||
|
performance.mark("paillier-end")
|
||||||
|
|
||||||
|
console.log(`Bench done. Time per proof: ${performance.measure("paillier-duration", "paillier-start", "paillier-end").duration / ROUNDS}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Protocol4VerifierBench() {
|
||||||
|
console.log("Warming up")
|
||||||
|
|
||||||
|
const ROUNDS = 20;
|
||||||
|
const regions = {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
let proof = proveRegions(regions)
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
verifyRegions(proof, paillier.pubKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Benching")
|
||||||
|
|
||||||
|
performance.mark("paillier-start")
|
||||||
|
for (let i = 0; i < ROUNDS; i++) {
|
||||||
|
verifyRegions(proof, paillier.pubKey)
|
||||||
|
}
|
||||||
|
performance.mark("paillier-end")
|
||||||
|
|
||||||
|
console.log(`Bench done. Time per verification: ${performance.measure("paillier-duration", "paillier-start", "paillier-end").duration / ROUNDS}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://gist.github.com/kawanet/352a2ed1d1656816b2bc
|
||||||
|
function string_to_buffer(src) {
|
||||||
|
return (new Uint16Array([].map.call(src, function(c) {
|
||||||
|
return c.charCodeAt(0)
|
||||||
|
}))).buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Protocol4Size() {
|
||||||
|
const regions = {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
let ROUNDS = 10;
|
||||||
|
|
||||||
|
let size = 0;
|
||||||
|
let compressedSize = 0;
|
||||||
|
|
||||||
|
for (let x = 0; x < ROUNDS; x++) {
|
||||||
|
let s = JSON.stringify(proveRegions(regions));
|
||||||
|
size += string_to_buffer(s).byteLength;
|
||||||
|
compressedSize += LZString.compressToUint8Array(s).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
size: size / ROUNDS,
|
||||||
|
compressedSize: compressedSize / ROUNDS
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function ZeroProofSize() {
|
||||||
|
const ROUNDS = 100;
|
||||||
|
const cipherText = paillier.pubKey.encrypt(0n)
|
||||||
|
|
||||||
|
let size = 0;
|
||||||
|
let compressedSize = 0;
|
||||||
|
|
||||||
|
for (let x = 0; x < ROUNDS; x++) {
|
||||||
|
let s = JSON.stringify(cipherText.proveNI());
|
||||||
|
size += string_to_buffer(s).byteLength;
|
||||||
|
compressedSize += LZString.compressToUint8Array(s).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
size: size / ROUNDS,
|
||||||
|
compressedSize: compressedSize / ROUNDS
|
||||||
|
};
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
Binary file not shown.
@ -8,6 +8,11 @@
|
|||||||
\usepackage{amsthm}
|
\usepackage{amsthm}
|
||||||
\usepackage{tikz}
|
\usepackage{tikz}
|
||||||
\usepackage{minted}
|
\usepackage{minted}
|
||||||
|
\usepackage{multirow}
|
||||||
|
\usepackage{tabularx}
|
||||||
|
\usepackage{booktabs}
|
||||||
|
\usepackage{ragged2e}
|
||||||
|
\usepackage[alph]{parnotes}
|
||||||
|
|
||||||
\DeclareMathOperator{\lcm}{lcm}
|
\DeclareMathOperator{\lcm}{lcm}
|
||||||
\DeclareMathOperator{\id}{id}
|
\DeclareMathOperator{\id}{id}
|
||||||
@ -598,18 +603,52 @@ The other proofs do not translate so trivially to this structure however. In fac
|
|||||||
|
|
||||||
\subsection{Complexity results}
|
\subsection{Complexity results}
|
||||||
|
|
||||||
All measurements taken on Brave 1.50.114 (Chromium 112.0.5615.49) 64-bit, using a Ryzen 5 3600 CPU.
|
All measurements taken on Brave 1.50.114 (Chromium 112.0.5615.49) 64-bit, using a Ryzen 5 3600 CPU. Absolute timings are extremely dependent on the browser engine: for example Firefox 111.0.1 was typically 4 times slower than the results shown.
|
||||||
|
|
||||||
\begin{center}
|
\begin{table}[htp]
|
||||||
\begin{tabular}{|c|c|c|c|}
|
\fontsize{10pt}{10pt}\selectfont
|
||||||
\hline
|
\caption{Time to encrypt}
|
||||||
Modulus size & Na\"ive encrypt & Jacobi encrypt & RSA encrypt \\\hline
|
\begin{tabularx}{\textwidth}{c *3{>{\Centering}X}}
|
||||||
|
\toprule
|
||||||
|
Modulus size & Na\"ive encrypt & Jacobi encrypt & RSA encrypt \\
|
||||||
|
\midrule
|
||||||
$|n| = 1024$ & 6ms & 4ms & <1ms \\
|
$|n| = 1024$ & 6ms & 4ms & <1ms \\
|
||||||
$|n| = 2048$ & 34ms & 22ms & <1ms \\
|
$|n| = 2048$ & 34ms & 22ms & <1ms \\
|
||||||
$|n| = 4096$ & 189ms & 128ms & <1ms \\
|
$|n| = 4096$ & 189ms & 128ms & <1ms \\
|
||||||
\hline
|
\bottomrule
|
||||||
\end{tabular}
|
\end{tabularx}
|
||||||
\end{center}
|
\end{table}
|
||||||
|
|
||||||
|
\begin{table}[htp]
|
||||||
|
\fontsize{10pt}{10pt}\selectfont
|
||||||
|
\caption{Time to process proofs}
|
||||||
|
\begin{tabularx}{\textwidth}{c *4{>{\Centering}X}}
|
||||||
|
\toprule
|
||||||
|
\multirow{2}{*}{Modulus size} & \multicolumn{2}{c}{Proof-of-zero non-interactive} & \multicolumn{2}{c}{\hyperref[protocol1]{Protocol~\ref*{protocol1}} with $t = 24$} \tabularnewline \cmidrule(l){2-3}\cmidrule(l){4-5}
|
||||||
|
& Prover & Verifier & Prover & Verifier \\
|
||||||
|
\midrule
|
||||||
|
$|n| = 1024$ & 10ms & 18ms & 1,740ms & 2,190ms \\
|
||||||
|
$|n| = 2048$ & 44ms & 68ms & 8,170ms & 8,421ms \\
|
||||||
|
$|n| = 4096$ & 225ms & 292ms & 41,500ms & 34,405ms \\
|
||||||
|
\bottomrule
|
||||||
|
\end{tabularx}
|
||||||
|
\end{table}
|
||||||
|
|
||||||
|
\begin{table}[htp]
|
||||||
|
\fontsize{10pt}{10pt}\selectfont
|
||||||
|
\caption{Byte size\parnote{1 UTF-16 character, as used by ECMAScript, is 2 or more bytes} of encoded proofs}
|
||||||
|
\begin{tabularx}{\textwidth}{c *4{>{\Centering}X}}
|
||||||
|
\toprule
|
||||||
|
\multirow{2}{*}{Modulus size} & \multicolumn{2}{c}{Proof-of-zero non-interactive} & \multicolumn{2}{c}{\hyperref[protocol1]{Protocol~\ref*{protocol1}} with $t = 24$} \tabularnewline \cmidrule(l){2-3}\cmidrule(l){4-5}
|
||||||
|
& JSON & with LZ-String & JSON & with LZ-String \\
|
||||||
|
\midrule
|
||||||
|
$|n| = 1024$ & 1,617B & 576B (35.62\%) & 338,902B & 95,738B (28.25\%) \\
|
||||||
|
$|n| = 2048$ & 3,153B & 1,050B (33.30\%) & 662,233B & 187,333B (28.29\%) \\
|
||||||
|
$|n| = 4096$ & 6,226B & 1,999B (32.11\%) & 1,315,027B & 368,646B (28.03\%) \\
|
||||||
|
\bottomrule
|
||||||
|
\end{tabularx}
|
||||||
|
\parnotes
|
||||||
|
\end{table}
|
||||||
|
|
||||||
\subsection{Quantum resistance}
|
\subsection{Quantum resistance}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user