readme, benchmarks, fix verification
This commit is contained in:
		
							
								
								
									
										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 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 { | ||||
|     constructor(key, plainText, r, set) { | ||||
|         if (set !== undefined) { | ||||
| @@ -93,28 +112,12 @@ class Ciphertext { | ||||
|         } | ||||
|  | ||||
|         let a = mod_exp(rp, this.pubKey.n, this.pubKey.n2); | ||||
|         let hasher = new jsSHA("SHAKE256", "HEX"); | ||||
|  | ||||
|         let plainText = this.plainText.toString(16); | ||||
|         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 })); | ||||
|         let challenge = RSTransform(this.pubKey.g, a, this.plainText); | ||||
|  | ||||
|         return { | ||||
|             plainText: "0x" + this.plainText.toString(16), | ||||
|             a: "0x" + a.toString(16), | ||||
|             challenge: "0x" + challenge.toString(16), | ||||
|             proof: | ||||
|                 "0x" + | ||||
|                 ( | ||||
| @@ -195,11 +198,17 @@ export class ReadOnlyCiphertext { | ||||
|     } | ||||
|  | ||||
|     verifyNI(statement) { | ||||
|         let challenge = RSTransform( | ||||
|             this.pubKey.g, | ||||
|             BigInt(statement.a), | ||||
|             BigInt(statement.plainText) | ||||
|         ); | ||||
|  | ||||
|         let verifier = new ValueProofSessionVerifier( | ||||
|             this, | ||||
|             BigInt(statement.plainText), | ||||
|             BigInt(statement.a), | ||||
|             BigInt(statement.challenge) | ||||
|             challenge | ||||
|         ); | ||||
|  | ||||
|         if (verifier.verify(BigInt(statement.proof))) { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import { mod_exp } from "./math.js"; | ||||
|  | ||||
| export const KEY_SIZE = 512; | ||||
| export const KEY_SIZE = 2048; | ||||
|  | ||||
| export function cryptoRandom(bits) { | ||||
|     if (bits === undefined) { | ||||
|   | ||||
| @@ -135,7 +135,6 @@ export function verifyRegions(obj, key) { | ||||
|                 let plaintext = c.verifyNI(verification.zeroProofs[regionName]); | ||||
|  | ||||
|                 if (plaintext !== 0n) { | ||||
|                     console.log(plaintext); | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|   | ||||
| @@ -7,7 +7,8 @@ | ||||
|  | ||||
|     <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="{{ 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/crypto/main.js') }}" type="module"></script> | ||||
| </head> | ||||
| @@ -188,6 +189,8 @@ | ||||
|         function RSABench() { | ||||
|             console.log("Warming up") | ||||
|  | ||||
|             const ROUNDS = 250; | ||||
|  | ||||
|             for (let i = 0n; i < 100n; i++) { | ||||
|                 window.rsa.pubKey.encrypt(i); | ||||
|             } | ||||
| @@ -195,17 +198,19 @@ | ||||
|             console.log("Benching") | ||||
|  | ||||
|             performance.mark("rsa-start") | ||||
|             for (let i = 0n; i < 250n; i++) { | ||||
|             for (let i = 0n; i < BigInt(ROUNDS); i++) { | ||||
|                 window.rsa.pubKey.encrypt(i); | ||||
|             } | ||||
|             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() { | ||||
|             console.log("Warming up") | ||||
|  | ||||
|             const ROUNDS = 250 | ||||
|  | ||||
|             for (let i = 0n; i < 100n; i++) { | ||||
|                 window.paillier.pubKey.encrypt(i); | ||||
|             } | ||||
| @@ -213,12 +218,162 @@ | ||||
|             console.log("Benching") | ||||
|  | ||||
|             performance.mark("paillier-start") | ||||
|             for (let i = 0n; i < 250n; i++) { | ||||
|             for (let i = 0n; i < BigInt(ROUNDS); i++) { | ||||
|                 window.paillier.pubKey.encrypt(i); | ||||
|             } | ||||
|             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> | ||||
| </body> | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| @@ -8,6 +8,11 @@ | ||||
| \usepackage{amsthm} | ||||
| \usepackage{tikz} | ||||
| \usepackage{minted} | ||||
| \usepackage{multirow} | ||||
| \usepackage{tabularx} | ||||
| \usepackage{booktabs} | ||||
| \usepackage{ragged2e} | ||||
| \usepackage[alph]{parnotes} | ||||
|  | ||||
| \DeclareMathOperator{\lcm}{lcm} | ||||
| \DeclareMathOperator{\id}{id} | ||||
| @@ -598,18 +603,52 @@ The other proofs do not translate so trivially to this structure however. In fac | ||||
|  | ||||
| \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{tabular}{|c|c|c|c|} | ||||
| 		\hline | ||||
| 		Modulus size & Na\"ive encrypt & Jacobi encrypt & RSA encrypt \\\hline | ||||
| \begin{table}[htp] | ||||
| 	\fontsize{10pt}{10pt}\selectfont | ||||
| 	\caption{Time to encrypt} | ||||
| 	\begin{tabularx}{\textwidth}{c *3{>{\Centering}X}} | ||||
| 		\toprule | ||||
| 		Modulus size & Na\"ive encrypt & Jacobi encrypt & RSA encrypt \\ | ||||
| 		\midrule | ||||
| 		$|n| = 1024$   & 6ms & 4ms & <1ms \\   | ||||
| 		$|n| = 2048$   & 34ms & 22ms & <1ms \\ | ||||
| 		$|n| = 4096$   & 189ms & 128ms & <1ms \\ | ||||
| 		\hline | ||||
| 	\end{tabular} | ||||
| \end{center} | ||||
| 		\bottomrule | ||||
| 	\end{tabularx} | ||||
| \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} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user