/* * 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 */ describe('Proofs service ...', function() { 'use strict'; // Initialize variables common to all proof tests. beforeEach(initializeTestVars); // Simple plaintext equality proof tests. describe('should be able to ..', function() { var num_plaintext_elements = 4; var num_progress_checks = num_plaintext_elements + 1; var initialized = false; var plaintext; var publicKey; var primaryPublicKey; var secondaryPublicKey; var ciphertext; var primaryCiphertext; var secondaryCiphertext; var witness; var proof; var preComputedValues; var anotherPlaintext; var anotherPrimaryPublicKey; var anotherSecondaryPublicKey; var anotherPrimaryCiphertext; var anotherSecondaryCiphertext; var anotherWitness; var aNonSimplePrimaryCiphertext; var aNonSimpleSecondaryCiphertext; var aNonSimpleWitness; var aShorterPrimaryPublicKey; var aShorterSecondaryPublicKey; var aShorterPrimaryCiphertext; // Initialize variables common to simple plaintext equality proof tests. beforeEach(function() { if (!initialized) { cryptolib('proofs.service', function(box) { plaintext = generateSimplePlaintext(num_plaintext_elements); publicKey = generateElGamalKeyPair(num_plaintext_elements).getPublicKey(); primaryPublicKey = getSubElGamalPublicKey( publicKey, 0, (num_plaintext_elements / 2)); secondaryPublicKey = getSubElGamalPublicKey( publicKey, (num_plaintext_elements / 2), num_plaintext_elements); ciphertext = generateCiphertext(publicKey, plaintext); primaryCiphertext = getSubCiphertext(ciphertext, 0, (num_plaintext_elements / 2)); secondaryCiphertext = getSubCiphertext( ciphertext, (num_plaintext_elements / 2), num_plaintext_elements); witness = ciphertext.getR(); proof = box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup); preComputedValues = box.proofs.service.preComputeSimplePlaintextEqualityProof( primaryPublicKey, secondaryPublicKey, _zpSubgroup); do { anotherPlaintext = generateSimplePlaintext(num_plaintext_elements); } while (anotherPlaintext.equals(plaintext)); do { anotherPrimaryPublicKey = generateElGamalKeyPair(num_plaintext_elements / 2) .getPublicKey(); } while (anotherPrimaryPublicKey.getGroupElementsArray().equals( primaryPublicKey.getGroupElementsArray())); do { anotherSecondaryPublicKey = generateElGamalKeyPair(num_plaintext_elements / 2) .getPublicKey(); } while (anotherSecondaryPublicKey.getGroupElementsArray().equals( secondaryPublicKey.getGroupElementsArray())); var subPlaintext; do { subPlaintext = generateSimplePlaintext(num_plaintext_elements / 2); anotherPrimaryCiphertext = generateCiphertext(primaryPublicKey, subPlaintext); } while (subPlaintext.equals( plaintext.slice(0, (num_plaintext_elements / 2)))); do { subPlaintext = generateSimplePlaintext(num_plaintext_elements / 2); anotherSecondaryCiphertext = generateCiphertext(secondaryPublicKey, subPlaintext); } while (subPlaintext.equals(plaintext.slice( (num_plaintext_elements / 2), num_plaintext_elements))); do { anotherWitness = generateRandomExponent(_zpSubgroup); } while (anotherWitness.getValue().equals(witness.getValue())); var nonSimplePlaintext = generateNonSimplePlaintext(num_plaintext_elements); var nonSimpleCiphertext = generateCiphertext(publicKey, nonSimplePlaintext); aNonSimplePrimaryCiphertext = getSubCiphertext( nonSimpleCiphertext, 0, (num_plaintext_elements / 2)); aNonSimpleSecondaryCiphertext = getSubCiphertext( nonSimpleCiphertext, (num_plaintext_elements / 2), num_plaintext_elements); aNonSimpleWitness = nonSimpleCiphertext.getR(); aShorterPrimaryPublicKey = getSubElGamalPublicKey( publicKey, 1, (num_plaintext_elements / 2)); aShorterSecondaryPublicKey = getSubElGamalPublicKey( publicKey, ((num_plaintext_elements / 2) + 1), num_plaintext_elements); aShorterPrimaryCiphertext = getSubCiphertext(ciphertext, 1, (num_plaintext_elements / 2)); }); } initialized = true; }); it('generate and verify a simple plaintext equality proof', function() { cryptolib('proofs.service', function(box) { var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, proof, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('and generate and verify a simple plaintext equality proof, using pre-computed values', function() { cryptolib('proofs.service', function(box) { expect(preComputedValues).toBeDefined(); var anotherProof = box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup, preComputedValues); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, anotherProof, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('and generate and verify a simple plaintext equality proof, using null for the pre-computed values option', function() { cryptolib('proofs.service', function(box) { var anotherProof = box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup, null); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, anotherProof, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('generate and verify a simple plaintext equality proof, using serialization', function() { cryptolib('commons.mathematical', 'proofs', function(box) { var proofAsJson = proof.stringify(); var proofFromJson = box.proofs.utils.deserializeProof(proofAsJson); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, proofFromJson, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('generate and verify a simple plaintext equality proof, using pre-computed values and serialization', function() { cryptolib('commons.mathematical', 'proofs', function(box) { var preComputedValuesAsJson = preComputedValues.stringify(); var preComputedValuesFromJson = box.proofs.utils.deserializeProofPreComputedValues( preComputedValuesAsJson); var anotherProof = box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup, preComputedValuesFromJson); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, anotherProof, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('and measure progress when generating a simple plaintext equality proof', function() { cryptolib('proofs.service', function(box) { initializeProgressMeter(); var anotherProof = box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup, progressCallback, PROGRESS_PERCENT_MIN_CHECK_INTERVAL); expect(_progressPercentSum) .toBe(getProgressPercentSum( num_progress_checks, PROGRESS_PERCENT_MIN_CHECK_INTERVAL)); expect(_progressPercentLatest).toBe(100); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, anotherProof, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('and measure progress when pre-computing a simple plaintext equality proof', function() { cryptolib('proofs.service', function(box) { initializeProgressMeter(); box.proofs.service.preComputeSimplePlaintextEqualityProof( primaryPublicKey, secondaryPublicKey, _zpSubgroup, progressCallback, PROGRESS_PERCENT_MIN_CHECK_INTERVAL); expect(_progressPercentSum) .toBe(getProgressPercentSum( num_progress_checks, PROGRESS_PERCENT_MIN_CHECK_INTERVAL)); expect(_progressPercentLatest).toBe(100); var anotherProof = box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup, preComputedValues); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, anotherProof, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('and measure progress when verifying a simple plaintext equality proof', function() { cryptolib('proofs.service', function(box) { initializeProgressMeter(); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, proof, _zpSubgroup, progressCallback, PROGRESS_PERCENT_MIN_CHECK_INTERVAL); expect(verification).toBeTruthy(); expect(_progressPercentSum) .toBe(getProgressPercentSum( num_progress_checks, PROGRESS_PERCENT_MIN_CHECK_INTERVAL)); expect(_progressPercentLatest).toBe(100); }); }); it('and fail to verify a simple plaintext equality proof that was generated with the wrong primary ciphertext', function() { cryptolib('proofs.service', function(box) { var anotherProof = box.proofs.service.createSimplePlaintextEqualityProof( anotherPrimaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( anotherPrimaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, anotherProof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a simple plaintext equality proof that was generated with the wrong primary public key', function() { cryptolib('proofs.service', function(box) { var anotherProof = box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, anotherPrimaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, anotherPrimaryPublicKey, secondaryCiphertext, secondaryPublicKey, anotherProof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a simple plaintext equality proof that was generated with the wrong secondary ciphertext', function() { cryptolib('proofs.service', function(box) { var anotherProof = box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, anotherSecondaryCiphertext, secondaryPublicKey, _zpSubgroup); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, anotherSecondaryCiphertext, secondaryPublicKey, anotherProof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a simple plaintext equality proof that was generated with the wrong secondary public key', function() { cryptolib('proofs.service', function(box) { var anotherProof = box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, anotherSecondaryPublicKey, _zpSubgroup); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, anotherSecondaryPublicKey, anotherProof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a simple plaintext equality proof that was generated with the wrong witness', function() { cryptolib('proofs.service', function(box) { var anotherProof = box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, anotherWitness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, anotherProof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a simple plaintext equality proof that was generated with plaintext that is not simple', function() { cryptolib('proofs.service', function(box) { var anotherProof = box.proofs.service.createSimplePlaintextEqualityProof( aNonSimplePrimaryCiphertext, primaryPublicKey, aNonSimpleWitness, aNonSimpleSecondaryCiphertext, secondaryPublicKey, _zpSubgroup); var verification = box.proofs.service.verifySimplePlaintextEqualityProof( aNonSimplePrimaryCiphertext, primaryPublicKey, aNonSimpleSecondaryCiphertext, secondaryPublicKey, anotherProof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a simple plaintext equality proof when using the wrong primary ciphertext', function() { cryptolib('proofs.service', function(box) { var verification = box.proofs.service.verifySimplePlaintextEqualityProof( anotherPrimaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, proof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a simple plaintext equality proof when using the wrong primary public key', function() { cryptolib('proofs.service', function(box) { var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, anotherPrimaryPublicKey, secondaryCiphertext, secondaryPublicKey, proof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a simple plaintext equality proof when using the wrong secondary ciphertext', function() { cryptolib('proofs.service', function(box) { var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, anotherSecondaryCiphertext, secondaryPublicKey, proof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a simple plaintext equality proof when using the wrong secondary public key', function() { cryptolib('proofs.service', function(box) { var verification = box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, anotherSecondaryPublicKey, proof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and throw an exception when generating a simple plaintext equality proof, using null input data', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.createSimplePlaintextEqualityProof( null, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, null, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, null, secondaryCiphertext, secondaryPublicKey, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, null, secondaryPublicKey, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, null, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, null); }).toThrow(); }); }); it('and throw an exception when generating a simple plaintext proof, using the wrong mathematical group', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _anotherZpSubgroup); }).toThrow(); }); }); it('and throw an exception when generating a simple plaintext equality proof, using primary and secondary public keys with different lengths', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, aShorterPrimaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup); }).toThrow(); }); }); it('and throw an exception when generating a simple plaintext equality proof, using primary and secondary ciphertexts with different lengths', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.createSimplePlaintextEqualityProof( aShorterPrimaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup); }).toThrow(); }); }); it('and throw an exception when generating a simple plaintext equality proof, using public keys and ciphertexts with a incorrect length relation', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, aShorterPrimaryPublicKey, witness, secondaryCiphertext, aShorterSecondaryPublicKey, _zpSubgroup); }).toThrow(); }); }); it('and throw an exception when generating a simple plaintext equality proof, using a progress callback function that is not a function', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup, PROGRESS_PERCENT_MIN_CHECK_INTERVAL); }).toThrow(); }); }); it('and throw an exception when generating a simple plaintext equality proof, using a progress percent check interval that is not a number', function() { cryptolib('proofs.service', function(box) { var percentMeasuredLatest = 0; var progressCallback = function(progressPercent) { percentMeasuredLatest = progressPercent; }; expect(function() { box.proofs.service.createSimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, witness, secondaryCiphertext, secondaryPublicKey, _zpSubgroup, progressCallback, progressCallback); }).toThrow(); }); }); it('and throw an exception when pre-computing values for a simple plaintext equality proof, using null input data', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.preComputeSimplePlaintextEqualityProof( null, secondaryPublicKey, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.preComputeSimplePlaintextEqualityProof( primaryPublicKey, null, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.preComputeSimplePlaintextEqualityProof( primaryPublicKey, secondaryPublicKey, null); }).toThrow(); }); }); it('and throw an exception when verifying a simple plaintext equality proof, using null input data', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.verifySimplePlaintextEqualityProof( null, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, proof, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, null, secondaryCiphertext, secondaryPublicKey, proof, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, null, secondaryPublicKey, proof, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, null, proof, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, null, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, proof, null); }).toThrow(); }); }); it('and throw an exception when verifying a simple plaintext equality proof, using the wrong mathematical group', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, proof, _anotherZpSubgroup); }).toThrow(); }); }); it('and throw an exception when verifying a simple plaintext equality proof, using primary and secondary public keys with different lengths', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, aShorterPrimaryPublicKey, secondaryCiphertext, secondaryPublicKey, proof, _zpSubgroup); }).toThrow(); }); }); it('and throw an exception when verifying a simple plaintext equality proof, using primary and secondary ciphertexts with different lengths', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.verifySimplePlaintextEqualityProof( aShorterPrimaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, proof, _zpSubgroup); }).toThrow(); }); }); it('and throw an exception when verifying a simple plaintext equality proof, using public keys and ciphertexts with a incorrect length relation', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, aShorterPrimaryPublicKey, secondaryCiphertext, aShorterSecondaryPublicKey, proof, _zpSubgroup); }).toThrow(); }); }); it('and throw an exception when verifying a simple plaintext equality proof, using a progress callback function that is not a function', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, proof, _zpSubgroup, _zpSubgroup, PROGRESS_PERCENT_MIN_CHECK_INTERVAL); }).toThrow(); }); }); it('and throw an exception when verifying a simple plaintext equality proof, using a progress percent check interval that is not a number', function() { cryptolib('proofs.service', function(box) { var percentMeasuredLatest = 0; var progressCallback = function(progressPercent) { percentMeasuredLatest = progressPercent; }; expect(function() { box.proofs.service.verifySimplePlaintextEqualityProof( primaryCiphertext, primaryPublicKey, secondaryCiphertext, secondaryPublicKey, proof, _zpSubgroup, progressCallback, progressCallback); }).toThrow(); }); }); }); });