/* * Copyright 2018 Scytl Secure Electronic Voting SA * * All rights reserved * * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package */ /* jshint node:true */ 'use strict'; var SimplePlaintextEqualityProofTestData = require('./data/simple-plaintext-equality-proof-data'); var cryptoPolicy = require('scytl-cryptopolicy'); var zkProof = require('../lib/index'); var elGamal = require('scytl-elgamal'); var messageDigest = require('scytl-messagedigest'); var mathematical = require('scytl-mathematical'); var secureRandom = require('scytl-securerandom'); var codec = require('scytl-codec'); describe('The zero-knowledge proof module should be able to ...', function() { var proofService_; var group_; var secret_; var anotherSecret_; var primaryPublicKey_; var secondaryPublicKey_; var anotherPrimaryPublicKey_; var anotherSecondaryPublicKey_; var primaryCiphertext_; var secondaryCiphertext_; var anotherPrimaryCiphertext_; var anotherSecondaryCiphertext_; var data_; var otherData_; var secretForNonSimplePlaintext_; var primaryCiphertextForNonSimplePlaintext_; var secondaryCiphertextForNonSimplePlaintext_; var proofHandler_; var proof_; var preComputation_; beforeAll(function() { proofService_ = zkProof.newService(); var testData = new SimplePlaintextEqualityProofTestData(); var elGamalService = elGamal.newService(); group_ = testData.getGroup(); var primaryEncryptedElements = testData.getPrimaryEncryptedElements(); secret_ = primaryEncryptedElements.secret; var otherPrimaryEncryptedElements = testData.getOtherPrimaryEncryptedElements(); anotherSecret_ = otherPrimaryEncryptedElements.secret; primaryPublicKey_ = testData.getPrimaryPublicKey(); secondaryPublicKey_ = testData.getSecondaryPublicKey(); anotherPrimaryPublicKey_ = testData.getAnotherPrimaryPublicKey(); anotherSecondaryPublicKey_ = testData.getAnotherSecondaryPublicKey(); primaryCiphertext_ = elGamalService.newEncryptedElements( primaryEncryptedElements.gamma, primaryEncryptedElements.phis); var secondaryEncryptedElements = testData.getSecondaryEncryptedElements(); secondaryCiphertext_ = elGamalService.newEncryptedElements( secondaryEncryptedElements.gamma, secondaryEncryptedElements.phis); anotherPrimaryCiphertext_ = testData.getOtherPrimaryEncryptedElements(); anotherSecondaryCiphertext_ = testData.getOtherSecondaryEncryptedElements(); data_ = testData.getStringData(); otherData_ = testData.getOtherStringData(); var primaryEncryptedElementsForNonSimplePlaintext = testData.getPrimaryEncryptedElementsForNonSimplePlaintext(); secretForNonSimplePlaintext_ = primaryEncryptedElementsForNonSimplePlaintext.secret; primaryCiphertextForNonSimplePlaintext_ = elGamalService.newEncryptedElements( primaryEncryptedElementsForNonSimplePlaintext.gamma, primaryEncryptedElementsForNonSimplePlaintext.phis); var secondaryEncryptedElementsForNonSimplePlaintext = testData.getSecondaryEncryptedElementsForNonSimplePlaintext(); secondaryCiphertextForNonSimplePlaintext_ = elGamalService.newEncryptedElements( secondaryEncryptedElementsForNonSimplePlaintext.gamma, secondaryEncryptedElementsForNonSimplePlaintext.phis); proofHandler_ = proofService_.newSimplePlaintextEqualityProofHandler(group_).init( primaryPublicKey_, secondaryPublicKey_); proof_ = proofHandler_.generate( secret_, primaryCiphertext_, secondaryCiphertext_); preComputation_ = proofHandler_.preCompute(); }); beforeEach(function() { proofHandler_ = proofService_.newSimplePlaintextEqualityProofHandler(group_).init( primaryPublicKey_, secondaryPublicKey_); }); describe('create a zero-knowledge proof service that should be able to ..', function() { describe('create a simple plaintext equality proof handler that should be able to', function() { it('generate and verify a simple plaintext equality proof', function() { var verified = proofHandler_.verify( proof_, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeTruthy(); }); it('generate and verify a simple plaintext equality proof, using a specified cryptographic policy', function() { var policy = cryptoPolicy.newInstance(); policy.proofs.messageDigest.algorithm = cryptoPolicy.options.proofs.messageDigest.algorithm.SHA512_224; var proofService = zkProof.newService({policy: policy}); var proofHandler = proofService.newSimplePlaintextEqualityProofHandler(group_).init( primaryPublicKey_, secondaryPublicKey_); proof_ = proofHandler.generate( secret_, primaryCiphertext_, secondaryCiphertext_); var verified = proofHandler.verify( proof_, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeTruthy(); }); it('generate and verify a simple plaintext equality proof, using a specified message digest service', function() { var policy = cryptoPolicy.newInstance(); policy.proofs.messageDigest.algorithm = cryptoPolicy.options.proofs.messageDigest.algorithm.SHA512_224; var messageDigestService = messageDigest.newService({policy: policy}); var proofService = zkProof.newService({messageDigestService: messageDigestService}); var proofHandler = proofService.newSimplePlaintextEqualityProofHandler(group_).init( primaryPublicKey_, secondaryPublicKey_); proof_ = proofHandler.generate( secret_, primaryCiphertext_, secondaryCiphertext_); var verified = proofHandler.verify( proof_, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeTruthy(); }); it('generate and verify a simple plaintext equality proof, using a specified secure random service object', function() { var proofService = zkProof.newService( {secureRandomService: secureRandom.newService()}); var proofHandler = proofService.newSimplePlaintextEqualityProofHandler(group_).init( primaryPublicKey_, secondaryPublicKey_); proof_ = proofHandler.generate( secret_, primaryCiphertext_, secondaryCiphertext_); var verified = proofHandler.verify( proof_, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeTruthy(); }); it('generate and verify a simple plaintext equality proof, using a specified mathematical service object', function() { var proofService = zkProof.newService( {mathematicalService: mathematical.newService()}); var proofHandler = proofService.newSimplePlaintextEqualityProofHandler(group_).init( primaryPublicKey_, secondaryPublicKey_); proof_ = proofHandler.generate( secret_, primaryCiphertext_, secondaryCiphertext_); var verified = proofHandler.verify( proof_, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeTruthy(); }); it('generate and verify a plaintext proof, using provided auxiliary data', function() { // Data as string. var proof = proofHandler_.generate( secret_, primaryCiphertext_, secondaryCiphertext_, {data: data_}); var verified = proofHandler_.verify( proof, primaryCiphertext_, secondaryCiphertext_, {data: data_}); expect(verified).toBeTruthy(); // Data as bytes. proof = proofHandler_.generate( secret_, primaryCiphertext_, secondaryCiphertext_, {data: codec.utf8Encode(data_)}); verified = proofHandler_.verify( proof, primaryCiphertext_, secondaryCiphertext_, {data: codec.utf8Encode(data_)}); expect(verified).toBeTruthy(); }); it('generate and verify a simple plaintext equality proof, using a pre-computation', function() { var proof = proofHandler_.generate( secret_, primaryCiphertext_, secondaryCiphertext_, {preComputation: preComputation_}); var verified = proofHandler_.verify( proof, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeTruthy(); }); it('generate and verify a simple plaintext equality proof, using empty auxiliary data', function() { var proof = proofHandler_.generate( secret_, primaryCiphertext_, secondaryCiphertext_, {data: ''}); var verified = proofHandler_.verify( proof, primaryCiphertext_, secondaryCiphertext_, {data: ''}); expect(verified).toBeTruthy(); }); it('pre-compute, generate and verify a simple plaintext proof, using method chaining', function() { var preComputation = proofService_.newSimplePlaintextEqualityProofHandler(group_) .init(primaryPublicKey_, secondaryPublicKey_) .preCompute(); var proof = proofService_.newSimplePlaintextEqualityProofHandler(group_) .init(primaryPublicKey_, secondaryPublicKey_) .generate( secret_, primaryCiphertext_, secondaryCiphertext_, {data: data_, preComputation: preComputation}); var verified = proofService_.newSimplePlaintextEqualityProofHandler(group_) .init(primaryPublicKey_, secondaryPublicKey_) .verify( proof, primaryCiphertext_, secondaryCiphertext_, {data: data_}); expect(verified).toBeTruthy(); }); it('create a new simple plaintext equality ZeroKnowledgeProof object', function() { var hash = proof_.hash; var values = proof_.values; var proof = proofService_.newProof(hash, values); var verified = proofHandler_.verify( proof, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeTruthy(); }); it('create a new simple plaintext equality ZeroKnowledgeProofPreComputation object', function() { var exponents = preComputation_.exponents; var phiOutputs = preComputation_.phiOutputs; var preComputation = proofService_.newPreComputation(exponents, phiOutputs); var proof = proofHandler_.generate( secret_, primaryCiphertext_, secondaryCiphertext_, {preComputation: preComputation}); var verified = proofHandler_.verify( proof, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeTruthy(); }); it('serialize and deserialize a simple plaintext equality', function() { var proofJson = proof_.toJson(); var proof = proofService_.newProof(proofJson); var verified = proofHandler_.verify( proof, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeTruthy(); }); it('serialize and deserialize a simple plaintext equality pre-computation', function() { var preComputationJson = preComputation_.toJson(); var preComputation = proofService_.newPreComputation(preComputationJson); var proof = proofHandler_.generate( secret_, primaryCiphertext_, secondaryCiphertext_, {preComputation: preComputation}); var verified = proofHandler_.verify( proof, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeTruthy(); }); it('fail to verify a simple plaintext equality proof that was generated with a secret not used to generate the ciphertexts', function() { var proof = proofHandler_.generate( anotherSecret_, primaryCiphertext_, secondaryCiphertext_); var verified = proofHandler_.verify( proof, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeFalsy(); }); it('fail to verify a simple plaintext equality proof that was generated with a primary publicKey not used to generate the primary ciphertext', function() { proofHandler_.init(anotherPrimaryPublicKey_, secondaryPublicKey_); var proof = proofHandler_.generate( secret_, primaryCiphertext_, secondaryCiphertext_); var verified = proofHandler_.verify( proof, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeFalsy(); }); it('fail to verify a simple plaintext equality proof that was generated with a secondary publicKey not used to generate the secondary ciphertext', function() { proofHandler_.init(primaryPublicKey_, anotherSecondaryPublicKey_); var proof = proofHandler_.generate( secret_, primaryCiphertext_, secondaryCiphertext_); var verified = proofHandler_.verify( proof, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeFalsy(); }); it('fail to verify a simple plaintext equality proof that was generated with a primary ciphertext not generated from the simple plaintext', function() { var proof = proofHandler_.generate( secret_, anotherPrimaryCiphertext_, secondaryCiphertext_); var verified = proofHandler_.verify( proof, anotherPrimaryCiphertext_, secondaryCiphertext_); expect(verified).toBeFalsy(); }); it('fail to verify a simple plaintext equality proof that was generated with a secondary ciphertext not generated from the simple plaintext', function() { var proof = proofHandler_.generate( secret_, primaryCiphertext_, anotherSecondaryCiphertext_); var verified = proofHandler_.verify( proof, primaryCiphertext_, anotherSecondaryCiphertext_); expect(verified).toBeFalsy(); }); it('fail to verify a simple plaintext equality proof that was generated with plaintext that is not simple', function() { var proof = proofHandler_.generate( secretForNonSimplePlaintext_, primaryCiphertextForNonSimplePlaintext_, secondaryCiphertextForNonSimplePlaintext_); var verified = proofHandler_.verify( proof, primaryCiphertextForNonSimplePlaintext_, secondaryCiphertextForNonSimplePlaintext_); expect(verified).toBeFalsy(); }); it('fail to verify a simple plaintext equality proof when using a primary public key not used to generate the proof', function() { var verified = proofHandler_.init(anotherPrimaryPublicKey_, secondaryPublicKey_) .verify(proof_, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeFalsy(); }); it('fail to verify a simple plaintext equality proof when using a secondary public key not used to generate the proof', function() { var verified = proofHandler_.init(primaryPublicKey_, anotherSecondaryPublicKey_) .verify(proof_, primaryCiphertext_, secondaryCiphertext_); expect(verified).toBeFalsy(); }); it('fail to verify a simple plaintext equality proof when using a primary ciphertext not used to generate the proof', function() { var verified = proofHandler_.verify( proof_, anotherPrimaryCiphertext_, secondaryCiphertext_); expect(verified).toBeFalsy(); }); it('fail to verify a simple plaintext equality proof when using a secondary ciphertext not used to generate the proof', function() { var verified = proofHandler_.verify( proof_, primaryCiphertext_, anotherSecondaryCiphertext_); expect(verified).toBeFalsy(); }); it('fail to verify a simple plaintext equality proof when using auxiliary data not used to generate the proof', function() { var proof = proofHandler_.generate( secret_, primaryCiphertext_, secondaryCiphertext_, {data: data_}); var verified = proofHandler_.verify( proof, primaryCiphertext_, secondaryCiphertext_, {data: otherData_}); expect(verified).toBeFalsy(); }); it('throw an error when generating a proof before the handler has been initialized with any pubilc key', function() { var proofHandler = proofService_.newSimplePlaintextEqualityProofHandler(group_); expect(function() { proofHandler.generate( secret_, primaryCiphertext_, secondaryCiphertext_); }).toThrow(); }); it('throw an error when pre-computing a proof before the handler has been initialized with any pubilc key', function() { var proofHandler = proofService_.newSimplePlaintextEqualityProofHandler(group_); expect(function() { proofHandler.preCompute(); }).toThrow(); }); it('throw an error when verifying a proof before the handler has been initialized with any pubilc key', function() { var proofHandler = proofService_.newSimplePlaintextEqualityProofHandler(group_); expect(function() { proofHandler.verify( proof_, primaryCiphertext_, secondaryCiphertext_); }).toThrow(); }); }); }); });