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 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} | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user