123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- /*
- * 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
- */
- // The global namespace pollution and other glaring violations of anything
- // resembling best practices is due to the intended short-livedness of this
- // implementation.
- var MAX_EXPONENT_BYTES = 2;
- var PROGRESS_PERCENT_MIN_CHECK_INTERVAL = 10;
- var GENERATOR =
- '21303916314604998551484796420422871007468543247831789236879215369694842734099405650535148287249791144057375987697205687518340016316179892851284240278138045703633698036256611527988640313051528625117090689542380890153876064768602704006774164341226969138952495075758675629665109761968589385514561688161321002676900768077022957299407868881468752268501397255241070908793893954188678747644443826465068701078202311876709764302561277744548084228639372458598925393551439452959527949768006498598646518365505226629313181567048632516237514971091380204424481498506499338185144271546651990709723565928420753129878206710329253950578';
- var P =
- '25701322016688441576103032148674110774925156427397637132202577741938936247112125492211659378990027134829873026348759004510642939209382852797923423233606398455768339503774439196473285206499419017249519687083918862292745452369770073017370862703937184066962152692474974647384317528679859283948201449898123774491462507974828236623365121967170401847974506359775053259024902177376974036791676038887180065668218851769610708183278395407393103098286493672450097566567641277262751905925272593655979627326843104589717100845609213331825322091528671293329804211235906640910489075537455976735341285644494144220105240375300711488393';
- var Q =
- '81259987775362040571620137377019110900790585487969528507141757273696249070213';
- var ANOTHER_GENERATOR =
- '9484337033848536557358945372517536146444081505783459082983213315915020922388822299017798461933010391712259501201285084235930755858547311934865298396110947362913733900057881561201738951725697128822802249693116611294569213895789823297341865759919045291915705783128173481781221176839434866976235031358969583527093743179257827355453820268832913547364509208164670680381449515691300440305333919098105147193087681183020489724214850151272955879869448467832934822639783688344322183540621808345771717172404141548242866493539424279296365911355186761897533654055060787119955689115570505208857288933136456026541073605147828202749';
- var ANOTHER_P =
- '22115396014581083143553195792384915983375949993753365299824374182778648887213105675373952839695834312125954513956465041609718392131788741228259266178434294275575978809365653903991346366383637500069010795276889266879661859362340655085050484891149389971190945080643692669920059928787982790808824970597361825060408436004650739931286605415552480363242364319544423959620330010413847743583301091182870021747196927889763205955078275353307312408480155002017730305672359814713050632922694161739281353676187308501682728826507718002850698488786266115311952718697872338756199429262811547458969260835283688979875294699655014592833';
- var ANOTHER_Q =
- '79783631514788897688995869254536231266441581267248557197866166084121363399063';
- var _converters;
- var _keyFactory;
- var _elGamalCipherFactory;
- var _g;
- var _p;
- var _q;
- var _zpSubgroup;
- var _anotherZpSubgroup;
- var _progressPercentSum;
- var _progressPercentLatest;
- var isInitialized = false;
- function initializeTestVars() {
- if (!isInitialized) {
- cryptolib(
- 'commons.mathematical', 'commons.utils', 'homomorphic.keypair',
- 'homomorphic.cipher', function(box) {
- _converters = new box.commons.utils.Converters();
- _keyFactory = new box.homomorphic.keypair.factory.KeyFactory();
- _elGamalCipherFactory =
- new box.homomorphic.cipher.factory.ElGamalCipherFactory();
- _g = new box.forge.jsbn.BigInteger(GENERATOR);
- _p = new box.forge.jsbn.BigInteger(P);
- _q = new box.forge.jsbn.BigInteger(Q);
- _zpSubgroup = new box.commons.mathematical.ZpSubgroup(_g, _p, _q);
- var g = new box.forge.jsbn.BigInteger(ANOTHER_GENERATOR);
- var p = new box.forge.jsbn.BigInteger(ANOTHER_P);
- var q = new box.forge.jsbn.BigInteger(ANOTHER_Q);
- _anotherZpSubgroup = new box.commons.mathematical.ZpSubgroup(g, p, q);
- initializeProgressMeter();
- });
- isInitialized = true;
- }
- }
- function generateRandomInteger(min, max) {
- return Math.floor(Math.random() * (max - min + 1)) + min;
- }
- function generateRandomString(length) {
- var charset = 'abcdefghijklmnopqrstuvwxyz0123456789';
- var string = '';
- for (var i = 0; i < length; i++)
- string += charset.charAt(Math.floor(Math.random() * charset.length));
- return string;
- }
- function generateRandomExponent(zpSubgroup) {
- var exponent;
- cryptolib('commons.mathematical', function(box) {
- do {
- var randomInt = new box.forge.jsbn.BigInteger(
- box.forge.random.getBytes(MAX_EXPONENT_BYTES));
- exponent =
- new box.commons.mathematical.Exponent(zpSubgroup.getQ(), randomInt);
- } while (exponent.getValue().equals(box.forge.jsbn.BigInteger.ZERO));
- });
- return exponent;
- }
- function generateRandomGroupElement(zpSubgroup) {
- var element = zpSubgroup.getGenerator().exponentiate(
- generateRandomExponent(zpSubgroup));
- cryptolib('commons.exceptions', function(box) {
- if (!zpSubgroup.isGroupMember(element)) {
- throw new box.commons.exceptions.CryptoLibException(
- 'Randomly generated element is not a member of the required mathematical group');
- }
- });
- return element;
- }
- function generateExponentiatedElements(baseElements, exponent) {
- var exponentiatedElements = [];
- for (var i = 0; i < baseElements.length; i++) {
- var element = baseElements[i].exponentiate(exponent);
- exponentiatedElements.push(element);
- }
- return exponentiatedElements;
- }
- function generatePlaintext(numElements) {
- var plaintext = [];
- var element = generateRandomGroupElement(_zpSubgroup);
- plaintext.push(element);
- for (var i = 1; i < numElements; i++) {
- element = generateRandomGroupElement(_zpSubgroup);
- plaintext.push(element);
- }
- return plaintext;
- }
- function generateSimplePlaintext(numElements) {
- var plaintext = [];
- cryptolib('commons.exceptions', function(box) {
- if ((numElements % 2) !== 0) {
- throw new box.commons.exceptions.CryptoLibException(
- 'Plaintext must have even number of elements for simple plaintext equality proof generation.');
- }
- // Note that all elements of a simple plaintext must have the same value.
- var element = generateRandomGroupElement(_zpSubgroup);
- for (var i = 0; i < numElements; i++) {
- plaintext.push(element);
- }
- });
- return plaintext;
- }
- function generateNonSimplePlaintext(numElements) {
- var plaintext = [];
- var element = generateRandomGroupElement(_zpSubgroup);
- plaintext.push(element);
- for (var i = 1; i < numElements; i++) {
- do {
- element = generateRandomGroupElement(_zpSubgroup);
- } while (
- element.getElementValue().equals(plaintext[i - 1].getElementValue()));
- plaintext.push(element);
- }
- return plaintext;
- }
- function generateElGamalKeyPair(numElements) {
- var elements = [];
- var exponents = [];
- var exponent = generateRandomExponent(_zpSubgroup);
- var element = _zpSubgroup.getGenerator().exponentiate(exponent);
- exponents.push(exponent);
- elements.push(element);
- for (var i = 1; i < numElements; i++) {
- exponent = generateRandomExponent(_zpSubgroup);
- element = _zpSubgroup.getGenerator().exponentiate(exponent);
- exponents.push(exponent);
- elements.push(element);
- }
- var elGamalPublicKey = _keyFactory.createPublicKey(elements, _zpSubgroup);
- var elGamalPrivateKey = _keyFactory.createPrivateKey(exponents, _zpSubgroup);
- return _keyFactory.createKeyPair(elGamalPublicKey, elGamalPrivateKey);
- }
- function generateCiphertext(publicKey, plaintext) {
- var encrypter = _elGamalCipherFactory.createEncrypter(publicKey);
- return encrypter.encryptGroupElements(plaintext);
- }
- function generateExponentCiphertext(
- plaintext, primaryWitness, secondaryWitness) {
- var ciphertext;
- cryptolib('commons.exceptions', 'homomorphic.cipher', function(box) {
- var plaintextLength = plaintext.length;
- if ((plaintextLength % 2) === 0) {
- throw new box.commons.exceptions.CryptoLibException(
- 'Plaintext must have odd number of elements for plaintext exponent equality proof generation.');
- }
- var numCiphertextElements = ((plaintextLength - 1) / 2) + 1;
- var exponents = [];
- exponents.push(primaryWitness);
- exponents.push(secondaryWitness);
- var gamma = plaintext[0].exponentiate(exponents[0]);
- var phis = [];
- for (var i = 0; i < (numCiphertextElements - 1); i++) {
- var phi = plaintext[i + 1].exponentiate(exponents[0]);
- phi = phi.multiply(
- plaintext[i + numCiphertextElements].exponentiate(exponents[1]));
- phis.push(phi);
- }
- ciphertext =
- new box.homomorphic.cipher.ElGamalEncrypterValues(null, gamma, phis);
- });
- return ciphertext;
- }
- function getSubElGamalPublicKey(publicKey, fromIndex, toIndex) {
- var elements = publicKey.getGroupElementsArray();
- var subElements = [];
- for (var i = fromIndex; i < toIndex; i++) {
- subElements.push(elements[i]);
- }
- return _keyFactory.createPublicKey(subElements, _zpSubgroup);
- }
- function getSubCiphertext(encrypterValues, fromIndex, toIndex) {
- var subCiphertext;
- cryptolib('homomorphic.cipher', function(box) {
- var exponent = encrypterValues.getR();
- var gamma = encrypterValues.getGamma();
- var phis = encrypterValues.getPhis();
- var subPhis = [];
- for (var i = fromIndex; i < toIndex; i++) {
- subPhis.push(phis[i]);
- }
- subCiphertext = new box.homomorphic.cipher.ElGamalEncrypterValues(
- exponent, gamma, subPhis);
- });
- return subCiphertext;
- }
- function initializeProgressMeter() {
- _progressPercentSum = 0;
- _progressPercentLatest = 0;
- }
- function progressCallback(progressPercent) {
- _progressPercentSum += progressPercent;
- _progressPercentLatest = progressPercent;
- };
- function getProgressPercentSum(numChecks, minCheckInterval) {
- var percent = 0;
- var lastPercent = 0;
- var percentChange = 0;
- var incrementPercentSum = false;
- var percentSum = 0;
- for (var i = 0; i < numChecks; i++) {
- percent = Math.floor(((i + 1) / numChecks) * 100);
- percent = Math.min(percent, 100);
- percentChange = percent - lastPercent;
- if (percentChange > 0) {
- incrementPercentSum =
- (percentChange >= minCheckInterval) || (percent === 100);
- if (incrementPercentSum) {
- lastPercent = percent;
- percentSum += percent;
- }
- }
- }
- return percentSum;
- }
|