or-proof.spec.js 13 KB

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