/* * 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); // Plaintext proof tests. describe('should be able to ..', function() { var num_plaintext_elements = 3; var num_progress_checks = num_plaintext_elements + 1; var initialized = false; var plaintext; var publicKey; var ciphertext; var witness; var proof; var preComputedValues; var anotherPlaintext; var anotherPublicKey; var anotherWitness; var anotherCiphertext; var aShorterPlaintext; var aShorterCiphertext; // Initialize variables common to plaintext proof tests. beforeEach(function() { if (!initialized) { cryptolib('proofs.service', function(box) { plaintext = generatePlaintext(num_plaintext_elements); publicKey = generateElGamalKeyPair(num_plaintext_elements).getPublicKey(); ciphertext = generateCiphertext(publicKey, plaintext); witness = ciphertext.getR(); proof = box.proofs.service.createPlaintextProof( publicKey, ciphertext, plaintext, witness, _zpSubgroup); preComputedValues = box.proofs.service.preComputePlaintextProof( publicKey, _zpSubgroup); do { anotherPlaintext = generatePlaintext(num_plaintext_elements); } while (anotherPlaintext.equals(plaintext)); do { anotherPublicKey = generateElGamalKeyPair(num_plaintext_elements).getPublicKey(); } while (anotherPublicKey.getGroupElementsArray().equals( publicKey.getGroupElementsArray())); anotherCiphertext = generateCiphertext(publicKey, anotherPlaintext); do { anotherWitness = generateRandomExponent(_zpSubgroup); } while (anotherWitness.getValue().equals(witness.getValue())); aShorterPlaintext = generatePlaintext(num_plaintext_elements - 1); var subPublicKey = generateElGamalKeyPair(num_plaintext_elements - 1).getPublicKey(); aShorterCiphertext = generateCiphertext(subPublicKey, aShorterPlaintext); }); initialized = true; } }); it('generate and verify a plaintext proof', function() { cryptolib('proofs.service', function(box) { var verification = box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, plaintext, proof, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('and generate and verify a plaintext proof, using pre-computed values', function() { cryptolib('proofs.service', function(box) { var anotherProof = box.proofs.service.createPlaintextProof( publicKey, ciphertext, plaintext, witness, _zpSubgroup, preComputedValues); var verification = box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, plaintext, anotherProof, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('and generate and verify a plaintext proof, using null for the pre-computed values option', function() { cryptolib('proofs.service', function(box) { var anotherProof = box.proofs.service.createPlaintextProof( publicKey, ciphertext, plaintext, witness, _zpSubgroup, null); var verification = box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, plaintext, anotherProof, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('generate and verify a plaintext 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.verifyPlaintextProof( publicKey, ciphertext, plaintext, proofFromJson, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('generate and verify a plaintext 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.createPlaintextProof( publicKey, ciphertext, plaintext, witness, _zpSubgroup, preComputedValuesFromJson); var verification = box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, plaintext, anotherProof, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('and measure progress when generating a plaintext proof', function() { cryptolib('proofs.service', function(box) { initializeProgressMeter(); var anotherProof = box.proofs.service.createPlaintextProof( publicKey, ciphertext, plaintext, witness, _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.verifyPlaintextProof( publicKey, ciphertext, plaintext, anotherProof, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('and measure progress when pre-computing values for a plaintext proof', function() { cryptolib('proofs.service', function(box) { initializeProgressMeter(); box.proofs.service.preComputePlaintextProof( publicKey, _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.createPlaintextProof( publicKey, ciphertext, plaintext, witness, _zpSubgroup, preComputedValues); var verification = box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, plaintext, anotherProof, _zpSubgroup); expect(verification).toBeTruthy(); }); }); it('and measure progress when verifying a plaintext proof', function() { cryptolib('proofs.service', function(box) { initializeProgressMeter(); var verification = box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, plaintext, 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 plaintext proof that was generated with the wrong plaintext', function() { cryptolib('proofs.service', function(box) { var anotherProof = box.proofs.service.createPlaintextProof( publicKey, ciphertext, anotherPlaintext, witness, _zpSubgroup); var verification = box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, anotherPlaintext, anotherProof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a plaintext proof that was generated with the wrong public key', function() { cryptolib('proofs.service', function(box) { var anotherProof = box.proofs.service.createPlaintextProof( anotherPublicKey, ciphertext, plaintext, witness, _zpSubgroup); var verification = box.proofs.service.verifyPlaintextProof( anotherPublicKey, ciphertext, plaintext, anotherProof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a plaintext proof that was generated with the wrong witness', function() { cryptolib('proofs.service', function(box) { var anotherProof = box.proofs.service.createPlaintextProof( publicKey, ciphertext, plaintext, anotherWitness, _zpSubgroup); var verification = box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, plaintext, anotherProof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a plaintext proof when using the wrong plaintext', function() { cryptolib('proofs.service', function(box) { var verification = box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, anotherPlaintext, proof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a plaintext proof when using the wrong ciphertext', function() { cryptolib('proofs.service', function(box) { var verification = box.proofs.service.verifyPlaintextProof( publicKey, anotherCiphertext, plaintext, proof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and fail to verify a plaintext proof when using the wrong public key', function() { cryptolib('proofs.service', function(box) { var verification = box.proofs.service.verifyPlaintextProof( anotherPublicKey, ciphertext, plaintext, proof, _zpSubgroup); expect(verification).toBeFalsy(); }); }); it('and throw an exception when generating a plaintext proof, using null input data', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.createPlaintextProof( null, ciphertext, plaintext, witness, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.createPlaintextProof( publicKey, null, plaintext, witness, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.createPlaintextProof( publicKey, ciphertext, null, witness, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.createPlaintextProof( publicKey, ciphertext, plaintext, null, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.createPlaintextProof( publicKey, ciphertext, plaintext, witness, null); }).toThrow(); }); }); it('and throw an exception when generating a plaintext proof, using the wrong mathematical group', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.createPlaintextProof( publicKey, ciphertext, plaintext, witness, _anotherZpSubgroup); }).toThrow(); }); }); it('and throw an exception when generating a plaintext proof, using a public key and a plaintext with different lengths', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.createPlaintextProof( publicKey, ciphertext, aShorterPlaintext, witness, _zpSubgroup); }).toThrow(); }); }); it('and throw an exception when generating a plaintext proof, using a public key and a ciphertext with the incorrect length relation', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.createPlaintextProof( publicKey, aShorterCiphertext, plaintext, witness, _zpSubgroup); }).toThrow(); }); }); it('and throw an exception when generating a plaintext proof, using a progress callback function that is not a function', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.createPlaintextProof( publicKey, ciphertext, plaintext, witness, _zpSubgroup, PROGRESS_PERCENT_MIN_CHECK_INTERVAL); }).toThrow(); }); }); it('and throw an exception when pre-computing values for a plaintext proof, using null input data', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.preComputePlaintextProof(null, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.preComputePlaintextProof(publicKey, null); }).toThrow(); }); }); it('and throw an exception when generating a plaintext 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.createPlaintextProof( publicKey, ciphertext, plaintext, witness, _zpSubgroup, progressCallback, progressCallback); }).toThrow(); }); }); it('and throw an exception when pre-computing values for a plaintext proof, using null input data', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.preComputePlaintextProof(null, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.preComputePlaintextProof(publicKey, null); }).toThrow(); }); }); it('and throw an exception when verifying a plaintext proof, using null input data', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.verifyPlaintextProof( null, ciphertext, plaintext, proof, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.verifyPlaintextProof( publicKey, null, plaintext, proof, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, null, proof, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, plaintext, null, _zpSubgroup); }).toThrow(); expect(function() { box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, plaintext, proof, null); }).toThrow(); }); }); it('and throw an exception when verifying a plaintext proof, using the wrong mathematical group', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, plaintext, proof, _anotherZpSubgroup); }).toThrow(); }); }); it('and throw an exception when verifying a plaintext proof, using a public key and a plaintext with different lengths', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, aShorterPlaintext, proof, _zpSubgroup); }).toThrow(); }); }); it('and throw an exception when verifying a plaintext proof, using a public key and a ciphertext with the incorrect length relation', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.verifyPlaintextProof( publicKey, aShorterCiphertext, plaintext, proof, _zpSubgroup); }).toThrow(); }); }); it('and throw an exception when verifying a plaintext proof, using a progress callback function that is not a function', function() { cryptolib('proofs.service', function(box) { expect(function() { box.proofs.service.verifyPlaintextProof( publicKey, ciphertext, plaintext, proof, _zpSubgroup, PROGRESS_PERCENT_MIN_CHECK_INTERVAL); }).toThrow(); }); }); it('and throw an exception when verifying a plaintext 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.verifyPlaintextProof( publicKey, ciphertext, plaintext, proof, _zpSubgroup, progressCallback, progressCallback); }).toThrow(); }); }); }); });