plaintext-proof.spec.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  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 PlaintextProofTestData = require('./data/plaintext-proof-data');
  11. var cryptoPolicy = require('scytl-cryptopolicy');
  12. var zkProof = require('../lib/index');
  13. var elGamal = require('scytl-elgamal');
  14. var messageDigest = require('scytl-messagedigest');
  15. var mathematical = require('scytl-mathematical');
  16. var secureRandom = require('scytl-securerandom');
  17. var codec = require('scytl-codec');
  18. describe('The zero-knowledge proof module should be able to ...', function() {
  19. var proofService_;
  20. var group_;
  21. var secret_;
  22. var ciphertext_;
  23. var anotherSecret_;
  24. var anotherCiphertext_;
  25. var publicKey_;
  26. var anotherPublicKey_;
  27. var plaintext_;
  28. var anotherPlaintext_;
  29. var data_;
  30. var otherData_;
  31. var proofHandler_;
  32. var proof_;
  33. var preComputation_;
  34. beforeAll(function() {
  35. proofService_ = zkProof.newService();
  36. var testData = new PlaintextProofTestData();
  37. var elGamalService = elGamal.newService();
  38. group_ = testData.getGroup();
  39. var encryptedElements = testData.getEncryptedElements();
  40. secret_ = encryptedElements.secret;
  41. ciphertext_ = elGamalService.newEncryptedElements(
  42. encryptedElements.gamma, encryptedElements.phis);
  43. var otherEncryptedElements = testData.getOtherEncryptedElements();
  44. anotherSecret_ = otherEncryptedElements.secret;
  45. anotherCiphertext_ = elGamalService.newEncryptedElements(
  46. otherEncryptedElements.gamma, otherEncryptedElements.phis);
  47. publicKey_ = testData.getPublicKey();
  48. anotherPublicKey_ = testData.getAnotherPublicKey();
  49. plaintext_ = testData.getPlaintext();
  50. anotherPlaintext_ = testData.getAnotherPlaintext();
  51. data_ = testData.getStringData();
  52. otherData_ = testData.getOtherStringData();
  53. proofHandler_ =
  54. proofService_.newPlaintextProofHandler(group_).init(publicKey_);
  55. proof_ = proofHandler_.generate(secret_, plaintext_, ciphertext_);
  56. preComputation_ = proofHandler_.preCompute();
  57. });
  58. beforeEach(function() {
  59. proofHandler_ =
  60. proofService_.newPlaintextProofHandler(group_).init(publicKey_);
  61. });
  62. describe('create a zero-knowledge proof service that should be able to ..', function() {
  63. describe('create a plaintext proof handler that should be able to', function() {
  64. it('generate and verify a plaintext proof', function() {
  65. var verified = proofHandler_.verify(proof_, plaintext_, ciphertext_);
  66. expect(verified).toBeTruthy();
  67. });
  68. it('generate and verify a plaintext proof, using a specified cryptographic policy',
  69. function() {
  70. var policy = cryptoPolicy.newInstance();
  71. policy.proofs.messageDigest.algorithm =
  72. cryptoPolicy.options.proofs.messageDigest.algorithm.SHA512_224;
  73. var proofService = zkProof.newService({policy: policy});
  74. var proofHandler =
  75. proofService.newPlaintextProofHandler(group_).init(publicKey_);
  76. proof_ = proofHandler.generate(secret_, plaintext_, ciphertext_);
  77. var verified = proofHandler.verify(proof_, plaintext_, ciphertext_);
  78. expect(verified).toBeTruthy();
  79. });
  80. it('generate and verify a plaintext proof, using a specified message digest service',
  81. function() {
  82. var policy = cryptoPolicy.newInstance();
  83. policy.proofs.messageDigest.algorithm =
  84. cryptoPolicy.options.proofs.messageDigest.algorithm.SHA512_224;
  85. var messageDigestService =
  86. messageDigest.newService({policy: policy});
  87. var proofService =
  88. zkProof.newService({messageDigestService: messageDigestService});
  89. var proofHandler =
  90. proofService.newPlaintextProofHandler(group_).init(publicKey_);
  91. proof_ = proofHandler.generate(secret_, plaintext_, ciphertext_);
  92. var verified = proofHandler.verify(proof_, plaintext_, ciphertext_);
  93. expect(verified).toBeTruthy();
  94. });
  95. it('generate and verify a plaintext proof, using a specified secure random service object',
  96. function() {
  97. var proofService = zkProof.newService(
  98. {secureRandomService: secureRandom.newService()});
  99. var proofHandler =
  100. proofService.newPlaintextProofHandler(group_).init(publicKey_);
  101. proof_ = proofHandler.generate(secret_, plaintext_, ciphertext_);
  102. var verified = proofHandler.verify(proof_, plaintext_, ciphertext_);
  103. expect(verified).toBeTruthy();
  104. });
  105. it('generate and verify a plaintext proof, using a specified mathematical service object',
  106. function() {
  107. var proofService = zkProof.newService(
  108. {mathematicalService: mathematical.newService()});
  109. var proofHandler =
  110. proofService.newPlaintextProofHandler(group_).init(publicKey_);
  111. proof_ = proofHandler.generate(secret_, plaintext_, ciphertext_);
  112. var verified = proofHandler.verify(proof_, plaintext_, ciphertext_);
  113. expect(verified).toBeTruthy();
  114. });
  115. it('generate and verify a plaintext proof, using provided auxiliary data',
  116. function() {
  117. // Data as string.
  118. var proof = proofHandler_.generate(
  119. secret_, plaintext_, ciphertext_, {data: data_});
  120. var verified = proofHandler_.verify(
  121. proof, plaintext_, ciphertext_, {data: data_});
  122. expect(verified).toBeTruthy();
  123. // Data as bytes.
  124. proof = proofHandler_.generate(
  125. secret_, plaintext_, ciphertext_,
  126. {data: codec.utf8Encode(data_)});
  127. verified = proofHandler_.verify(
  128. proof, plaintext_, ciphertext_, {data: codec.utf8Encode(data_)});
  129. expect(verified).toBeTruthy();
  130. });
  131. it('generate and verify a plaintext proof, using a pre-computation',
  132. function() {
  133. var proof = proofHandler_.generate(
  134. secret_, plaintext_, ciphertext_,
  135. {preComputation: preComputation_});
  136. var verified = proofHandler_.verify(proof, plaintext_, ciphertext_);
  137. expect(verified).toBeTruthy();
  138. });
  139. it('generate and verify a plaintext proof, using empty string auxiliary data',
  140. function() {
  141. var proof = proofHandler_.generate(
  142. secret_, plaintext_, ciphertext_, {data: ''});
  143. var verified =
  144. proofHandler_.verify(proof, plaintext_, ciphertext_, {data: ''});
  145. expect(verified).toBeTruthy();
  146. });
  147. it('pre-compute, generate and verify a plaintext proof, using method chaining',
  148. function() {
  149. var preComputation = proofService_.newPlaintextProofHandler(group_)
  150. .init(publicKey_)
  151. .preCompute();
  152. var proof = proofService_.newPlaintextProofHandler(group_)
  153. .init(publicKey_)
  154. .generate(
  155. secret_, plaintext_, ciphertext_,
  156. {data: data_, preComputation: preComputation});
  157. var verified =
  158. proofService_.newPlaintextProofHandler(group_)
  159. .init(publicKey_)
  160. .verify(proof, plaintext_, ciphertext_, {data: data_});
  161. expect(verified).toBeTruthy();
  162. });
  163. it('create a new plaintext ZeroKnowledgeProof object', function() {
  164. var hash = proof_.hash;
  165. var values = proof_.values;
  166. var proof = proofService_.newProof(hash, values);
  167. var verified = proofHandler_.verify(proof, plaintext_, ciphertext_);
  168. expect(verified).toBeTruthy();
  169. });
  170. it('create a new plaintext ZeroKnowledgeProofPreComputation object',
  171. function() {
  172. var exponents = preComputation_.exponents;
  173. var phiOutputs = preComputation_.phiOutputs;
  174. var preComputation =
  175. proofService_.newPreComputation(exponents, phiOutputs);
  176. var proof = proofHandler_.generate(
  177. secret_, plaintext_, ciphertext_,
  178. {preComputation: preComputation});
  179. var verified = proofHandler_.verify(proof, plaintext_, ciphertext_);
  180. expect(verified).toBeTruthy();
  181. });
  182. it('serialize and deserialize a plaintext proof', function() {
  183. var proofJson = proof_.toJson();
  184. var proof = proofService_.newProof(proofJson);
  185. var verified = proofHandler_.verify(proof, plaintext_, ciphertext_);
  186. expect(verified).toBeTruthy();
  187. });
  188. it('serialize and deserialize a plaintext proof pre-computation',
  189. function() {
  190. var preComputationJson = preComputation_.toJson();
  191. var preComputation =
  192. proofService_.newPreComputation(preComputationJson);
  193. var proof = proofHandler_.generate(
  194. secret_, plaintext_, ciphertext_,
  195. {preComputation: preComputation});
  196. var verified = proofHandler_.verify(proof, plaintext_, ciphertext_);
  197. expect(verified).toBeTruthy();
  198. });
  199. it('fail to verify a plaintext proof that was generated with a secret not used to generate the ciphertext',
  200. function() {
  201. var proof =
  202. proofHandler_.generate(anotherSecret_, plaintext_, ciphertext_);
  203. var verified = proofHandler_.verify(proof, plaintext_, ciphertext_);
  204. expect(verified).toBeFalsy();
  205. });
  206. it('fail to verify a plaintext proof that was generated with a publicKey not used to generate the ciphertext',
  207. function() {
  208. proofHandler_.init(anotherPublicKey_);
  209. var proof = proofHandler_.generate(secret_, plaintext_, ciphertext_);
  210. var verified = proofHandler_.verify(proof, plaintext_, ciphertext_);
  211. expect(verified).toBeFalsy();
  212. });
  213. it('fail to verify a plaintext proof that was generated with a plaintext not used to generate the ciphertext',
  214. function() {
  215. var proof =
  216. proofHandler_.generate(secret_, anotherPlaintext_, ciphertext_);
  217. var verified =
  218. proofHandler_.verify(proof, anotherPlaintext_, ciphertext_);
  219. expect(verified).toBeFalsy();
  220. });
  221. it('fail to verify a plaintext proof that was generated with a ciphertext not generated with the public key',
  222. function() {
  223. var proof =
  224. proofHandler_.generate(secret_, plaintext_, anotherCiphertext_);
  225. var verified =
  226. proofHandler_.verify(proof, plaintext_, anotherCiphertext_);
  227. expect(verified).toBeFalsy();
  228. });
  229. it('fail to verify a plaintext proof when using a public key not used to generate the proof',
  230. function() {
  231. var verified = proofHandler_.init(anotherPublicKey_)
  232. .verify(proof_, plaintext_, ciphertext_);
  233. expect(verified).toBeFalsy();
  234. });
  235. it('fail to verify a plaintext proof when using a plaintext not used to generate the proof',
  236. function() {
  237. var verified =
  238. proofHandler_.verify(proof_, anotherPlaintext_, ciphertext_);
  239. expect(verified).toBeFalsy();
  240. });
  241. it('fail to verify a plaintext proof when using a ciphertext not used to generate the proof',
  242. function() {
  243. var verified =
  244. proofHandler_.verify(proof_, plaintext_, anotherCiphertext_);
  245. expect(verified).toBeFalsy();
  246. });
  247. it('fail to verify a plaintext proof when using auxiliary data not used to generate the proof',
  248. function() {
  249. var proof = proofHandler_.generate(
  250. secret_, plaintext_, ciphertext_, {data: data_});
  251. var verified = proofHandler_.verify(
  252. proof, plaintext_, ciphertext_, {data: otherData_});
  253. expect(verified).toBeFalsy();
  254. });
  255. it('throw an error when generating a proof before the handler has been initialized with a pubilc key',
  256. function() {
  257. var proofHandler = proofService_.newPlaintextProofHandler(group_);
  258. expect(function() {
  259. proofHandler.generate(secret_, plaintext_, ciphertext_);
  260. }).toThrow();
  261. });
  262. it('throw an error when pre-computing a proof before the handler has been initialized with a pubilc key',
  263. function() {
  264. var proofHandler = proofService_.newPlaintextProofHandler(group_);
  265. expect(function() {
  266. proofHandler.preCompute();
  267. }).toThrow();
  268. });
  269. it('throw an error when verifying a proof before the handler has been initialized with a pubilc key',
  270. function() {
  271. var proofHandler = proofService_.newPlaintextProofHandler(group_);
  272. expect(function() {
  273. proofHandler.verify(proof_, plaintext_, ciphertext_);
  274. }).toThrow();
  275. });
  276. });
  277. });
  278. });