simple-plaintext-equality-proof.spec.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. /*
  2. * Copyright 2018 Scytl Secure Electronic Voting SA
  3. *
  4. * All rights reserved
  5. *
  6. * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
  7. */
  8. /* jshint node:true */
  9. 'use strict';
  10. var SimplePlaintextEqualityProofTestData =
  11. require('./data/simple-plaintext-equality-proof-data');
  12. var cryptoPolicy = require('scytl-cryptopolicy');
  13. var zkProof = require('../lib/index');
  14. var elGamal = require('scytl-elgamal');
  15. var messageDigest = require('scytl-messagedigest');
  16. var mathematical = require('scytl-mathematical');
  17. var secureRandom = require('scytl-securerandom');
  18. var codec = require('scytl-codec');
  19. describe('The zero-knowledge proof module should be able to ...', function() {
  20. var proofService_;
  21. var group_;
  22. var secret_;
  23. var anotherSecret_;
  24. var primaryPublicKey_;
  25. var secondaryPublicKey_;
  26. var anotherPrimaryPublicKey_;
  27. var anotherSecondaryPublicKey_;
  28. var primaryCiphertext_;
  29. var secondaryCiphertext_;
  30. var anotherPrimaryCiphertext_;
  31. var anotherSecondaryCiphertext_;
  32. var data_;
  33. var otherData_;
  34. var secretForNonSimplePlaintext_;
  35. var primaryCiphertextForNonSimplePlaintext_;
  36. var secondaryCiphertextForNonSimplePlaintext_;
  37. var proofHandler_;
  38. var proof_;
  39. var preComputation_;
  40. beforeAll(function() {
  41. proofService_ = zkProof.newService();
  42. var testData = new SimplePlaintextEqualityProofTestData();
  43. var elGamalService = elGamal.newService();
  44. group_ = testData.getGroup();
  45. var primaryEncryptedElements = testData.getPrimaryEncryptedElements();
  46. secret_ = primaryEncryptedElements.secret;
  47. var otherPrimaryEncryptedElements =
  48. testData.getOtherPrimaryEncryptedElements();
  49. anotherSecret_ = otherPrimaryEncryptedElements.secret;
  50. primaryPublicKey_ = testData.getPrimaryPublicKey();
  51. secondaryPublicKey_ = testData.getSecondaryPublicKey();
  52. anotherPrimaryPublicKey_ = testData.getAnotherPrimaryPublicKey();
  53. anotherSecondaryPublicKey_ = testData.getAnotherSecondaryPublicKey();
  54. primaryCiphertext_ = elGamalService.newEncryptedElements(
  55. primaryEncryptedElements.gamma, primaryEncryptedElements.phis);
  56. var secondaryEncryptedElements = testData.getSecondaryEncryptedElements();
  57. secondaryCiphertext_ = elGamalService.newEncryptedElements(
  58. secondaryEncryptedElements.gamma, secondaryEncryptedElements.phis);
  59. anotherPrimaryCiphertext_ = testData.getOtherPrimaryEncryptedElements();
  60. anotherSecondaryCiphertext_ = testData.getOtherSecondaryEncryptedElements();
  61. data_ = testData.getStringData();
  62. otherData_ = testData.getOtherStringData();
  63. var primaryEncryptedElementsForNonSimplePlaintext =
  64. testData.getPrimaryEncryptedElementsForNonSimplePlaintext();
  65. secretForNonSimplePlaintext_ =
  66. primaryEncryptedElementsForNonSimplePlaintext.secret;
  67. primaryCiphertextForNonSimplePlaintext_ =
  68. elGamalService.newEncryptedElements(
  69. primaryEncryptedElementsForNonSimplePlaintext.gamma,
  70. primaryEncryptedElementsForNonSimplePlaintext.phis);
  71. var secondaryEncryptedElementsForNonSimplePlaintext =
  72. testData.getSecondaryEncryptedElementsForNonSimplePlaintext();
  73. secondaryCiphertextForNonSimplePlaintext_ =
  74. elGamalService.newEncryptedElements(
  75. secondaryEncryptedElementsForNonSimplePlaintext.gamma,
  76. secondaryEncryptedElementsForNonSimplePlaintext.phis);
  77. proofHandler_ =
  78. proofService_.newSimplePlaintextEqualityProofHandler(group_).init(
  79. primaryPublicKey_, secondaryPublicKey_);
  80. proof_ = proofHandler_.generate(
  81. secret_, primaryCiphertext_, secondaryCiphertext_);
  82. preComputation_ = proofHandler_.preCompute();
  83. });
  84. beforeEach(function() {
  85. proofHandler_ =
  86. proofService_.newSimplePlaintextEqualityProofHandler(group_).init(
  87. primaryPublicKey_, secondaryPublicKey_);
  88. });
  89. describe('create a zero-knowledge proof service that should be able to ..', function() {
  90. describe('create a simple plaintext equality proof handler that should be able to', function() {
  91. it('generate and verify a simple plaintext equality proof', function() {
  92. var verified = proofHandler_.verify(
  93. proof_, primaryCiphertext_, secondaryCiphertext_);
  94. expect(verified).toBeTruthy();
  95. });
  96. it('generate and verify a simple plaintext equality proof, using a specified cryptographic policy',
  97. function() {
  98. var policy = cryptoPolicy.newInstance();
  99. policy.proofs.messageDigest.algorithm =
  100. cryptoPolicy.options.proofs.messageDigest.algorithm.SHA512_224;
  101. var proofService = zkProof.newService({policy: policy});
  102. var proofHandler =
  103. proofService.newSimplePlaintextEqualityProofHandler(group_).init(
  104. primaryPublicKey_, secondaryPublicKey_);
  105. proof_ = proofHandler.generate(
  106. secret_, primaryCiphertext_, secondaryCiphertext_);
  107. var verified = proofHandler.verify(
  108. proof_, primaryCiphertext_, secondaryCiphertext_);
  109. expect(verified).toBeTruthy();
  110. });
  111. it('generate and verify a simple plaintext equality proof, using a specified message digest service',
  112. function() {
  113. var policy = cryptoPolicy.newInstance();
  114. policy.proofs.messageDigest.algorithm =
  115. cryptoPolicy.options.proofs.messageDigest.algorithm.SHA512_224;
  116. var messageDigestService =
  117. messageDigest.newService({policy: policy});
  118. var proofService =
  119. zkProof.newService({messageDigestService: messageDigestService});
  120. var proofHandler =
  121. proofService.newSimplePlaintextEqualityProofHandler(group_).init(
  122. primaryPublicKey_, secondaryPublicKey_);
  123. proof_ = proofHandler.generate(
  124. secret_, primaryCiphertext_, secondaryCiphertext_);
  125. var verified = proofHandler.verify(
  126. proof_, primaryCiphertext_, secondaryCiphertext_);
  127. expect(verified).toBeTruthy();
  128. });
  129. it('generate and verify a simple plaintext equality proof, using a specified secure random service object',
  130. function() {
  131. var proofService = zkProof.newService(
  132. {secureRandomService: secureRandom.newService()});
  133. var proofHandler =
  134. proofService.newSimplePlaintextEqualityProofHandler(group_).init(
  135. primaryPublicKey_, secondaryPublicKey_);
  136. proof_ = proofHandler.generate(
  137. secret_, primaryCiphertext_, secondaryCiphertext_);
  138. var verified = proofHandler.verify(
  139. proof_, primaryCiphertext_, secondaryCiphertext_);
  140. expect(verified).toBeTruthy();
  141. });
  142. it('generate and verify a simple plaintext equality proof, using a specified mathematical service object',
  143. function() {
  144. var proofService = zkProof.newService(
  145. {mathematicalService: mathematical.newService()});
  146. var proofHandler =
  147. proofService.newSimplePlaintextEqualityProofHandler(group_).init(
  148. primaryPublicKey_, secondaryPublicKey_);
  149. proof_ = proofHandler.generate(
  150. secret_, primaryCiphertext_, secondaryCiphertext_);
  151. var verified = proofHandler.verify(
  152. proof_, primaryCiphertext_, secondaryCiphertext_);
  153. expect(verified).toBeTruthy();
  154. });
  155. it('generate and verify a plaintext proof, using provided auxiliary data',
  156. function() {
  157. // Data as string.
  158. var proof = proofHandler_.generate(
  159. secret_, primaryCiphertext_, secondaryCiphertext_,
  160. {data: data_});
  161. var verified = proofHandler_.verify(
  162. proof, primaryCiphertext_, secondaryCiphertext_, {data: data_});
  163. expect(verified).toBeTruthy();
  164. // Data as bytes.
  165. proof = proofHandler_.generate(
  166. secret_, primaryCiphertext_, secondaryCiphertext_,
  167. {data: codec.utf8Encode(data_)});
  168. verified = proofHandler_.verify(
  169. proof, primaryCiphertext_, secondaryCiphertext_,
  170. {data: codec.utf8Encode(data_)});
  171. expect(verified).toBeTruthy();
  172. });
  173. it('generate and verify a simple plaintext equality proof, using a pre-computation',
  174. function() {
  175. var proof = proofHandler_.generate(
  176. secret_, primaryCiphertext_, secondaryCiphertext_,
  177. {preComputation: preComputation_});
  178. var verified = proofHandler_.verify(
  179. proof, primaryCiphertext_, secondaryCiphertext_);
  180. expect(verified).toBeTruthy();
  181. });
  182. it('generate and verify a simple plaintext equality proof, using empty auxiliary data',
  183. function() {
  184. var proof = proofHandler_.generate(
  185. secret_, primaryCiphertext_, secondaryCiphertext_, {data: ''});
  186. var verified = proofHandler_.verify(
  187. proof, primaryCiphertext_, secondaryCiphertext_, {data: ''});
  188. expect(verified).toBeTruthy();
  189. });
  190. it('pre-compute, generate and verify a simple plaintext proof, using method chaining',
  191. function() {
  192. var preComputation =
  193. proofService_.newSimplePlaintextEqualityProofHandler(group_)
  194. .init(primaryPublicKey_, secondaryPublicKey_)
  195. .preCompute();
  196. var proof =
  197. proofService_.newSimplePlaintextEqualityProofHandler(group_)
  198. .init(primaryPublicKey_, secondaryPublicKey_)
  199. .generate(
  200. secret_, primaryCiphertext_, secondaryCiphertext_,
  201. {data: data_, preComputation: preComputation});
  202. var verified =
  203. proofService_.newSimplePlaintextEqualityProofHandler(group_)
  204. .init(primaryPublicKey_, secondaryPublicKey_)
  205. .verify(
  206. proof, primaryCiphertext_, secondaryCiphertext_,
  207. {data: data_});
  208. expect(verified).toBeTruthy();
  209. });
  210. it('create a new simple plaintext equality ZeroKnowledgeProof object',
  211. function() {
  212. var hash = proof_.hash;
  213. var values = proof_.values;
  214. var proof = proofService_.newProof(hash, values);
  215. var verified = proofHandler_.verify(
  216. proof, primaryCiphertext_, secondaryCiphertext_);
  217. expect(verified).toBeTruthy();
  218. });
  219. it('create a new simple plaintext equality ZeroKnowledgeProofPreComputation object',
  220. function() {
  221. var exponents = preComputation_.exponents;
  222. var phiOutputs = preComputation_.phiOutputs;
  223. var preComputation =
  224. proofService_.newPreComputation(exponents, phiOutputs);
  225. var proof = proofHandler_.generate(
  226. secret_, primaryCiphertext_, secondaryCiphertext_,
  227. {preComputation: preComputation});
  228. var verified = proofHandler_.verify(
  229. proof, primaryCiphertext_, secondaryCiphertext_);
  230. expect(verified).toBeTruthy();
  231. });
  232. it('serialize and deserialize a simple plaintext equality', function() {
  233. var proofJson = proof_.toJson();
  234. var proof = proofService_.newProof(proofJson);
  235. var verified = proofHandler_.verify(
  236. proof, primaryCiphertext_, secondaryCiphertext_);
  237. expect(verified).toBeTruthy();
  238. });
  239. it('serialize and deserialize a simple plaintext equality pre-computation',
  240. function() {
  241. var preComputationJson = preComputation_.toJson();
  242. var preComputation =
  243. proofService_.newPreComputation(preComputationJson);
  244. var proof = proofHandler_.generate(
  245. secret_, primaryCiphertext_, secondaryCiphertext_,
  246. {preComputation: preComputation});
  247. var verified = proofHandler_.verify(
  248. proof, primaryCiphertext_, secondaryCiphertext_);
  249. expect(verified).toBeTruthy();
  250. });
  251. it('fail to verify a simple plaintext equality proof that was generated with a secret not used to generate the ciphertexts',
  252. function() {
  253. var proof = proofHandler_.generate(
  254. anotherSecret_, primaryCiphertext_, secondaryCiphertext_);
  255. var verified = proofHandler_.verify(
  256. proof, primaryCiphertext_, secondaryCiphertext_);
  257. expect(verified).toBeFalsy();
  258. });
  259. it('fail to verify a simple plaintext equality proof that was generated with a primary publicKey not used to generate the primary ciphertext',
  260. function() {
  261. proofHandler_.init(anotherPrimaryPublicKey_, secondaryPublicKey_);
  262. var proof = proofHandler_.generate(
  263. secret_, primaryCiphertext_, secondaryCiphertext_);
  264. var verified = proofHandler_.verify(
  265. proof, primaryCiphertext_, secondaryCiphertext_);
  266. expect(verified).toBeFalsy();
  267. });
  268. it('fail to verify a simple plaintext equality proof that was generated with a secondary publicKey not used to generate the secondary ciphertext',
  269. function() {
  270. proofHandler_.init(primaryPublicKey_, anotherSecondaryPublicKey_);
  271. var proof = proofHandler_.generate(
  272. secret_, primaryCiphertext_, secondaryCiphertext_);
  273. var verified = proofHandler_.verify(
  274. proof, primaryCiphertext_, secondaryCiphertext_);
  275. expect(verified).toBeFalsy();
  276. });
  277. it('fail to verify a simple plaintext equality proof that was generated with a primary ciphertext not generated from the simple plaintext',
  278. function() {
  279. var proof = proofHandler_.generate(
  280. secret_, anotherPrimaryCiphertext_, secondaryCiphertext_);
  281. var verified = proofHandler_.verify(
  282. proof, anotherPrimaryCiphertext_, secondaryCiphertext_);
  283. expect(verified).toBeFalsy();
  284. });
  285. it('fail to verify a simple plaintext equality proof that was generated with a secondary ciphertext not generated from the simple plaintext',
  286. function() {
  287. var proof = proofHandler_.generate(
  288. secret_, primaryCiphertext_, anotherSecondaryCiphertext_);
  289. var verified = proofHandler_.verify(
  290. proof, primaryCiphertext_, anotherSecondaryCiphertext_);
  291. expect(verified).toBeFalsy();
  292. });
  293. it('fail to verify a simple plaintext equality proof that was generated with plaintext that is not simple',
  294. function() {
  295. var proof = proofHandler_.generate(
  296. secretForNonSimplePlaintext_,
  297. primaryCiphertextForNonSimplePlaintext_,
  298. secondaryCiphertextForNonSimplePlaintext_);
  299. var verified = proofHandler_.verify(
  300. proof, primaryCiphertextForNonSimplePlaintext_,
  301. secondaryCiphertextForNonSimplePlaintext_);
  302. expect(verified).toBeFalsy();
  303. });
  304. it('fail to verify a simple plaintext equality proof when using a primary public key not used to generate the proof',
  305. function() {
  306. var verified =
  307. proofHandler_.init(anotherPrimaryPublicKey_, secondaryPublicKey_)
  308. .verify(proof_, primaryCiphertext_, secondaryCiphertext_);
  309. expect(verified).toBeFalsy();
  310. });
  311. it('fail to verify a simple plaintext equality proof when using a secondary public key not used to generate the proof',
  312. function() {
  313. var verified =
  314. proofHandler_.init(primaryPublicKey_, anotherSecondaryPublicKey_)
  315. .verify(proof_, primaryCiphertext_, secondaryCiphertext_);
  316. expect(verified).toBeFalsy();
  317. });
  318. it('fail to verify a simple plaintext equality proof when using a primary ciphertext not used to generate the proof',
  319. function() {
  320. var verified = proofHandler_.verify(
  321. proof_, anotherPrimaryCiphertext_, secondaryCiphertext_);
  322. expect(verified).toBeFalsy();
  323. });
  324. it('fail to verify a simple plaintext equality proof when using a secondary ciphertext not used to generate the proof',
  325. function() {
  326. var verified = proofHandler_.verify(
  327. proof_, primaryCiphertext_, anotherSecondaryCiphertext_);
  328. expect(verified).toBeFalsy();
  329. });
  330. it('fail to verify a simple plaintext equality proof when using auxiliary data not used to generate the proof',
  331. function() {
  332. var proof = proofHandler_.generate(
  333. secret_, primaryCiphertext_, secondaryCiphertext_,
  334. {data: data_});
  335. var verified = proofHandler_.verify(
  336. proof, primaryCiphertext_, secondaryCiphertext_,
  337. {data: otherData_});
  338. expect(verified).toBeFalsy();
  339. });
  340. it('throw an error when generating a proof before the handler has been initialized with any pubilc key',
  341. function() {
  342. var proofHandler =
  343. proofService_.newSimplePlaintextEqualityProofHandler(group_);
  344. expect(function() {
  345. proofHandler.generate(
  346. secret_, primaryCiphertext_, secondaryCiphertext_);
  347. }).toThrow();
  348. });
  349. it('throw an error when pre-computing a proof before the handler has been initialized with any pubilc key',
  350. function() {
  351. var proofHandler =
  352. proofService_.newSimplePlaintextEqualityProofHandler(group_);
  353. expect(function() {
  354. proofHandler.preCompute();
  355. }).toThrow();
  356. });
  357. it('throw an error when verifying a proof before the handler has been initialized with any pubilc key',
  358. function() {
  359. var proofHandler =
  360. proofService_.newSimplePlaintextEqualityProofHandler(group_);
  361. expect(function() {
  362. proofHandler.verify(
  363. proof_, primaryCiphertext_, secondaryCiphertext_);
  364. }).toThrow();
  365. });
  366. });
  367. });
  368. });