code for proof system
This commit is contained in:
		| @@ -38,4 +38,18 @@ export function mod_inv(a, n) { | ||||
|     return t; | ||||
| } | ||||
|  | ||||
| export function gcd(a, b) { | ||||
|     // check a, b are correct types. | ||||
|     a *= 1n; | ||||
|     b *= 1n; | ||||
|     while (b !== 0n) { | ||||
|         let temp = b; | ||||
|         b = a % b; | ||||
|         a = temp; | ||||
|     } | ||||
|     return a; | ||||
| } | ||||
|  | ||||
| window.mod_exp = mod_exp; | ||||
| window.mod_inv = mod_inv; | ||||
| window.gcd = gcd; | ||||
|   | ||||
| @@ -17,10 +17,12 @@ class Cyphertext { | ||||
|         // Compute g^m r^n from crt | ||||
|         this.cyphertext = (gm * mod_exp(r, key.n, key.n ** 2n)) % key.n ** 2n; | ||||
|         this.r = r; | ||||
|         this.key = key; | ||||
|         this.pubKey = key; | ||||
|         this.plainText = plainText; | ||||
|  | ||||
|         this.readOnly = false; | ||||
|  | ||||
|         this.rp = null; | ||||
|     } | ||||
|  | ||||
|     update(c) { | ||||
| @@ -32,21 +34,92 @@ class Cyphertext { | ||||
|     toString() { | ||||
|         return "0x" + this.cyphertext.toString(16); | ||||
|     } | ||||
|  | ||||
|     prove() { | ||||
|         return new ProofSessionProver(this); | ||||
|     } | ||||
|  | ||||
|     asReadOnlyCyphertext() { | ||||
|         return new ReadOnlyCyphertext(this.pubKey, this.cyphertext); | ||||
|     } | ||||
| } | ||||
|  | ||||
| class ProofSessionProver { | ||||
|     constructor(cipherText) { | ||||
|         this.cipherText = cipherText; | ||||
|  | ||||
|         this.rp = random2048(); | ||||
|         while (this.rp >= this.cipherText.pubKey.n) { | ||||
|             this.rp = random2048(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     noise() { | ||||
|         return mod_exp(this.rp, this.cipherText.pubKey.n, this.cipherText.pubKey.n ** 2n); | ||||
|     } | ||||
|  | ||||
|     prove(challenge) { | ||||
|         return { | ||||
|             proof: | ||||
|                 ((this.rp % this.cipherText.pubKey.n) * | ||||
|                     mod_exp(this.cipherText.r, challenge, this.cipherText.pubKey.n)) % | ||||
|                 this.cipherText.pubKey.n, | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| window.Cyphertext = Cyphertext; | ||||
|  | ||||
| export class ReadOnlyCyphertext { | ||||
|     constructor(key, cyphertext) { | ||||
|         this.cyphertext = cyphertext; | ||||
|         this.key = key; | ||||
|         this.pubKey = key; | ||||
|  | ||||
|         this.readOnly = true; | ||||
|  | ||||
|         this.proofPromise = null; | ||||
|     } | ||||
|  | ||||
|     update(c) { | ||||
|         this.cyphertext *= c.cyphertext; | ||||
|     } | ||||
|  | ||||
|     async prove() { | ||||
|         // request a proof | ||||
|         let promise = new Promise((res) => (this.proofPromise = res)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| class ProofSessionVerifier { | ||||
|     constructor(cipherText, a) { | ||||
|         this.cipherText = cipherText; | ||||
|         this.challenge = random2048(); | ||||
|         this.a = a; | ||||
|     } | ||||
|  | ||||
|     verify(proof) { | ||||
|         // check coprimality | ||||
|         if (gcd(proof, this.cipherText.pubKey.n) !== 1n) return false; | ||||
|         if (gcd(this.cipherText.cyphertext, this.cipherText.pubKey.n) !== 1n) | ||||
|             return false; | ||||
|         if (gcd(this.a, this.cipherText.pubKey.n) !== 1n) return false; | ||||
|  | ||||
|         // check exp | ||||
|         return ( | ||||
|             mod_exp(proof, this.cipherText.pubKey.n, this.cipherText.pubKey.n ** 2n) === | ||||
|             (this.a * | ||||
|                 mod_exp( | ||||
|                     this.cipherText.cyphertext, | ||||
|                     this.challenge, | ||||
|                     this.cipherText.pubKey.n ** 2n | ||||
|                 )) % | ||||
|                 this.cipherText.pubKey.n ** 2n | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| window.ReadOnlyCyphertext = ReadOnlyCyphertext; | ||||
|  | ||||
| export class PaillierPubKey { | ||||
|     constructor(n) { | ||||
|         this.n = n; | ||||
|   | ||||
| @@ -146,10 +146,6 @@ document.addEventListener("ACT", async (ev) => { | ||||
|                     game.currentPlayer().endTurn(); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (game.allReinforcementsPlaced()) { | ||||
|                 game.incrementState(); | ||||
|             } | ||||
|         } else { | ||||
|             if (await game.currentPlayer().act(data)) { | ||||
|                 game.currentPlayer().endTurn(); | ||||
| @@ -161,6 +157,12 @@ document.addEventListener("ACT", async (ev) => { | ||||
|     } | ||||
| }); | ||||
|  | ||||
| document.addEventListener("endTurn", () => { | ||||
|     if (game.isPregame() && game.allReinforcementsPlaced()) { | ||||
|         game.incrementState(); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| document.addEventListener("gameStateUpdate", async () => { | ||||
|     if (game.isPregame()) { | ||||
|         let firstPlayerIndex = await random.get( | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| @@ -364,9 +364,9 @@ Then, a proof for the following homologous problem can be trivially constructed: | ||||
|  | ||||
| % Furthermore, the above protocol can be made non-interactive using the Fiat-Shamir heuristic \citep{fiatshamir}. (this contradicts the lit review) | ||||
|  | ||||
| \subsection{Recovering $r$ given $c$} | ||||
| \subsection{Implementation details} | ||||
|  | ||||
|  | ||||
| The proof requires that the prover can perform new calculations with $r$ given a cyphertext $c = g^mr^n \mod n^2$. For ease of programming,  | ||||
|  | ||||
| \subsection{Application to domain} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user