/* * 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 CommonTestData = require('./data/common-data'); var ValidationTestData = require('./data/validation-data'); var elGamal = require('../lib/index'); var secureRandom = require('scytl-securerandom'); describe('The ElGamal cryptography module should be able to ...', function() { var elGamalService_; var secureRandomGenerator_; var group_; var publicKey_; var privateKey_; var publicKeyElements_; var privateKeyExponents_; var elements_; var elementValueStrings_; var nonObject_; var emptyObject_; var nonSecureRandomService_; var nonSecureRandomGenerator_; var nonMathematicalService_; var nonBoolean_; var nonString_; var nonJsonString_; var nonArray_; var nonStringArray_; var nonMathObject_; var nonMathObjectArray_; var nonElGamalObject_; var elementsFromAnotherGroup_; var publicKeyFromAnotherGroup_; var elGamalEncrypter_; var elGamalDecrypter_; var elGamalPrngDecrypter_; var encryptedElements_; var gamma_; var phis_; var secret_; var encryptedElementsFromAnotherGroup_; beforeAll(function() { elGamalService_ = elGamal.newService(); secureRandomGenerator_ = secureRandom.newService().newRandomGenerator(); var commonTestData = new CommonTestData(); group_ = commonTestData.getGroup(); publicKey_ = commonTestData.getPublicKey(); privateKey_ = commonTestData.getPrivateKey(); publicKeyElements_ = commonTestData.getPublicKeyElements(); privateKeyExponents_ = commonTestData.getPrivateKeyExponents(); elements_ = commonTestData.getZpGroupElements(); elementValueStrings_ = commonTestData.getZpGroupElementValueStrings(); var validationTestData = new ValidationTestData(); nonObject_ = validationTestData.getNonObject(); emptyObject_ = validationTestData.getEmptyObject(); nonSecureRandomService_ = validationTestData.getNonSecureRandomService(); nonSecureRandomGenerator_ = validationTestData.getNonSecureRandomGenerator(); nonMathematicalService_ = validationTestData.getNonMathematicalService(); nonBoolean_ = validationTestData.getNonBoolean(); nonString_ = validationTestData.getNonString(); nonJsonString_ = validationTestData.getNonJsonString(); nonArray_ = validationTestData.getNonArray(); nonStringArray_ = validationTestData.getNonStringArray(); nonMathObject_ = validationTestData.getNonMathObject(); nonMathObjectArray_ = validationTestData.getNonMathObjectArray(); nonElGamalObject_ = validationTestData.getNonElGamalObject(); elementsFromAnotherGroup_ = validationTestData.getElementsFromAnotherGroup(); publicKeyFromAnotherGroup_ = validationTestData.getPublicKeyFromAnotherGroup(); }); beforeEach(function() { elGamalEncrypter_ = elGamalService_.newEncrypter().init(publicKey_); elGamalDecrypter_ = elGamalService_.newDecrypter().init(privateKey_); elGamalPrngDecrypter_ = elGamalService_.newPrngDecrypter().init( publicKey_, secureRandomGenerator_); var encryptedElementsAndSecret = elGamalEncrypter_.encrypt(elements_, {saveSecret: true}); gamma_ = encryptedElementsAndSecret.gamma; phis_ = encryptedElementsAndSecret.phis; secret_ = encryptedElementsAndSecret.secret; encryptedElements_ = elGamalService_.newEncryptedElements( encryptedElementsAndSecret.gamma, encryptedElementsAndSecret.phis); encryptedElementsFromAnotherGroup_ = elGamalService_.newEncrypter() .init(publicKeyFromAnotherGroup_) .encrypt(elementsFromAnotherGroup_); }); describe('create an ElGamal cryptography service that should be able to ..', function() { it('throw an error when being created, using an invalid secure random service object', function() { expect(function() { Object.create(elGamal.newService({secureRandomService: null})); }).toThrow(); expect(function() { Object.create(elGamal.newService({secureRandomService: nonObject_})); }).toThrow(); expect(function() { Object.create( elGamal.newService({secureRandomService: emptyObject_})); }).toThrow(); }); it('throw an error when being created, using an invalid mathematical service object', function() { expect(function() { Object.create(elGamal.newService({mathematicalService: null})); }).toThrow(); expect(function() { Object.create(elGamal.newService({mathematicalService: nonObject_})); }).toThrow(); expect(function() { Object.create( elGamal.newService({mathematicalService: emptyObject_})); }).toThrow(); }); it('throw an error when creating a new ElGamalPublicKey object, using invalid input data', function() { expect(function() { elGamalService_.newPublicKey(group_); }).toThrow(); expect(function() { elGamalService_.newPublicKey(undefined, publicKeyElements_); }).toThrow(); expect(function() { elGamalService_.newPublicKey(null, publicKeyElements_); }).toThrow(); expect(function() { elGamalService_.newPublicKey(nonMathObject_, publicKeyElements_); }).toThrow(); expect(function() { elGamalService_.newPublicKey(group_, undefined); }).toThrow(); expect(function() { elGamalService_.newPublicKey(group_, null); }).toThrow(); expect(function() { elGamalService_.newPublicKey(group_, nonArray_); }).toThrow(); expect(function() { elGamalService_.newPublicKey(group_, nonMathObjectArray_); }).toThrow(); expect(function() { elGamalService_.newPublicKey(nonJsonString_); }).toThrow(); }); it('throw an error when creating a new ElGamalPrivateKey object, using invalid input data', function() { expect(function() { elGamalService_.newPrivateKey(undefined, privateKeyExponents_); }).toThrow(); expect(function() { elGamalService_.newPrivateKey(null, privateKeyExponents_); }).toThrow(); expect(function() { elGamalService_.newPrivateKey(nonObject_, privateKeyExponents_); }).toThrow(); expect(function() { elGamalService_.newPrivateKey(emptyObject_, privateKeyExponents_); }).toThrow(); expect(function() { elGamalService_.newPrivateKey(group_); }).toThrow(); expect(function() { elGamalService_.newPrivateKey(group_, undefined); }).toThrow(); expect(function() { elGamalService_.newPrivateKey(group_, null); }).toThrow(); expect(function() { elGamalService_.newPrivateKey(group_, nonArray_); }).toThrow(); expect(function() { elGamalService_.newPrivateKey(group_, nonMathObjectArray_); }).toThrow(); expect(function() { elGamalService_.newPrivateKey(nonJsonString_); }).toThrow(); }); it('throw an error when creating a new ElGamalKeyPair object, using invalid input data', function() { expect(function() { elGamalService_.newKeyPair(publicKey_); }).toThrow(); expect(function() { elGamalService_.newKeyPair(undefined, privateKey_); }).toThrow(); expect(function() { elGamalService_.newKeyPair(null, privateKey_); }).toThrow(); expect(function() { elGamalService_.newKeyPair(nonElGamalObject_, privateKey_); }).toThrow(); expect(function() { elGamalService_.newKeyPair(publicKey_, undefined); }).toThrow(); expect(function() { elGamalService_.newKeyPair(publicKey_, null); }).toThrow(); expect(function() { elGamalService_.newKeyPair(publicKey_, nonElGamalObject_); }).toThrow(); }); it('throw an error when creating a new ElGamalEncryptedElements object, using invalid input data', function() { expect(function() { elGamalService_.newEncryptedElements(undefined, phis_); }).toThrow(); expect(function() { elGamalService_.newEncryptedElements(null, phis_); }).toThrow(); expect(function() { elGamalService_.newEncryptedElements(nonObject_, phis_); }).toThrow(); expect(function() { elGamalService_.newEncryptedElements(emptyObject_, phis_); }).toThrow(); expect(function() { elGamalService_.newEncryptedElements(gamma_); }).toThrow(); expect(function() { elGamalService_.newEncryptedElements(gamma_, undefined); }).toThrow(); expect(function() { elGamalService_.newEncryptedElements(gamma_, null); }).toThrow(); expect(function() { elGamalService_.newEncryptedElements(gamma_, nonArray_); }).toThrow(); expect(function() { elGamalService_.newEncryptedElements(gamma_, nonMathObjectArray_); }).toThrow(); expect(function() { elGamalService_.newEncryptedElements(gamma_, phis_, null); }).toThrow(); expect(function() { elGamalService_.newEncryptedElements(gamma_, phis_, nonObject_); }).toThrow(); expect(function() { elGamalService_.newEncryptedElements(gamma_, phis_, emptyObject_); }).toThrow(); expect(function() { elGamalService_.newEncryptedElements(nonJsonString_); }).toThrow(); }); describe('Create an encrypter/decrypter pair that should ..', function() { it('throw an error when being initialized, using invalid input data', function() { expect(function() { elGamalEncrypter_.init(); }).toThrow(); expect(function() { elGamalEncrypter_.init(undefined); }).toThrow(); expect(function() { elGamalEncrypter_.init(null); }).toThrow(); expect(function() { elGamalEncrypter_.init(nonElGamalObject_); }).toThrow(); expect(function() { elGamalDecrypter_.init(); }).toThrow(); expect(function() { elGamalDecrypter_.init(undefined); }).toThrow(); expect(function() { elGamalDecrypter_.init(null); }).toThrow(); expect(function() { elGamalDecrypter_.init(nonElGamalObject_); }).toThrow(); }); it('throw an error when encrypting an array of Zp group elements, using invalid input data', function() { expect(function() { elGamalEncrypter_.encrypt(); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(undefined); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(null); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(nonArray_); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(nonMathObjectArray_); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt( elements_, {useShortExponent: nonBoolean_}); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(elements_, {preComputation: null}); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(elements_, {preComputation: nonObject_}); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt( elements_, {preComputation: emptyObject_}); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt( elements_, {preComputation: nonElGamalObject_}); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(elementsFromAnotherGroup_); }).toThrow(); }); it('throw an error when encrypting an array of Zp group element strings, using invalid input data', function() { expect(function() { elGamalEncrypter_.encrypt(); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(undefined); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(null); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(nonArray_); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(nonStringArray_); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(elements_, {preComputation: null}); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(elements_, {preComputation: nonObject_}); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt( elements_, {preComputation: emptyObject_}); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt( elements_, {preComputation: nonElGamalObject_}); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt( elements_, {useShortExponent: nonBoolean_}); }).toThrow(); expect(function() { elGamalEncrypter_.encrypt(elements_, {saveSecret: nonBoolean_}); }).toThrow(); }); it('throw an error when pre-computing an ElGamal encryption, using invalid input data', function() { expect(function() { elGamalEncrypter_.preCompute({useShortExponent: nonBoolean_}); }).toThrow(); expect(function() { elGamalEncrypter_.preCompute({saveSecret: nonBoolean_}); }).toThrow(); }); it('throw an error when decrypting an ElGamalEncryptedElements object, using invalid input data', function() { expect(function() { elGamalDecrypter_.decrypt(); }).toThrow(); expect(function() { elGamalDecrypter_.decrypt(undefined); }).toThrow(); expect(function() { elGamalDecrypter_.decrypt(null); }).toThrow(); expect(function() { elGamalDecrypter_.decrypt(nonElGamalObject_); }).toThrow(); expect(function() { elGamalDecrypter_.decrypt( encryptedElements_, {confirmMembership: null}); }).toThrow(); expect(function() { elGamalDecrypter_.decrypt( encryptedElements_, {confirmMembership: nonBoolean_}); }).toThrow(); expect(function() { elGamalDecrypter_.decrypt(encryptedElementsFromAnotherGroup_); }).toThrow(); }); }); describe('Create a PRNG decrypter that should ..', function() { it('throw an error when being initialized, using invalid input data', function() { expect(function() { elGamalPrngDecrypter_.init(); }).toThrow(); expect(function() { elGamalPrngDecrypter_.init(undefined); }).toThrow(); expect(function() { elGamalPrngDecrypter_.init(null); }).toThrow(); expect(function() { elGamalPrngDecrypter_.init(nonElGamalObject_); }).toThrow(); expect(function() { elGamalPrngDecrypter_.init(publicKey_); }).toThrow(); expect(function() { elGamalPrngDecrypter_.init(publicKey_, undefined); }).toThrow(); expect(function() { elGamalPrngDecrypter_.init(publicKey_, null); }).toThrow(); expect(function() { elGamalPrngDecrypter_.init(publicKey_, nonObject_); }).toThrow(); expect(function() { elGamalPrngDecrypter_.init(publicKey_, emptyObject_); }).toThrow(); }); it('throw an error when decrypting an ElGamalEncryptedElements object, using invalid input data', function() { expect(function() { elGamalPrngDecrypter_.decrypt(); }).toThrow(); expect(function() { elGamalPrngDecrypter_.decrypt(undefined); }).toThrow(); expect(function() { elGamalPrngDecrypter_.decrypt(null); }).toThrow(); expect(function() { elGamalPrngDecrypter_.decrypt(nonElGamalObject_); }).toThrow(); expect(function() { elGamalPrngDecrypter_.decrypt( encryptedElements_, {confirmMembership: null}); }).toThrow(); expect(function() { elGamalPrngDecrypter_.decrypt( encryptedElements_, {confirmMembership: nonBoolean_}); }).toThrow(); expect(function() { elGamalPrngDecrypter_.decrypt(encryptedElementsFromAnotherGroup_); }).toThrow(); }); }); }); });