precompute.spec.js 6.8 KB

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