1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620 |
- /*
- * 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
- */
- cryptolib.modules = cryptolib.modules || {};
- cryptolib.modules.proofs = cryptolib.modules.proofs || {};
- /**
- * Defines Zero-Knowledge Proofs (ZKPs).
- */
- cryptolib.modules.proofs.implementation = function(box) {
- 'use strict';
- box.proofs = box.proofs || {};
- var exceptions, mathematical, utils, converters, secureRandomFactory,
- messageDigestFactory;
- var f = function(box) {
- exceptions = box.commons.exceptions;
- mathematical = box.commons.mathematical;
- utils = box.commons.utils;
- converters = new box.commons.utils.Converters();
- secureRandomFactory =
- new box.primitives.securerandom.factory.SecureRandomFactory();
- messageDigestFactory =
- new box.primitives.messagedigest.factory.MessageDigestFactory();
- };
- f.policies = {
- primitives: {
- messagedigest: {
- algorithm: box.policies.proofs.messagedigest.algorithm,
- provider: box.policies.proofs.messagedigest.provider
- },
- secureRandom: {provider: box.policies.proofs.secureRandom.provider}
- }
- };
- cryptolib(
- 'commons.exceptions', 'commons.mathematical', 'primitives.messagedigest',
- 'commons.utils', 'primitives.securerandom', f);
- /**
- * Schnorr proof generator.
- */
- box.proofs.SchnorrProofGenerator = function(voterID, electionID, group) {
- checkNotEmpty('voter ID', voterID);
- checkNotEmpty('election ID', electionID);
- checkDefined('group', group);
- var computationRules = [[[1, 1]]];
- var _voterID = voterID;
- var _electionID = electionID;
- var _progressMeter;
- var _numOutputs = 1;
- var buildListOfBaseElements = function() {
- var baseElements = [];
- baseElements.push(group.getGenerator());
- return baseElements;
- };
- var phiFunctionSchnorr = new box.proofs.PhiFunction(
- group, 1, _numOutputs, buildListOfBaseElements(), computationRules);
- var _prover = new box.proofs.Prover(group, phiFunctionSchnorr);
- this._buildListPublicValues = function(exponentiatedElement) {
- var publicList = [];
- publicList.push(exponentiatedElement);
- return publicList;
- };
- this._getProver = function() {
- return _prover;
- };
- this._buildListExponents = function(witness) {
- var exponentList = [];
- exponentList.push(witness);
- return exponentList;
- };
- this._buildDataString = function() {
- return 'SchnorrProof:VoterID=' + _voterID +
- 'ElectionEventID=' + _electionID;
- };
- this._getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _numOutputs, progressCallback, progressPercentMinCheckInterval);
- return this;
- };
- };
- box.proofs.SchnorrProofGenerator.prototype = {
- preCompute: function() {
- return this._getProver().preCompute(1, this._getProgressMeter());
- },
- generate: function(exponentiatedElement, witness, preComputedValues) {
- checkDefined('exponentiated element', exponentiatedElement);
- checkDefined('witness', witness);
- if (!preComputedValues) {
- preComputedValues = this.preCompute();
- }
- return this._getProver().prove(
- this._buildListPublicValues(exponentiatedElement),
- this._buildListExponents(witness), this._buildDataString(),
- preComputedValues);
- }
- };
- /**
- * Exponentiation proof generator.
- */
- box.proofs.ExponentiationProofGenerator = function(baseElements, group) {
- checkDefined('base elements', baseElements);
- checkDefined('group', group);
- var buildComputationRules = function(k) {
- var rules = [];
- for (var i = 0; i < k; i++) {
- rules[i] = [];
- rules[i][0] = [];
- rules[i][0].push(i + 1);
- rules[i][0].push(1);
- }
- return rules;
- };
- var _numOutputs = baseElements.length;
- var phiFunctionExponentiation = new box.proofs.PhiFunction(
- group, 1, _numOutputs, baseElements,
- buildComputationRules(_numOutputs));
- var _prover = new box.proofs.Prover(group, phiFunctionExponentiation);
- var _progressMeter;
- this._getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _numOutputs, progressCallback, progressPercentMinCheckInterval);
- return this;
- };
- this.check = function(exponentiatedElements) {
- if (exponentiatedElements.length !== _numOutputs) {
- throw new exceptions.CryptoLibException(
- 'The number of exponentiated elements must be equal to the number of base elements');
- }
- };
- this._getProver = function() {
- return _prover;
- };
- };
- box.proofs.ExponentiationProofGenerator.prototype = {
- preCompute: function() {
- var EXPONENT_QUANTITY = 1;
- return this._getProver().preCompute(
- EXPONENT_QUANTITY, this._getProgressMeter());
- },
- generate: function(exponentiatedElements, exponent, preComputedValues) {
- checkDefined('exponentiatedElements', exponentiatedElements);
- checkDefined('exponent', exponent);
- this.check(exponentiatedElements);
- var exponents = [];
- exponents.push(exponent);
- if (!preComputedValues) {
- preComputedValues = this.preCompute();
- }
- return this._getProver().prove(
- exponentiatedElements, exponents,
- box.EXPONENTIATION_PROOF_AUXILIARY_DATA, preComputedValues);
- }
- };
- /**
- * Plaintext proof generator.
- */
- box.proofs.PlaintextProofGenerator = function(publicKey, group) {
- checkDefined('public key', publicKey);
- checkDefined('group', group);
- var buildListOfBaseElements = function() {
- var list = [];
- list.push(group.getGenerator());
- list.addAll(publicKey.getGroupElementsArray());
- return list;
- };
- var buildComputationRules = function(k) {
- var rules = [];
- for (var i = 0; i < (k + 1); i++) {
- rules[i] = [];
- rules[i][0] = [];
- rules[i][0].push(i + 1);
- rules[i][0].push(1);
- }
- return rules;
- };
- var _publicKeyLength = publicKey.getGroupElementsArray().length;
- var numOutputs = _publicKeyLength + 1;
- var phiFunctionPlaintext = new box.proofs.PhiFunction(
- group, 1, numOutputs, buildListOfBaseElements(),
- buildComputationRules(_publicKeyLength));
- var _prover = new box.proofs.Prover(group, phiFunctionPlaintext);
- var _progressMeter;
- this._buildListPublicValues = function(ciphertext, plaintext) {
- var dividedCiphertext =
- mathematical.groupUtils.divide(ciphertext.getPhis(), plaintext);
- var publicValues = [];
- publicValues.push(ciphertext.getGamma());
- publicValues.addAll(dividedCiphertext);
- return publicValues;
- };
- this._getPublicKeyLength = function() {
- return _publicKeyLength;
- };
- this._getProver = function() {
- return _prover;
- };
- this._getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _publicKeyLength + 1, progressCallback,
- progressPercentMinCheckInterval);
- return this;
- };
- };
- box.proofs.PlaintextProofGenerator.prototype = {
- preCompute: function() {
- return this._getProver().preCompute(1, this._getProgressMeter());
- },
- generate: function(ciphertext, plaintext, witness, preComputedValues) {
- checkDefined('ciphertext', ciphertext);
- checkDefined('plaintext', plaintext);
- checkDefined('witness', witness);
- var publicKeyLength = this._getPublicKeyLength();
- var numPhis = ciphertext.getPhis().length;
- if (publicKeyLength !== numPhis) {
- throw new exceptions.CryptoLibException(
- 'The length of the ciphertext must be equal to the length of the public key + 1.');
- }
- if (publicKeyLength !== plaintext.length) {
- throw new exceptions.CryptoLibException(
- 'The public key and the plaintext must have the same number of elements');
- }
- if (!preComputedValues) {
- preComputedValues = this.preCompute();
- }
- var exponents = [];
- exponents.push(witness);
- return this._getProver().prove(
- this._buildListPublicValues(ciphertext, plaintext), exponents,
- box.PLAINTEXT_PROOF_AUXILIARY_DATA, preComputedValues);
- }
- };
- /**
- * Simple plaintext equality proof generator.
- */
- box.proofs.SimplePlaintextEqualityProofGenerator = function(
- primaryPublicKey, secondaryPublicKey, group) {
- checkDefined('primary public key', primaryPublicKey);
- checkDefined('secondary public key', secondaryPublicKey);
- checkDefined('group', group);
- var _primaryPublicKey = primaryPublicKey;
- var _secondaryPublicKey = secondaryPublicKey;
- var _group = group;
- var buildComputationRules = function(k) {
- var rules = [];
- var firstDimensionLength = k + 1;
- rules[0] = [];
- rules[0][0] = [];
- rules[0][0].push(1);
- rules[0][0].push(1);
- for (var i = 1; i < firstDimensionLength; i++) {
- rules[i] = [];
- rules[i][0] = [];
- rules[i][1] = [];
- rules[i][0].push(i + 1);
- rules[i][0].push(1);
- rules[i][1].push(i + 1 + k);
- rules[i][1].push(1);
- }
- return rules;
- };
- var buildSecondaryInvertedPublicKey = function() {
- var listInvertedElements = [];
- var keys = _secondaryPublicKey.getGroupElementsArray();
- for (var i = 0; i < keys.length; i++) {
- listInvertedElements.push(keys[i].invert());
- }
- return listInvertedElements;
- };
- var buildListOfBaseElements = function() {
- var invertedSecondaryKeyValues = buildSecondaryInvertedPublicKey();
- var baseElements = [];
- baseElements.push(group.getGenerator());
- baseElements.addAll(_primaryPublicKey.getGroupElementsArray());
- baseElements.addAll(invertedSecondaryKeyValues);
- return baseElements;
- };
- var primaryPublicKeyLength =
- primaryPublicKey.getGroupElementsArray().length;
- var secondaryPublicKeyLength =
- secondaryPublicKey.getGroupElementsArray().length;
- if (primaryPublicKeyLength !== secondaryPublicKeyLength) {
- throw new exceptions.CryptoLibException(
- 'The number of elements in the primary and secondary public keys must be equal');
- }
- var _progressMeter;
- var _numKeyElements = primaryPublicKey.getGroupElementsArray().length;
- var numOutputs = _numKeyElements + 1;
- var rules = buildComputationRules(_numKeyElements);
- var phiFunctionSimplePlaintextEquality = new box.proofs.PhiFunction(
- group, 1, numOutputs, buildListOfBaseElements(), rules);
- var _prover =
- new box.proofs.Prover(_group, phiFunctionSimplePlaintextEquality);
- this._buildListExponents = function(witness) {
- var exponentList = [];
- exponentList.push(witness);
- return exponentList;
- };
- this._buildInputList = function(primaryCiphertext, secondaryCiphertext) {
- var dividedSubCiphertext = mathematical.groupUtils.divide(
- primaryCiphertext.getPhis(), secondaryCiphertext.getPhis());
- var generatedList = [];
- generatedList.push(secondaryCiphertext.getGamma());
- generatedList.addAll(dividedSubCiphertext);
- return generatedList;
- };
- this._getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _numKeyElements * 2 + 1, progressCallback,
- progressPercentMinCheckInterval);
- return this;
- };
- this._getProver = function() {
- return _prover;
- };
- this._check = function(primaryCiphertextLength) {
- if (primaryCiphertextLength !== (primaryPublicKeyLength + 1)) {
- throw new exceptions.CryptoLibException(
- 'The number of elements in the ciphertext must be equal to the number in the public key + 1');
- }
- };
- };
- box.proofs.SimplePlaintextEqualityProofGenerator.prototype = {
- preCompute: function() {
- return this._getProver().preCompute(1, this._getProgressMeter());
- },
- generate: function(
- primaryCiphertext, secondaryCiphertext, witness, preComputedValues) {
- checkDefined('primary ciphertext', primaryCiphertext);
- checkDefined('secondary ciphertext', secondaryCiphertext);
- checkDefined('witness', witness);
- var primaryCiphertextLength = primaryCiphertext.getPhis().length + 1;
- var secondaryCiphertextLength = secondaryCiphertext.getPhis().length + 1;
- if (primaryCiphertextLength !== secondaryCiphertextLength) {
- throw new exceptions.CryptoLibException(
- 'The number of elements in the primary and secondary ciphertext must be equal');
- }
- this._check(primaryCiphertextLength);
- if (!preComputedValues) {
- preComputedValues = this.preCompute();
- }
- return this._getProver().prove(
- this._buildInputList(primaryCiphertext, secondaryCiphertext),
- this._buildListExponents(witness),
- box.SIMPLE_PLAINTEXT_EQUALITY_PROOF_AUXILIARY_DATA,
- preComputedValues);
- }
- };
- /**
- * Plaintext equality proof generator.
- */
- box.proofs.PlaintextEqualityProofGenerator = function(
- primaryPublicKey, secondaryPublicKey, group) {
- checkDefined('primary public key', primaryPublicKey);
- checkDefined('secondary public key', secondaryPublicKey);
- checkDefined('group', group);
- var numPrimaryPublicKeyElements =
- primaryPublicKey.getGroupElementsArray().length;
- var numSecondaryPublicKeyElements =
- secondaryPublicKey.getGroupElementsArray().length;
- if (numPrimaryPublicKeyElements !== numSecondaryPublicKeyElements) {
- throw new exceptions.CryptoLibException(
- 'The primary and secondary public keys contain different numbers of elements: ' +
- numPrimaryPublicKeyElements + ', ' + numSecondaryPublicKeyElements);
- }
- var _primaryPublicKey = primaryPublicKey;
- var _secondaryPublicKey = secondaryPublicKey;
- var _group = group;
- var _progressMeter;
- this._buildListExponents = function(primaryWitness, secondaryWitness) {
- var exponentList = [];
- exponentList.push(primaryWitness);
- exponentList.push(secondaryWitness);
- return exponentList;
- };
- this._buildInputList = function(primaryCiphertext, secondaryCiphertext) {
- var dividedSubCiphertext = mathematical.groupUtils.divide(
- primaryCiphertext.getPhis(), secondaryCiphertext.getPhis());
- var generatedList = [];
- generatedList.push(primaryCiphertext.getGamma());
- generatedList.push(secondaryCiphertext.getGamma());
- generatedList.addAll(dividedSubCiphertext);
- return generatedList;
- };
- function buildComputationRules(k) {
- var firstDimensionLength = k + 2;
- var rules = [];
- rules[0] = [];
- rules[0][0] = [];
- rules[0][0].push(1);
- rules[0][0].push(1);
- rules[1] = [];
- rules[1][0] = [];
- rules[1][0].push(1);
- rules[1][0].push(2);
- for (var i = 2; i < firstDimensionLength; i++) {
- rules[i] = [];
- rules[i][0] = [];
- rules[i][0].push(i);
- rules[i][0].push(1);
- rules[i][1] = [];
- rules[i][1].push(i + k);
- rules[i][1].push(2);
- }
- return rules;
- }
- function buildListOfBaseElements() {
- var invertedSecondaryKeyValues = buildSecondaryInvertedPublicKey();
- var baseElements = [];
- baseElements.push(group.getGenerator());
- baseElements.addAll(_primaryPublicKey.getGroupElementsArray());
- baseElements.addAll(invertedSecondaryKeyValues);
- return baseElements;
- }
- function buildSecondaryInvertedPublicKey() {
- var listInvertedElements = [];
- var keys = _secondaryPublicKey.getGroupElementsArray();
- for (var i = 0; i < keys.length; i++) {
- listInvertedElements.push(keys[i].invert());
- }
- return listInvertedElements;
- }
- var numKeyElements = primaryPublicKey.getGroupElementsArray().length;
- var _numOutputs = numKeyElements + 2;
- var rules = buildComputationRules(numKeyElements);
- var phiFunctionPlaintextEquality = new box.proofs.PhiFunction(
- group, 2, _numOutputs, buildListOfBaseElements(), rules);
- var _prover = new box.proofs.Prover(group, phiFunctionPlaintextEquality);
- this.getPrimaryPublicKey = function() {
- return _primaryPublicKey;
- };
- this.getSecondaryPublicKey = function() {
- return _secondaryPublicKey;
- };
- this.getGroup = function() {
- return _group;
- };
- this._getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- numKeyElements * 2 + 2, progressCallback,
- progressPercentMinCheckInterval);
- return this;
- };
- this._getProver = function() {
- return _prover;
- };
- this.check = function(numPrimaryCiphertextElements) {
- if (numPrimaryCiphertextElements !== (numPrimaryPublicKeyElements + 1)) {
- throw new exceptions.CryptoLibException(
- 'The number of ciphertext elements is not equal to the number public key elements plus one.');
- }
- };
- };
- box.proofs.PlaintextEqualityProofGenerator.prototype = {
- preCompute: function() {
- return this._getProver().preCompute(2, this._getProgressMeter());
- },
- generate: function(
- primaryCiphertext, primaryWitness, secondaryCiphertext,
- secondaryWitness, preComputedValues) {
- checkDefined('primary ciphertext', primaryCiphertext);
- checkDefined('primary witness', primaryWitness);
- checkDefined('secondary ciphertext', secondaryCiphertext);
- checkDefined('secondary witness', secondaryWitness);
- var numPrimaryCiphertextElements = primaryCiphertext.getPhis().length + 1;
- var numSecondaryCiphertextElements =
- secondaryCiphertext.getPhis().length + 1;
- if (numPrimaryCiphertextElements !== numSecondaryCiphertextElements) {
- throw new exceptions.CryptoLibException(
- 'The primary and secondary ciphertexts contain different numbers of elements: ' +
- numPrimaryCiphertextElements + ', ' +
- numSecondaryCiphertextElements);
- }
- this.check(numPrimaryCiphertextElements);
- if (!preComputedValues) {
- preComputedValues = this.preCompute();
- }
- return this._getProver().prove(
- this._buildInputList(primaryCiphertext, secondaryCiphertext),
- this._buildListExponents(primaryWitness, secondaryWitness),
- box.PLAINTEXT_EQUALITY_PROOF_AUXILIARY_DATA, preComputedValues);
- }
- };
- /**
- * Plaintext exponent equality proof generator.
- */
- box.proofs.PlaintextExponentEqualityProofGenerator = function(
- baseElements, group) {
- var buildComputationRules = function(k) {
- var rules = [];
- var firstDimensionLength = k + 1;
- rules[0] = [];
- rules[0][0] = [];
- rules[0][0].push(1);
- rules[0][0].push(1);
- for (var i = 1; i < firstDimensionLength; i++) {
- rules[i] = [];
- rules[i][0] = [];
- rules[i][1] = [];
- rules[i][0].push(i + 1);
- rules[i][0].push(1);
- rules[i][1].push(i + 1 + k);
- rules[i][1].push(2);
- }
- return rules;
- };
- checkDefined('base elements', baseElements);
- checkDefined('group', group);
- var _numBaseElements = baseElements.length;
- var _progressMeter;
- var k = (_numBaseElements - 1) / 2;
- var numOutputs = k + 1;
- var phiFunctionPlaintextExponentEquality = new box.proofs.PhiFunction(
- group, 2, numOutputs, baseElements, buildComputationRules(k));
- var _prover =
- new box.proofs.Prover(group, phiFunctionPlaintextExponentEquality);
- this._buildListExponents = function(witness1, witness2) {
- var exponentList = [];
- exponentList.push(witness1);
- exponentList.push(witness2);
- return exponentList;
- };
- this._buildListPublicValues = function(ciphertext) {
- var list = [];
- list.push(ciphertext.getGamma());
- list.addAll(ciphertext.getPhis());
- return list;
- };
- this._getProver = function() {
- return _prover;
- };
- this._getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _numBaseElements, progressCallback, progressPercentMinCheckInterval);
- return this;
- };
- this._checkLengthOf = function(ciphertext) {
- var k = ciphertext.getPhis().length;
- var expectedNumBaseElements = (2 * k) + 1;
- if (_numBaseElements !== expectedNumBaseElements) {
- throw new exceptions.CryptoLibException(
- 'The lengths of the ciphertext and the base elements do not have the expected relationship.');
- }
- };
- };
- box.proofs.PlaintextExponentEqualityProofGenerator.prototype = {
- preCompute: function() {
- return this._getProver().preCompute(2, this._getProgressMeter());
- },
- generate: function(ciphertext, witness1, witness2, preComputedValues) {
- checkDefined('ciphertext', ciphertext);
- checkDefined('witness1', witness1);
- checkDefined('witness2', witness2);
- this._checkLengthOf(ciphertext);
- if (!preComputedValues) {
- preComputedValues = this.preCompute();
- }
- return this._getProver().prove(
- this._buildListPublicValues(ciphertext),
- this._buildListExponents(witness1, witness2),
- box.PLAINTEXT_EXPONENT_EQUALITY_PROOF_AUXILIARY_DATA,
- preComputedValues);
- }
- };
- /**
- * OR-proof generator.
- */
- box.proofs.ORProofGenerator = function(publicKey, numElements, group) {
- checkPublicKey(publicKey);
- checkNumElements(numElements);
- checkGroup(group);
- var _publicKey = publicKey;
- var _numElements = numElements;
- var _group = group;
- var _numOutputs = _numElements * 2;
- var _progressMeter;
- function checkPublicKey(publicKey) {
- checkDefined('public key', publicKey);
- checkNotNull('public key', publicKey);
- var publicKeyLength = publicKey.getGroupElementsArray().length;
- if (publicKeyLength !== 1) {
- throw new exceptions.CryptoLibException(
- 'Expected public key length: 1 ; Found: ' + publicKeyLength);
- }
- }
- function checkNumElements(numElements) {
- checkDefined('numElements', numElements);
- checkNotNull('numElements', numElements);
- if (numElements < 2) {
- throw new exceptions.CryptoLibException(
- 'Expected number of elements to be greater than 1 ; Found: ' +
- numElements);
- }
- }
- function checkGroup(group) {
- checkDefined('group', group);
- checkNotNull('group', group);
- }
- function buildBaseElements() {
- var baseElements = [];
- baseElements.push(_group.getGenerator());
- baseElements.push(_publicKey.getGroupElementsArray()[0]);
- return baseElements;
- }
- function buildComputationRules(numOutputs) {
- var rules = [];
- var index1;
- var index2 = 0;
- for (var i = 0; i < numOutputs; i++) {
- index1 = 1 + (i % 2);
- if (i % 2 === 0) {
- index2++;
- }
- rules[i] = [];
- rules[i][0] = [];
- rules[i][0].push(index1);
- rules[i][0].push(index2);
- }
- return rules;
- }
- var phiFunctionOR = new box.proofs.PhiFunction(
- group, _numElements, _numOutputs, buildBaseElements(),
- buildComputationRules(_numOutputs));
- var _prover = new box.proofs.Prover(_group, phiFunctionOR);
- this.getNumElements = function() {
- return _numElements;
- };
- this.getProver = function() {
- return _prover;
- };
- this.buildPublicValues = function(ciphertext) {
- var publicValues = [];
- publicValues.push(ciphertext.getGamma());
- publicValues.push(ciphertext.getPhis()[0]);
- return publicValues;
- };
- this.getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _numOutputs, progressCallback, progressPercentMinCheckInterval);
- return this;
- };
- };
- box.proofs.ORProofGenerator.prototype = {
- preCompute: function() {
- return this.getProver().preCompute(
- this.getNumElements(), this.getProgressMeter());
- },
- generate: function(
- ciphertext, witness, elements, index, data, preComputedValues) {
- checkCiphertext(ciphertext);
- checkWitness(witness);
- checkElements(elements, this.getNumElements());
- checkIndex(index, this.getNumElements());
- checkDefined('data', data);
- function checkCiphertext(ciphertext) {
- checkDefined('ciphertext', ciphertext);
- checkNotNull('ciphertext', ciphertext);
- var ciphertextLength = ciphertext.getPhis().length + 1;
- if (ciphertextLength !== 2) {
- throw new exceptions.CryptoLibException(
- 'Expected ciphertext length: 2 ; Found: ' + ciphertextLength);
- }
- }
- function checkWitness(witness) {
- checkDefined('witness', witness);
- checkNotNull('witness', witness);
- }
- function checkElements(elements, numElementsExpected) {
- checkDefined('elements', elements);
- checkNotNull('elements', elements);
- var numElementsFound = elements.length;
- if (numElementsFound !== numElementsExpected) {
- throw new exceptions.CryptoLibException(
- 'Expected number of elements: ' + numElementsExpected +
- ' ; Found: ' + numElementsFound);
- }
- }
- function checkIndex(index, numElements) {
- checkDefined('index', index);
- checkNotNull('index', index);
- if (index < 0) {
- throw new exceptions.CryptoLibException(
- 'Expected index of encrypted element to be positive ; Found: ' +
- index);
- }
- if (index >= numElements) {
- throw new exceptions.CryptoLibException(
- 'Expected index of encrypted element to be less than number of elements: ' +
- numElements + ' ; Found: ' + index);
- }
- }
- var publicValues = this.buildPublicValues(ciphertext);
- var privateValues = [];
- privateValues.push(witness);
- if (data === null) {
- data = '';
- }
- if (!preComputedValues) {
- preComputedValues = this.preCompute();
- }
- return this.getProver().prove(
- publicValues, privateValues, data, preComputedValues, elements,
- index);
- }
- };
- /**
- * Schnorr proof verifier.
- */
- box.proofs.SchnorrProofVerifier = function(
- exponentiatedElement, voterID, electionID, proof, group) {
- checkDefined('exponentiated element', exponentiatedElement);
- checkNotEmpty('voter ID', voterID);
- checkNotEmpty('election ID', electionID);
- checkDefined('proof', proof);
- checkDefined('group', group);
- var _exponentiatedElement = exponentiatedElement;
- var _voterID = voterID;
- var _electionID = electionID;
- var _proof = proof;
- var _group = group;
- var _progressMeter;
- this._buildListOfBaseElements = function() {
- var baseElements = [];
- baseElements.push(_group.getGenerator());
- return baseElements;
- };
- this._buildExponentiatedElementsList = function() {
- var exponentiatedElements = [];
- exponentiatedElements.push(_exponentiatedElement);
- return exponentiatedElements;
- };
- this._buildDataString = function() {
- return 'SchnorrProof:VoterID=' + _voterID +
- 'ElectionEventID=' + _electionID;
- };
- var computationRules = [[[1, 1]]];
- var _numOutputs = 1;
- var phiFunction = new box.proofs.PhiFunction(
- _group, 1, _numOutputs, this._buildListOfBaseElements(),
- computationRules);
- var _verifier = new box.proofs.Verifier(_group, phiFunction);
- this._getProof = function() {
- return _proof;
- };
- this._getVerifier = function() {
- return _verifier;
- };
- this._getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _numOutputs, progressCallback, progressPercentMinCheckInterval);
- return this;
- };
- };
- box.proofs.SchnorrProofVerifier.prototype = {
- verify: function() {
- return this._getVerifier().verify(
- this._buildExponentiatedElementsList(), this._getProof(),
- this._buildDataString(), this._getProgressMeter());
- }
- };
- /**
- * Exponentiation proof verifier.
- */
- box.proofs.ExponentiationProofVerifier = function(
- exponentiatedElements, baseElements, proof, group) {
- checkDefined('exponentiated elements', exponentiatedElements);
- checkDefined('base elements', baseElements);
- checkDefined('proof', proof);
- checkDefined('group', group);
- var _exponentiatedElements = exponentiatedElements;
- var _proof = proof;
- var _progressMeter;
- this._buildComputationRules = function(k) {
- var rules = [];
- for (var i = 0; i < k; i++) {
- rules[i] = [];
- rules[i][0] = [];
- rules[i][0].push(i + 1);
- rules[i][0].push(1);
- }
- return rules;
- };
- var _numOutputs = exponentiatedElements.length;
- var phiFunctionExponentiation = new box.proofs.PhiFunction(
- group, 1, _numOutputs, baseElements,
- this._buildComputationRules(_numOutputs));
- var _verifier = new box.proofs.Verifier(group, phiFunctionExponentiation);
- this._getProof = function() {
- return _proof;
- };
- this.getExponentiatedElements = function() {
- return _exponentiatedElements;
- };
- this._getVerifier = function() {
- return _verifier;
- };
- this._getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _numOutputs, progressCallback, progressPercentMinCheckInterval);
- return this;
- };
- };
- box.proofs.ExponentiationProofVerifier.prototype = {
- verify: function() {
- return this._getVerifier().verify(
- this.getExponentiatedElements(), this._getProof(),
- box.EXPONENTIATION_PROOF_AUXILIARY_DATA, this._getProgressMeter());
- }
- };
- /**
- * Plaintext proof verifier.
- */
- box.proofs.PlaintextProofVerifier = function(publicKey, group) {
- checkDefined('public key', publicKey);
- checkDefined('group', group);
- var _publicKey = publicKey;
- var _group = group;
- var _progressMeter;
- this._buildListOfBaseElements = function() {
- var list = [];
- list.push(_group.getGenerator());
- list.addAll(_publicKey.getGroupElementsArray());
- return list;
- };
- this._buildListPublicValues = function(ciphertext, plaintext) {
- var dividedCiphertext =
- mathematical.groupUtils.divide(ciphertext.getPhis(), plaintext);
- var publicValues = [];
- publicValues.push(ciphertext.getGamma());
- publicValues.addAll(dividedCiphertext);
- return publicValues;
- };
- this._buildComputationRules = function(k) {
- var rules = [];
- for (var i = 0; i < (k + 1); i++) {
- rules[i] = [];
- rules[i][0] = [];
- rules[i][0].push(i + 1);
- rules[i][0].push(1);
- }
- return rules;
- };
- var _publicKeyLength = _publicKey.getGroupElementsArray().length;
- var numOutputs = _publicKeyLength + 1;
- var phiFunctionPlaintext = new box.proofs.PhiFunction(
- _group, 1, numOutputs, this._buildListOfBaseElements(),
- this._buildComputationRules(_publicKeyLength));
- var _verifier = new box.proofs.Verifier(_group, phiFunctionPlaintext);
- this.getPublicKey = function() {
- return _publicKey;
- };
- this.getGroup = function() {
- return _group;
- };
- this._getVerifier = function() {
- return _verifier;
- };
- this._getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _publicKeyLength + 1, progressCallback,
- progressPercentMinCheckInterval);
- return this;
- };
- };
- box.proofs.PlaintextProofVerifier.prototype = {
- verify: function(ciphertext, plaintext, proof) {
- checkDefined('ciphertext', ciphertext);
- checkDefined('plaintext', plaintext);
- checkDefined('proof', proof);
- return this._getVerifier().verify(
- this._buildListPublicValues(ciphertext, plaintext), proof,
- box.PLAINTEXT_PROOF_AUXILIARY_DATA, this._getProgressMeter());
- }
- };
- /**
- * Simple plaintext equality proof verifier.
- */
- box.proofs.SimplePlaintextEqualityProofVerifier = function(
- primaryCiphertext, primaryPublicKey, secondaryCiphertext,
- secondaryPublicKey, proof, group) {
- checkDefined('primary ciphertext', primaryCiphertext);
- checkDefined('primary public key', primaryPublicKey);
- checkDefined('secondary ciphertext', secondaryCiphertext);
- checkDefined('secondary public key', secondaryPublicKey);
- checkDefined('proof', proof);
- checkDefined('group', group);
- var numPrimaryCiphertextElements = primaryCiphertext.getPhis().length + 1;
- var numPrimaryPublicKeyElements =
- primaryPublicKey.getGroupElementsArray().length;
- var numSecondaryCiphertextElements =
- secondaryCiphertext.getPhis().length + 1;
- var numSecondaryPublicKeyElements =
- secondaryPublicKey.getGroupElementsArray().length;
- if (numPrimaryCiphertextElements !== numSecondaryCiphertextElements) {
- throw new exceptions.CryptoLibException(
- 'The primary and secondary ciphertexts contain different numbers of elements: ' +
- numPrimaryCiphertextElements + ', ' + numSecondaryCiphertextElements);
- }
- if (numPrimaryPublicKeyElements !== numSecondaryPublicKeyElements) {
- throw new exceptions.CryptoLibException(
- 'The primary and secondary public keys contain different numbers of elements: ' +
- numPrimaryPublicKeyElements + ', ' + numSecondaryPublicKeyElements);
- }
- if (numPrimaryCiphertextElements !== (numPrimaryPublicKeyElements + 1)) {
- throw new exceptions.CryptoLibException(
- 'The number of ciphertext elements is not equal to the number public key elements plus one.');
- }
- var _primaryCiphertext = primaryCiphertext;
- var _primaryPublicKey = primaryPublicKey;
- var _secondaryCiphertext = secondaryCiphertext;
- var _secondaryPublicKey = secondaryPublicKey;
- var _proof = proof;
- var _progressMeter;
- function buildComputationRules(k) {
- var rules = [];
- var firstDimensionLength = k + 1;
- rules[0] = [];
- rules[0][0] = [];
- rules[0][0].push(1);
- rules[0][0].push(1);
- for (var i = 1; i < firstDimensionLength; i++) {
- rules[i] = [];
- rules[i][0] = [];
- rules[i][1] = [];
- rules[i][0].push(i + 1);
- rules[i][0].push(1);
- rules[i][1].push(i + 1 + k);
- rules[i][1].push(1);
- }
- return rules;
- }
- function buildListOfBaseElements() {
- var invertedSecondaryKeyValues = buildSecondaryInvertedPublicKey();
- var baseElements = [];
- baseElements.push(group.getGenerator());
- baseElements.addAll(_primaryPublicKey.getGroupElementsArray());
- baseElements.addAll(invertedSecondaryKeyValues);
- return baseElements;
- }
- function buildSecondaryInvertedPublicKey() {
- var listInvertedElements = [];
- var keys = _secondaryPublicKey.getGroupElementsArray();
- for (var i = 0; i < keys.length; i++) {
- listInvertedElements.push(keys[i].invert());
- }
- return listInvertedElements;
- }
- var _primarySubCiphertext = _primaryCiphertext.getPhis();
- var _secondarySubCiphertext = _secondaryCiphertext.getPhis();
- var _numKeyElements = _primaryPublicKey.getGroupElementsArray().length;
- var numOutputs = _numKeyElements + 1;
- var phiFunctionSimplePlaintextEquality = new box.proofs.PhiFunction(
- group, 1, numOutputs, buildListOfBaseElements(),
- buildComputationRules(_numKeyElements));
- var _verifier =
- new box.proofs.Verifier(group, phiFunctionSimplePlaintextEquality);
- this._buildInputList = function() {
- var dividedSubCiphertext = mathematical.groupUtils.divide(
- _primarySubCiphertext, _secondarySubCiphertext);
- var generatedList = [];
- generatedList.push(_primaryCiphertext.getGamma());
- generatedList.addAll(dividedSubCiphertext);
- return generatedList;
- };
- this._getProof = function() {
- return _proof;
- };
- this._getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _numKeyElements * 2 + 1, progressCallback,
- progressPercentMinCheckInterval);
- return this;
- };
- this._getVerifier = function() {
- return _verifier;
- };
- };
- box.proofs.SimplePlaintextEqualityProofVerifier.prototype = {
- verify: function() {
- return this._getVerifier().verify(
- this._buildInputList(), this._getProof(),
- box.SIMPLE_PLAINTEXT_EQUALITY_PROOF_AUXILIARY_DATA,
- this._getProgressMeter());
- }
- };
- /**
- * Plaintext equality proof verifier.
- */
- box.proofs.PlaintextEqualityProofVerifier = function(
- primaryCiphertext, primaryPublicKey, secondaryCiphertext,
- secondaryPublicKey, proof, group) {
- checkDefined('primary ciphertext', primaryCiphertext);
- checkDefined('primary public key', primaryPublicKey);
- checkDefined('secondary ciphertext', secondaryCiphertext);
- checkDefined('secondary public key', secondaryPublicKey);
- checkDefined('proof', proof);
- checkDefined('group', group);
- var _primaryCiphertext = primaryCiphertext;
- var _primaryPublicKey = primaryPublicKey;
- var _secondaryCiphertext = secondaryCiphertext;
- var _secondaryPublicKey = secondaryPublicKey;
- var _proof = proof;
- var buildComputationRules = function(k) {
- var firstDimensionLength = k + 2;
- var rules = [];
- rules[0] = [];
- rules[0][0] = [];
- rules[0][0].push(1);
- rules[0][0].push(1);
- rules[1] = [];
- rules[1][0] = [];
- rules[1][0].push(1);
- rules[1][0].push(2);
- for (var i = 2; i < firstDimensionLength; i++) {
- rules[i] = [];
- rules[i][0] = [];
- rules[i][1] = [];
- rules[i][0].push(i);
- rules[i][0].push(1);
- rules[i][1].push(i + k);
- rules[i][1].push(2);
- }
- return rules;
- };
- function buildListOfBaseElements() {
- var invertedSecondaryKeyValues = buildSecondaryInvertedPublicKey();
- var baseElements = [];
- baseElements.push(group.getGenerator());
- baseElements.addAll(_primaryPublicKey.getGroupElementsArray());
- baseElements.addAll(invertedSecondaryKeyValues);
- return baseElements;
- }
- function buildSecondaryInvertedPublicKey() {
- var listInvertedElements = [];
- var keys = _secondaryPublicKey.getGroupElementsArray();
- for (var i = 0; i < keys.length; i++) {
- listInvertedElements.push(keys[i].invert());
- }
- return listInvertedElements;
- }
- var _progressMeter;
- var _primarySubCiphertext = _primaryCiphertext.getPhis();
- var _secondarySubCiphertext = _secondaryCiphertext.getPhis();
- var _numKeyElements = primaryPublicKey.getGroupElementsArray().length;
- var numOutputs = _numKeyElements + 2;
- var phiFunctionPlaintextEquality = new box.proofs.PhiFunction(
- group, 2, numOutputs, buildListOfBaseElements(),
- buildComputationRules(_numKeyElements));
- var _verifier =
- new box.proofs.Verifier(group, phiFunctionPlaintextEquality);
- this._buildInputList = function() {
- var dividedSubCiphertext = mathematical.groupUtils.divide(
- _primarySubCiphertext, _secondarySubCiphertext);
- var generatedList = [];
- generatedList.push(_primaryCiphertext.getGamma());
- generatedList.push(_secondaryCiphertext.getGamma());
- generatedList.addAll(dividedSubCiphertext);
- return generatedList;
- };
- this._getProof = function() {
- return _proof;
- };
- this._getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _numKeyElements * 2 + 2, progressCallback,
- progressPercentMinCheckInterval);
- return this;
- };
- this._getVerifier = function() {
- return _verifier;
- };
- };
- box.proofs.PlaintextEqualityProofVerifier.prototype = {
- verify: function() {
- return this._getVerifier().verify(
- this._buildInputList(), this._getProof(),
- box.PLAINTEXT_EQUALITY_PROOF_AUXILIARY_DATA,
- this._getProgressMeter());
- }
- };
- /**
- * Plaintext exponent equality proof verifier.
- */
- box.proofs.PlaintextExponentEqualityProofVerifier = function(
- ciphertext, baseElements, proof, group) {
- checkDefined('ciphertext', ciphertext);
- checkDefined('base elements', baseElements);
- checkDefined('proof', proof);
- checkDefined('group', group);
- var _ciphertext = ciphertext;
- var _baseElements = baseElements;
- var _proof = proof;
- var _group = group;
- var _progressMeter;
- this._buildComputationRules = function(k) {
- var rules = [];
- var firstDimensionLength = k + 1;
- rules[0] = [];
- rules[0][0] = [];
- rules[0][0].push(1);
- rules[0][0].push(1);
- for (var i = 1; i < firstDimensionLength; i++) {
- rules[i] = [];
- rules[i][0] = [];
- rules[i][1] = [];
- rules[i][0].push(i + 1);
- rules[i][0].push(1);
- rules[i][1].push(i + 1 + k);
- rules[i][1].push(2);
- }
- return rules;
- };
- this._buildListPublicValues = function() {
- var list = [];
- list.push(_ciphertext.getGamma());
- list.addAll(_ciphertext.getPhis());
- return list;
- };
- var _k = _ciphertext.getPhis().length;
- var numOutputs = _k + 1;
- var phiFunctionPlaintextExponentEquality = new box.proofs.PhiFunction(
- _group, 2, numOutputs, _baseElements, this._buildComputationRules(_k));
- var _verifier =
- new box.proofs.Verifier(_group, phiFunctionPlaintextExponentEquality);
- this._getProof = function() {
- return _proof;
- };
- this._getVerifier = function() {
- return _verifier;
- };
- this._getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _k * 2 + 1, progressCallback, progressPercentMinCheckInterval);
- return this;
- };
- };
- box.proofs.PlaintextExponentEqualityProofVerifier.prototype = {
- verify: function() {
- return this._getVerifier().verify(
- this._buildListPublicValues(), this._getProof(),
- box.PLAINTEXT_EXPONENT_EQUALITY_PROOF_AUXILIARY_DATA,
- this._getProgressMeter());
- }
- };
- /**
- * OR-proof verifier.
- */
- box.proofs.ORProofVerifier = function(publicKey, numElements, group) {
- checkPublicKey(publicKey);
- checkNumElements(numElements);
- checkGroup(group);
- var _publicKey = publicKey;
- var _numElements = numElements;
- var _group = group;
- var _numOutputs = _numElements * 2;
- var _progressMeter;
- function checkPublicKey(publicKey) {
- checkDefined('public key', publicKey);
- checkNotNull('public key', publicKey);
- var publicKeyLength = publicKey.getGroupElementsArray().length;
- if (publicKeyLength !== 1) {
- throw new exceptions.CryptoLibException(
- 'Expected public key length: 1 ; Found: ' + publicKeyLength);
- }
- }
- function checkNumElements(numElements) {
- checkDefined('numElements', numElements);
- checkNotNull('numElements', numElements);
- if (numElements < 2) {
- throw new exceptions.CryptoLibException(
- 'Expected number of elements to be greater than 1 ; Found: ' +
- numElements);
- }
- }
- function checkGroup(group) {
- checkDefined('group', group);
- checkNotNull('group', group);
- }
- function buildBaseElements() {
- var baseElements = [];
- baseElements.push(_group.getGenerator());
- baseElements.push(_publicKey.getGroupElementsArray()[0]);
- return baseElements;
- }
- function buildComputationRules(numOutputs) {
- var rules = [];
- var index1;
- var index2 = 0;
- for (var i = 0; i < numOutputs; i++) {
- index1 = 1 + (i % 2);
- if (i % 2 === 0) {
- index2++;
- }
- rules[i] = [];
- rules[i][0] = [];
- rules[i][0].push(index1);
- rules[i][0].push(index2);
- }
- return rules;
- }
- var phiFunctionOR = new box.proofs.PhiFunction(
- _group, _numElements, _numOutputs, buildBaseElements(),
- buildComputationRules(_numOutputs));
- var _verifier = new box.proofs.Verifier(_group, phiFunctionOR);
- this.buildPublicValues = function(ciphertext) {
- var publicValues = [];
- publicValues.push(ciphertext.getGamma());
- publicValues.push(ciphertext.getPhis()[0]);
- return publicValues;
- };
- this.getNumElements = function() {
- return _numElements;
- };
- this.getVerifier = function() {
- return _verifier;
- };
- this.getProgressMeter = function() {
- return _progressMeter;
- };
- this.initProgressMeter = function(
- progressCallback, progressPercentMinCheckInterval) {
- _progressMeter = createProgressMeter(
- _numOutputs, progressCallback, progressPercentMinCheckInterval);
- return this;
- };
- };
- box.proofs.ORProofVerifier.prototype = {
- verify: function(ciphertext, elements, data, proof) {
- checkCiphertext(ciphertext);
- checkElements(elements, this.getNumElements());
- checkDefined('data', data);
- checkProof(proof);
- function checkCiphertext(ciphertext) {
- checkDefined('ciphertext', ciphertext);
- checkNotNull('ciphertext', ciphertext);
- var ciphertextLength = ciphertext.getPhis().length + 1;
- if (ciphertextLength !== 2) {
- throw new exceptions.CryptoLibException(
- 'Expected ciphertext length: 2 ; Found: ' + ciphertextLength);
- }
- }
- function checkElements(elements, numElementsExpected) {
- checkDefined('elements', elements);
- checkNotNull('elements', elements);
- var numElementsFound = elements.length;
- if (numElementsFound !== numElementsExpected) {
- throw new exceptions.CryptoLibException(
- 'Expected number of elements: ' + numElementsExpected +
- ' ; Found: ' + numElementsFound);
- }
- }
- function checkProof(proof) {
- checkDefined('proof', proof);
- checkNotNull('proof', proof);
- }
- if (data === null) {
- data = '';
- }
- return this.getVerifier().verify(
- this.buildPublicValues(ciphertext), proof, data, elements,
- this.getProgressMeter());
- }
- };
- /**
- * Proofs factory, can be used for creating proof generators and verifiers.
- */
- box.proofs.ProofsFactory = function() {
- };
- box.proofs.ProofsFactory.prototype = {
- createSchnorrProofGenerator: function(voterID, electionID, group) {
- return new box.proofs.SchnorrProofGenerator(voterID, electionID, group);
- },
- createExponentiationProofGenerator: function(baseElements, group) {
- return new box.proofs.ExponentiationProofGenerator(baseElements, group);
- },
- createPlaintextProofGenerator: function(publicKey, group) {
- return new box.proofs.PlaintextProofGenerator(publicKey, group);
- },
- createSimplePlaintextEqualityProofGenerator: function(
- primaryPublicKey, secondaryPublicKey, group) {
- return new box.proofs.SimplePlaintextEqualityProofGenerator(
- primaryPublicKey, secondaryPublicKey, group);
- },
- createPlaintextEqualityProofGenerator: function(
- primaryPublicKey, secondaryPublicKey, group) {
- return new box.proofs.PlaintextEqualityProofGenerator(
- primaryPublicKey, secondaryPublicKey, group);
- },
- createPlaintextExponentEqualityProofGenerator: function(
- baseElements, group) {
- return new box.proofs.PlaintextExponentEqualityProofGenerator(
- baseElements, group);
- },
- createORProofGenerator: function(publicKey, numElements, group) {
- return new box.proofs.ORProofGenerator(publicKey, numElements, group);
- },
- createSchnorrProofVerifier: function(
- element, voterID, electionEventID, proof, group) {
- return new box.proofs.SchnorrProofVerifier(
- element, voterID, electionEventID, proof, group);
- },
- createExponentiationProofVerifier: function(
- exponentiatedElements, baseElements, proof, group) {
- return new box.proofs.ExponentiationProofVerifier(
- exponentiatedElements, baseElements, proof, group);
- },
- createPlaintextProofVerifier: function(
- publicKey, ciphertext, plaintext, proof, group) {
- return new box.proofs.PlaintextProofVerifier(
- publicKey, ciphertext, plaintext, proof, group);
- },
- createSimplePlaintextEqualityProofVerifier: function(
- primaryCiphertext, primaryPublicKey, secondaryCiphertext,
- secondaryPublicKey, proof, group) {
- return new box.proofs.SimplePlaintextEqualityProofVerifier(
- primaryCiphertext, primaryPublicKey, secondaryCiphertext,
- secondaryPublicKey, proof, group);
- },
- createPlaintextEqualityProofVerifier: function(
- primaryCiphertext, primaryPublicKey, secondaryCiphertext,
- secondaryPublicKey, proof, group) {
- return new box.proofs.PlaintextEqualityProofVerifier(
- primaryCiphertext, primaryPublicKey, secondaryCiphertext,
- secondaryPublicKey, proof, group);
- },
- createPlaintextExponentEqualityProofVerifier: function(
- ciphertext, baseElements, proof, group) {
- return new box.proofs.PlaintextExponentEqualityProofVerifier(
- ciphertext, baseElements, proof, group);
- },
- createORProofVerifier: function(publicKey, numElements, group) {
- return new box.proofs.ORProofVerifier(publicKey, numElements, group);
- }
- };
- /**
- * Represents the PHI function of Maurer's Unified Zero-Knowledge Proof of
- * Knowledge (ZK-PoK) scheme.
- */
- box.proofs.PhiFunction = function(
- group, numInputs, numOutputs, baseElements, computationRules) {
- var validateComputationRules = function(
- numInputs, numOutputs, baseElements, computationRules) {
- // Validate that both of the values in each of the
- // pairs of rules have values in the correct ranges
- var numBaseElements = baseElements.length;
- for (var i = 0; i < numOutputs; i++) {
- for (var j = 0; j < computationRules[i].length; j++) {
- // Validate the first value of the pair
- var pairValue1 = computationRules[i][j][0];
- if ((pairValue1 < 1) || (pairValue1 > numBaseElements)) {
- throw new exceptions.CryptoLibException(
- 'Invalid first value in index pair - should be in the range 1 to ' +
- numBaseElements + ', but it was ' + pairValue1);
- }
- // Validate the second value of the pair
- var pairValue2 = computationRules[i][j][1];
- if ((pairValue2 < 1) || (pairValue2 > numInputs)) {
- throw new exceptions.CryptoLibException(
- 'Invalid second value in index pair - should be in the range 1 to ' +
- numInputs + ', but it was ' + pairValue2);
- }
- }
- }
- };
- checkDefined('group', group);
- checkIsPositive('number of inputs', numInputs);
- checkIsPositive('number of outputs', numOutputs);
- checkInitializedArray('base elements', baseElements);
- checkDefined('computation rules', computationRules);
- validateComputationRules(
- numInputs, numOutputs, baseElements, computationRules);
- var _numInputs = numInputs;
- var _numOutputs = numOutputs;
- var _baseElements = baseElements;
- var _computationRules = computationRules;
- /**
- * @return The number of inputs
- */
- this.getNumInputs = function() {
- return _numInputs;
- };
- /**
- * @return The number of outputs
- */
- this.getNumOutputs = function() {
- return _numOutputs;
- };
- /**
- * @return The list of base elements
- */
- this.getBaseElements = function() {
- return _baseElements;
- };
- /**
- * @return The computation rules.
- */
- this.getComputationRules = function() {
- return _computationRules;
- };
- };
- box.proofs.PhiFunction.prototype = {
- calculatePhi: function(inputs, progressMeter) {
- checkDefined('inputs', inputs);
- if (progressMeter === undefined) {
- progressMeter = new utils.ProgressMeter();
- }
- checkDefined('progressMeter', progressMeter);
- var computationsRules = this.getComputationRules();
- var baseElements = this.getBaseElements();
- var partialResult;
- var resultForThisListOfPairs;
- var result = [];
- var progress = 0;
- for (var i = 0; i < computationsRules.length; i++) {
- var numPairsInList = computationsRules[i].length;
- resultForThisListOfPairs =
- baseElements[computationsRules[i][0][0] - 1].exponentiate(
- inputs[computationsRules[i][0][1] - 1]);
- progressMeter.update(++progress);
- for (var j = 1; j < numPairsInList; j++) {
- var index1 = computationsRules[i][j][0];
- index1 = index1 - 1;
- var index2 = computationsRules[i][j][1];
- index2 = index2 - 1;
- partialResult = baseElements[index1].exponentiate(inputs[index2]);
- resultForThisListOfPairs =
- resultForThisListOfPairs.multiply(partialResult);
- progressMeter.update(++progress);
- }
- result.push(resultForThisListOfPairs);
- }
- return result;
- }
- };
- /**
- * Acts as a prover in a Zero-Knowledge Proof of Knowledge (ZK-PoK) exchange
- * using Maurer's unified PHI function.
- */
- box.proofs.Prover = function(group, phiFunction) {
- checkDefined('group', group);
- checkDefined('phiFunction', phiFunction);
- var _group = group;
- var _phiFunction = phiFunction;
- var _cryptoRandomInteger = secureRandomFactory.getCryptoRandomInteger();
- /**
- * @return Get the group.
- */
- this.getGroup = function() {
- return _group;
- };
- /**
- * @return Get the phi function.
- */
- this.getPhiFunction = function() {
- return _phiFunction;
- };
- this._calculateRandomExponents = function(numExponentsNeeded) {
- var exponentsArray = [];
- for (var i = 0; i < numExponentsNeeded; i++) {
- var randomExponent = mathematical.groupUtils.generateRandomExponent(
- _group, _cryptoRandomInteger);
- exponentsArray.push(randomExponent);
- }
- return exponentsArray;
- };
- this._generateHash = function(publicValues, phiOutputs, data) {
- var hashBuilder = new box.proofs.HashBuilder();
- var hashB64 =
- hashBuilder.buildHashForProof(publicValues, phiOutputs, data);
- var hash = converters.base64Decode(hashB64);
- var hashBytes = converters.bytesFromString(hash);
- hashBytes.unshift(0);
- var value = new box.forge.jsbn.BigInteger(hashBytes);
- return new mathematical.Exponent(_group.getQ(), value);
- };
- this._generateValuesList = function(
- privateValues, hash, randomExponents, index) {
- var proofValues = [];
- var proofValue;
- if (typeof index === 'undefined') {
- for (var i = 0; i < privateValues.length; i++) {
- proofValue = randomExponents[i].getValue().add(
- privateValues[i].getValue().multiply(hash.getValue()));
- proofValues.push(
- new mathematical.Exponent(_group.getQ(), proofValue));
- }
- } else {
- var numElements = randomExponents.length / 2;
- var updatedHash = hash;
- for (var j = 0; j < numElements; j++) {
- if (j === index) {
- for (var k = 0; k < numElements; k++) {
- if (k !== index) {
- updatedHash = updatedHash.subtract(randomExponents[k]);
- }
- }
- proofValues.push(updatedHash);
- } else {
- proofValues.push(randomExponents[j]);
- }
- }
- for (var m = numElements; m < (numElements * 2); m++) {
- if (m === (numElements + index)) {
- proofValue = randomExponents[m].getValue().add(
- privateValues[0].getValue().multiply(updatedHash.getValue()));
- proofValues.push(
- new mathematical.Exponent(_group.getQ(), proofValue));
- } else {
- proofValues.push(randomExponents[m]);
- }
- }
- }
- return proofValues;
- };
- this._updatePreComputedValues = function(
- preComputedValues, publicValues, elements, index) {
- var gamma = publicValues[0];
- var phi = publicValues[1];
- var numElements = elements.length;
- var challenges = this._calculateRandomExponents(numElements);
- var updatedExponents = [];
- updatedExponents.addAll(challenges);
- updatedExponents.addAll(preComputedValues.getExponents());
- var updatedPhiOutputs = [];
- var phiOutputs = preComputedValues.getPhiOutputs();
- for (var j = 0; j < numElements; j++) {
- var offset = 2 * j;
- if (j === index) {
- updatedPhiOutputs.push(phiOutputs[offset]);
- updatedPhiOutputs.push(phiOutputs[offset + 1]);
- } else {
- var gammaFactor = gamma.invert().exponentiate(challenges[j]);
- var phiFactor =
- (phi.invert().multiply(elements[j])).exponentiate(challenges[j]);
- updatedPhiOutputs.push(phiOutputs[offset].multiply(gammaFactor));
- updatedPhiOutputs.push(phiOutputs[offset + 1].multiply(phiFactor));
- }
- }
- return new box.proofs.ProofPreComputedValues(
- updatedExponents, updatedPhiOutputs);
- };
- };
- box.proofs.Prover.prototype = {
- /**
- * Pre-compute time-consuming values, so they can be used later for
- * method prove().
- */
- preCompute: function(privateValuesLength, progressMeter) {
- var randomExponents = this._calculateRandomExponents(privateValuesLength);
- var phiOutputs =
- this.getPhiFunction().calculatePhi(randomExponents, progressMeter);
- return new box.proofs.ProofPreComputedValues(randomExponents, phiOutputs);
- },
- /**
- * Performs prover steps in a ZK-PoK exchange using Maurer's unified PHI
- * function. This involves generating a proof, using the received inputs
- * and this Prover's internal fields.
- */
- prove: function(
- publicValues, privateValues, data, preComputedValues, elements, index) {
- checkDefined('public values', publicValues);
- checkDefined('private values', privateValues);
- checkDefined('data', data);
- if (!preComputedValues ||
- typeof preComputedValues.getPhiOutputs() === 'undefined' ||
- typeof preComputedValues.getExponents() === 'undefined') {
- throw new exceptions.CryptoLibException(
- 'The precomputed values must be initialized');
- }
- if (typeof elements !== 'undefined') {
- preComputedValues = this._updatePreComputedValues(
- preComputedValues, publicValues, elements, index);
- }
- var hash = this._generateHash(
- publicValues, preComputedValues.getPhiOutputs(), data);
- var proofValues = this._generateValuesList(
- privateValues, hash, preComputedValues.getExponents(), index);
- return new box.proofs.Proof(hash, proofValues);
- }
- };
- /**
- * Acts as a verifier in a Zero-Knowledge Proof of Knowledge (ZK-PoK)
- * exchange using Maurer's unified PHI function.
- */
- box.proofs.Verifier = function(group, phiFunction) {
- checkDefined('group', group);
- checkDefined('phiFunction', phiFunction);
- var _group = group;
- var _phiFunction = phiFunction;
- /**
- * @return Get the group.
- */
- this.getGroup = function() {
- return _group;
- };
- /**
- * @return Get the phi function.
- */
- this.getPhiFunction = function() {
- return _phiFunction;
- };
- this._calculateComputedValues = function(
- publicValues, phiOutputs, proofHashValueOrElements, challenges) {
- var proofHashValue;
- var elements;
- if (!isArray(proofHashValueOrElements)) {
- proofHashValue = proofHashValueOrElements;
- } else {
- elements = proofHashValueOrElements;
- }
- var computedValues = [];
- if (typeof proofHashValue !== 'undefined') {
- for (var i = 0; i < phiOutputs.length; i++) {
- computedValues.push(phiOutputs[i].multiply(
- publicValues[i].exponentiate(proofHashValue.negate())));
- }
- } else {
- var gamma = publicValues[0];
- var phi = publicValues[1];
- for (var j = 0; j < challenges.length; j++) {
- var offset = 2 * j;
- var gammaFactor = gamma.invert().exponentiate(challenges[j]);
- var phiFactor =
- (phi.invert().multiply(elements[j])).exponentiate(challenges[j]);
- computedValues.push(phiOutputs[offset].multiply(gammaFactor));
- computedValues.push(phiOutputs[offset + 1].multiply(phiFactor));
- }
- }
- return computedValues;
- };
- this._calculateHash = function(publicValues, computedValues, data) {
- var hashBuilder = new box.proofs.HashBuilder();
- var hashB64 =
- hashBuilder.buildHashForProof(publicValues, computedValues, data);
- var hash = converters.base64Decode(hashB64);
- var hashBytes = converters.bytesFromString(hash);
- hashBytes.unshift(0);
- var value = new box.forge.jsbn.BigInteger(hashBytes);
- return new mathematical.Exponent(_group.getQ(), value);
- };
- };
- box.proofs.Verifier.prototype = {
- /**
- * Verifies the received input as being true or false.
- */
- verify: function(
- publicValues, proof, data, elementsOrProgressMeter, progressMeter) {
- checkDefined('public values', publicValues);
- checkDefined('proof', proof);
- checkDefined('data', data);
- var elements;
- if (!isArray(elementsOrProgressMeter)) {
- progressMeter = elementsOrProgressMeter;
- } else {
- elements = elementsOrProgressMeter;
- }
- var proofHashValue = proof.getHash();
- var phiOutputs;
- var computedValues;
- if (typeof elements === 'undefined') {
- phiOutputs = this.getPhiFunction().calculatePhi(
- proof.getValues(), progressMeter);
- computedValues = this._calculateComputedValues(
- publicValues, phiOutputs, proofHashValue);
- } else {
- var numElements = elements.length;
- var proofValues = proof.getValues();
- var challenges = proofValues.slice(0, numElements);
- var phiInputs = proofValues.slice(numElements, numElements * 2);
- phiOutputs =
- this.getPhiFunction().calculatePhi(phiInputs, progressMeter);
- computedValues = this._calculateComputedValues(
- publicValues, phiOutputs, elements, challenges);
- }
- var calculatedHash =
- this._calculateHash(publicValues, computedValues, data);
- return proofHashValue.equals(calculatedHash);
- }
- };
- /**
- * @class ProofPreComputedValues stores randomly created exponents and
- * outputs of box.proofs.PhiFunction.calculatePhi().
- */
- box.proofs.ProofPreComputedValues = function(exponents, phiOutputs) {
- this.className = 'ProofPreComputedValues';
- var _exponents = exponents;
- var _phiOutputs = phiOutputs;
- /**
- * @return the exponents.
- */
- this.getExponents = function() {
- return _exponents;
- };
- /**
- * @return the phi function output.
- */
- this.getPhiOutputs = function() {
- return _phiOutputs;
- };
- };
- box.proofs.ProofPreComputedValues.prototype = {
- stringify: function() {
- var exponentValues = Array();
- var phiOutputValues = Array();
- for (var i = 0; i < this.getExponents().length; i++) {
- exponentValues[i] =
- converters.base64FromBigInteger(this.getExponents()[i].getValue());
- }
- for (var j = 0; j < this.getPhiOutputs().length; j++) {
- phiOutputValues[j] = converters.base64FromBigInteger(
- this.getPhiOutputs()[j].getElementValue());
- }
- return JSON.stringify({
- preComputed: {
- p: converters.base64FromBigInteger(this.getPhiOutputs()[0].getP()),
- q: converters.base64FromBigInteger(this.getPhiOutputs()[0].getQ()),
- exponents: exponentValues,
- phiOutputs: phiOutputValues
- }
- });
- }
- };
- /**
- * Represents a proof in a ZKP exchange.
- */
- box.proofs.Proof = function(hashValue, values) {
- checkDefined('hash value', hashValue);
- checkDefined('values', values);
- var _hashValue = hashValue;
- var _values = values;
- /**
- * @return Get the hash value of this proof.
- */
- this.getHash = function() {
- return _hashValue;
- };
- /**
- * @return Get the list of values of this proof.
- */
- this.getValues = function() {
- return _values;
- };
- };
- box.proofs.Proof.prototype = {
- /**
- * @return true if the given proof has the same hash and values.
- */
- equals: function(proof) {
- return proof.getHash().equals(this.getHash()) &&
- proof.getValues().equals(this.getValues());
- },
- /**
- * Displays a string representation of this proof JSON.
- * <p>
- * Note: in order to permit interoperability between libraries, this
- * representation should match the equivalent representation in Java.
- *
- * @function
- * @returns a string representation of this proof JSON.
- */
- stringify: function() {
- var values = Array();
- for (var i = 0; i < this.getValues().length; i++) {
- values[i] =
- converters.base64FromBigInteger(this.getValues()[i].getValue());
- }
- return JSON.stringify({
- zkProof: {
- q: converters.base64FromBigInteger(this.getHash().getQ()),
- hash: converters.base64FromBigInteger(this.getHash().getValue()),
- values: values
- }
- });
- }
- };
- /**
- * A class which provides utility methods for generating a hash from a set
- * of inputs.
- */
- box.proofs.HashBuilder = function() {
- /**
- * Convert an integer to a byte array
- */
- this._getInt64Bytes = function(x) {
- var bytes = [];
- var i = 8;
- do {
- bytes[--i] = x & (255);
- x = x >> 8;
- } while (i);
- return bytes;
- };
- /**
- * Converts an array to a String.
- */
- this._arrayElementValuesToString = function(groupElements) {
- var str = '';
- for (var i = 0; i < groupElements.length; i++) {
- if (groupElements[i].getElementValue() !== undefined) {
- str += groupElements[i].getElementValue();
- } else {
- throw new exceptions.CryptoLibException(
- 'Group Element must implement getElementValue() method.');
- }
- }
- return str;
- };
- };
- box.proofs.HashBuilder.prototype = {
- /**
- * Generates a hash value based on the element values of publicValues
- * and generatedValues and the data.
- *
- * @function
- * @param publicValues
- * {array} group elements representing public values.
- * @param generatedValues
- * {array} group elements representing generated values.
- * @param data
- * {string} some data encoded as a String.
- * @returns a generated hash code.
- * @throws CryptoLibException
- * if any of the received objects has unsupported type.
- */
- buildHashForProof: function(publicValues, generatedValues, data) {
- checkInitializedArray('public values', publicValues);
- checkInitializedArray('generated values', generatedValues);
- var messageDigester = messageDigestFactory.getCryptoMessageDigest();
- messageDigester.start();
- messageDigester = update(
- messageDigester, this._arrayElementValuesToString(publicValues));
- messageDigester = update(
- messageDigester, this._arrayElementValuesToString(generatedValues));
- messageDigester = update(messageDigester, data);
- return messageDigester.digest();
- }
- };
- /**
- * Utility method that updates messageDigester with the provided string.
- */
- function update(messageDigester, str) {
- var stringRepresentationB64 = converters.base64Encode(str);
- var arrayToHash = [];
- arrayToHash.push(stringRepresentationB64);
- messageDigester.update(arrayToHash);
- return messageDigester;
- }
- /**
- * Utility method that checks that value is defined and not null and throws
- * related exception otherwise.
- */
- function checkDefined(key, value) {
- if (typeof value === 'undefined') {
- throw new exceptions.CryptoLibException(
- 'The ' + key + ' must be defined');
- }
- }
- /**
- * Utility method that checks that value is initialized array and throws
- * related exception otherwise.
- */
- function checkInitializedArray(key, value) {
- checkDefined(key, value);
- if (!isArray(value)) {
- throw new exceptions.CryptoLibException(
- 'The ' + key + ' must be an initialized array');
- }
- }
- /**
- * Utility method that checks that value is not null and throws related
- * exception otherwise.
- */
- function checkNotNull(key, value) {
- checkDefined(key, value);
- if (value === null) {
- throw new exceptions.CryptoLibException(
- 'The ' + key + ' must not be null');
- }
- }
- /**
- * Utility method that checks that value is not empty and throws related
- * exception otherwise.
- */
- function checkNotEmpty(key, value) {
- checkDefined(key, value);
- if (value.length === 0) {
- throw new exceptions.CryptoLibException(
- 'The ' + key + ' must not be empty');
- }
- }
- /**
- * Utility method that checks that value is positive and throws related
- * exception otherwise.
- */
- function checkIsPositive(key, value) {
- checkDefined(key, value);
- if (isNaN(value)) {
- throw new exceptions.CryptoLibException(
- 'The ' + key + ' must be a number; Found ' + value);
- }
- if (value <= 0) {
- throw new exceptions.CryptoLibException(
- 'The ' + key + ' must be positive; Found ' + value);
- }
- }
- /**
- * Utility method that checks that values are defined and throws related
- * exception otherwise.
- */
- var checkDefinedProgressParams = function(
- progressCallback, progressPercentMinCheckInterval) {
- if (typeof progressCallback !== 'undefined' &&
- typeof progressCallback !== 'function') {
- throw new exceptions.CryptoLibException(
- 'The progress callback function provided as input is not a function');
- }
- if (typeof progressPercentMinCheckInterval !== 'undefined' &&
- isNaN(progressPercentMinCheckInterval)) {
- throw new exceptions.CryptoLibException(
- 'The progress percentage check interval provided as input is not a number');
- }
- };
- function isArray(a) {
- return (!!a) && (a.constructor === Array);
- }
- /**
- * Utility method that creates a new instance of ProgressMeter.
- */
- function createProgressMeter(
- progressMax, progressCallback, progressPercentMinCheckInterval) {
- checkDefinedProgressParams(
- progressCallback, progressPercentMinCheckInterval);
- return new utils.ProgressMeter(
- progressMax, progressCallback, progressPercentMinCheckInterval);
- }
- /**
- * Provides utility functionality for working with proofs.
- *
- * @class utils
- * @memberof proofs
- */
- box.proofs.utils = (function() {
- /**
- * Deserializes a Proof JSON string representation to a Proof object.
- *
- * @function
- * @memberof proofs.utils
- * @param jsonAsString
- * {JSON} a JSON representation of a proof.
- * @returns a new Proof, created from the received string.
- */
- function deserializeProof(jsonAsString) {
- var proofJson = JSON.parse(jsonAsString).zkProof;
- var q = converters.base64ToBigInteger(proofJson.q);
- var hash = new box.commons.mathematical.Exponent(
- q, converters.base64ToBigInteger(proofJson.hash));
- var values = [];
- for (var i = 0; i < proofJson.values.length; i++) {
- values.push(new box.commons.mathematical.Exponent(
- q, converters.base64ToBigInteger(proofJson.values[i])));
- }
- return new box.proofs.Proof(hash, values);
- }
- /**
- * Deserializes a ProofPreComputedValues JSON string representation to a
- * ProofPreComputedValues object.
- *
- * @function
- * @memberof proofs.utils
- * @param jsonAsString
- * {JSON} a JSON representation of a pre-computed value.
- * @returns a new ProofPreComputedValues, created from the received
- * string.
- */
- function deserializeProofPreComputedValues(jsonAsString) {
- var proofPreComputedValuesJson = JSON.parse(jsonAsString).preComputed;
- var p = converters.base64ToBigInteger(proofPreComputedValuesJson.p);
- var q = converters.base64ToBigInteger(proofPreComputedValuesJson.q);
- var exponentValues = proofPreComputedValuesJson.exponents;
- var exponents = [];
- var value;
- for (var i = 0; i < exponentValues.length; i++) {
- value = converters.base64ToBigInteger(exponentValues[i]);
- exponents.push(new box.commons.mathematical.Exponent(q, value));
- }
- var phiOutputValues = proofPreComputedValuesJson.phiOutputs;
- var phiOutputs = [];
- for (var j = 0; j < phiOutputValues.length; j++) {
- value = converters.base64ToBigInteger(phiOutputValues[j]);
- phiOutputs.push(
- new box.commons.mathematical.ZpGroupElement(value, p, q));
- }
- return new box.proofs.ProofPreComputedValues(exponents, phiOutputs);
- }
- return {
- deserializeProof: deserializeProof,
- deserializeProofPreComputedValues: deserializeProofPreComputedValues
- };
- })();
- };
|