proofs.spec.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. /* global forge */
  9. /* global CL */
  10. /* global OV */
  11. /* global TD */
  12. describe('Proofs api', function() {
  13. 'use strict';
  14. var TD = require('./mocks/testdata.json');
  15. it('should generate schnorr proof', function() {
  16. var encParms = OV.parseEncryptionParams(TD.authResponse);
  17. // encrypt vote
  18. var serializedEncrypterValues = OV.precomputeEncrypterValues(encParms);
  19. var encrypterValues = OV.deserializeEncrypterValues(serializedEncrypterValues);
  20. var keyValue = forge.jsbn.BigInteger.ONE;
  21. var element = new CL.commons.mathematical.ZpGroupElement(keyValue, encParms.p, encParms.q);
  22. var messages = [element];
  23. var encryptedOptions = OV.encryptOptions(messages, encParms, encrypterValues);
  24. // generate the proof
  25. var schnorr = OV.generateSchnorrProof('votingCardId', 'electionId', encParms, encryptedOptions);
  26. // prove it
  27. var verifies = (new CL.proofs.ProofsFactory()).createSchnorrProofVerifier(
  28. encryptedOptions.getElGamalComputationValues().getGamma(),
  29. 'votingCardId',
  30. 'electionId',
  31. schnorr,
  32. encParms.group).verify();
  33. expect(verifies).toBe(true);
  34. });
  35. // --------------------------------------------------------------
  36. it('should generate exponentiation proof', function() {
  37. var startVotingKey = TD.startVotingKey;
  38. var eventId = TD.eventId;
  39. var encParms = OV.parseEncryptionParams(TD.authResponse);
  40. var verificationCard = TD.authResponse.verificationCard;
  41. var startVotingKeyUnpacked = OV.parseStartVotingKey(startVotingKey, eventId);
  42. // encrypt vote
  43. var serializedEncrypterValues = OV.precomputeEncrypterValues(encParms);
  44. var encrypterValues = OV.deserializeEncrypterValues(serializedEncrypterValues);
  45. var keyValue = forge.jsbn.BigInteger.ONE;
  46. var element = new CL.commons.mathematical.ZpGroupElement(keyValue, encParms.p, encParms.q);
  47. var messages = [element];
  48. var encryptedOptions = OV.encryptOptions(messages, encParms, encrypterValues);
  49. var verificationCardPublicKey = JSON.parse(
  50. forge.util.decode64(verificationCard.signedVerificationPublicKey));
  51. var verificationCardSecret = OV.parseVerificationCard(
  52. verificationCard.verificationCardKeystore, startVotingKeyUnpacked.pin);
  53. // generate the proof
  54. var cipherTextExponentiations = OV.generateCipherTextExponentiations(
  55. encParms, encryptedOptions, verificationCardSecret);
  56. var exponentiationProof = OV.generateExponentiationProof(
  57. encParms, cipherTextExponentiations, verificationCardPublicKey.publicKey);
  58. // prove it
  59. var keyfactory = new CL.homomorphic.keypair.factory.KeyFactory();
  60. var generator = new CL.commons.mathematical.ZpGroupElement(encParms.g, encParms.p, encParms.q);
  61. var publicKey = keyfactory.createPublicKey(verificationCardPublicKey.publicKey).getGroupElementsArray()[0];
  62. var verifies = (new CL.proofs.ProofsFactory()).createExponentiationProofVerifier(
  63. [publicKey].concat(cipherTextExponentiations.cipherTextExponentiation), //
  64. [generator].concat(cipherTextExponentiations.cipherTextBases),
  65. exponentiationProof,
  66. encParms.group).verify();
  67. expect(verifies).toBe(true);
  68. });
  69. // --------------------------------------------------------------
  70. it('should generate plaintext equality proof', function() {
  71. var startVotingKey = TD.startVotingKey;
  72. var eventId = TD.eventId;
  73. var encParms = OV.parseEncryptionParams(TD.authResponse);
  74. var verificationCard = TD.authResponse.verificationCard;
  75. var startVotingKeyUnpacked = OV.parseStartVotingKey(startVotingKey, eventId);
  76. var verificationCardSecret = OV.parseVerificationCard(
  77. verificationCard.verificationCardKeystore, startVotingKeyUnpacked.pin);
  78. // encrypt vote
  79. var serializedEncrypterValues = OV.precomputeEncrypterValues(encParms);
  80. var encrypterValues = OV.deserializeEncrypterValues(serializedEncrypterValues);
  81. var keyValue = forge.jsbn.BigInteger.ONE;
  82. var element = new CL.commons.mathematical.ZpGroupElement(keyValue, encParms.p, encParms.q);
  83. var messages = [element];
  84. var encryptedOptions = OV.encryptOptions(messages, encParms, encrypterValues);
  85. // generate and ecrypt partial choice codes
  86. var partialChoiceCodes = OV.generatePartialChoiceCodes(messages, encParms, verificationCardSecret);
  87. var encryptedPCC = OV.encryptPartialChoiceCodes(partialChoiceCodes, encParms);
  88. // generate the proof
  89. var cipherTextExponentiations = OV.generateCipherTextExponentiations(
  90. encParms, encryptedOptions, verificationCardSecret);
  91. var plaintextEqualityProof = OV.generatePlaintextEqualityProof(
  92. encParms,
  93. encryptedOptions,
  94. encryptedPCC,
  95. verificationCardSecret, cipherTextExponentiations);
  96. // prove it
  97. var primaryCiphertext = (function() {
  98. var exponentiatedVoteCiphertext = CL.commons.mathematical.groupUtils.exponentiateArrays(
  99. [encryptedOptions.getGamma()].concat(encryptedOptions.getPhis()), // base elements
  100. new CL.commons.mathematical.Exponent(encParms.q, verificationCardSecret), // exponent
  101. encParms.group);
  102. return {
  103. getGamma: function() {
  104. return exponentiatedVoteCiphertext[0];
  105. },
  106. getPhis: function() {
  107. return exponentiatedVoteCiphertext.slice(1);
  108. },
  109. getComputationalValues: function() {
  110. return {
  111. gamma: exponentiatedVoteCiphertext[0],
  112. phis: exponentiatedVoteCiphertext.slice(1)
  113. };
  114. }
  115. };
  116. })();
  117. var secondaryCipherText = (function() {
  118. var compressedPRCphis = CL.commons.mathematical.groupUtils.compressGroupElements(
  119. encParms.group,
  120. encryptedPCC.getPhis());
  121. var gamma = encryptedPCC.getGamma();
  122. return {
  123. getGamma: function() {
  124. return gamma;
  125. },
  126. getPhis: function() {
  127. return [compressedPRCphis];
  128. },
  129. getComputationalValues: function() {
  130. return {
  131. gamma: gamma,
  132. phis: [compressedPRCphis]
  133. };
  134. }
  135. };
  136. })();
  137. var ebPubKey = encParms.optionsEncryptionKey;
  138. var prcPubKey = encParms.choiceCodesEncryptionKey;
  139. var primaryPublicKey = ebPubKey;
  140. var secondaryPublicKey = (function() {
  141. var compressedSecondaryPublicKey = CL.commons.mathematical.groupUtils.compressGroupElements(
  142. encParms.group,
  143. prcPubKey.getGroupElementsArray());
  144. return {
  145. getGroup: function() {
  146. return encParms.group;
  147. },
  148. getGroupElementsArray: function() {
  149. return [compressedSecondaryPublicKey];
  150. }
  151. };
  152. })();
  153. var verifies = (new CL.proofs.ProofsFactory()).createPlaintextEqualityProofVerifier(
  154. primaryCiphertext,
  155. primaryPublicKey,
  156. secondaryCipherText,
  157. secondaryPublicKey,
  158. plaintextEqualityProof,
  159. encParms.group).verify();
  160. expect(verifies).toBe(true);
  161. });
  162. });