/* * Copyright 2018 Scytl Secure Electronic Voting SA * * All rights reserved * * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package */ describe('Proofs ...', function() { 'use strict'; describe('Should be loaded if cryptolib is called with proofs: ', function() { it('should be defined a proofs', function() { cryptolib('*', function(box) { expect(typeof box.proofs.SimplePlaintextEqualityProofGenerator) .toBeDefined(); }); }); }); describe('PhiFunction ...', function() { describe('validate inputs ...', function() { it('valid inputs', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = new box.forge.jsbn.BigInteger('1'); var baseElements = [ new box.forge.jsbn.BigInteger('1'), new box.forge.jsbn.BigInteger('2') ]; var computationsRules = [[0, 1], [1, 1]]; var createdPhiFunction = new box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); expect(createdPhiFunction).toBeDefined(); }); }); it('invalid group', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var zpSubgroup = new box.forge.jsbn.BigInteger('11'); var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = new box.forge.jsbn.BigInteger('1'); var baseElements = [ new box.forge.jsbn.BigInteger('1'), new box.forge.jsbn.BigInteger('2') ]; var computationsRules = [[0, 1], [1, 1]]; // Note: Expect exception not to be thrown here but proof verification // will fail; See service tests. box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }); }); it('invalid number of inputs', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs; var numOutputs = new box.forge.jsbn.BigInteger('1'); var baseElements = [ new box.forge.jsbn.BigInteger('1'), new box.forge.jsbn.BigInteger('2') ]; var computationsRules = [[0, 1], [1, 1]]; expect(function() { box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }).toThrow(); }); }); it('invalid number of outputs (null)', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs; var baseElements = [ new box.forge.jsbn.BigInteger('1'), new box.forge.jsbn.BigInteger('2') ]; var computationsRules = [[0, 1], [1, 1]]; expect(function() { box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }).toThrow(); }); }); it('invalid number of outputs (negative)', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = -2; var baseElements = [ new box.forge.jsbn.BigInteger('1'), new box.forge.jsbn.BigInteger('2') ]; var computationsRules = [[0, 1], [1, 1]]; expect(function() { box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }).toThrow(); }); }); it('invalid number of outputs (array)', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = [[0, 1], [1, 1]]; var baseElements = [ new box.forge.jsbn.BigInteger('1'), new box.forge.jsbn.BigInteger('2') ]; var computationsRules = [[0, 1], [1, 1]]; expect(function() { box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }).toThrow(); }); }); it('invalid base elements (null)', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = new box.forge.jsbn.BigInteger('1'); var baseElements; var computationsRules = [[0, 1], [1, 1]]; expect(function() { box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }).toThrow(); }); }); it('invalid base elements (not array)', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = new box.forge.jsbn.BigInteger('1'); var baseElements = new box.forge.jsbn.BigInteger('1'); var computationsRules = [[0, 1], [1, 1]]; expect(function() { box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }).toThrow(); }); }); it('invalid computation rules (null)', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = new box.forge.jsbn.BigInteger('1'); var baseElements = new box.forge.jsbn.BigInteger('1'); var computationsRules; expect(function() { box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }).toThrow(); }); }); it('invalid computation rules (not array)', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = new box.forge.jsbn.BigInteger('1'); var baseElements = new box.forge.jsbn.BigInteger('1'); var computationsRules = new box.forge.jsbn.BigInteger('1'); expect(function() { box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }).toThrow(); }); }); it('invalid computation rules: first index value is smaller than 1', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = new box.forge.jsbn.BigInteger('1'); var zpGroupElement_p23_v2 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('2'), p, q); var baseElements = [zpGroupElement_p23_v2]; var computationsRules = [[[0, 1]]]; expect(function() { box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }).toThrow(); }); }); it('invalid computation rules: first index value larger then number of base elements', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = new box.forge.jsbn.BigInteger('1'); var zpGroupElement_p23_v2 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('2'), p, q); var baseElements = [zpGroupElement_p23_v2, zpGroupElement_p23_v2]; var computationsRules = [[[3, 1]]]; expect(function() { box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }).toThrow(); }); }); it('invalid computation rules: second index value smaller than 1', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = new box.forge.jsbn.BigInteger('1'); var zpGroupElement_p23_v2 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('2'), p, q); var baseElements = [zpGroupElement_p23_v2]; var computationsRules = [[[1, 0]]]; expect(function() { box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }).toThrow(); }); }); it('invalid computation rules: second index value bigger than number of inputs', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create PhiFunction var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var numInputs = new box.forge.jsbn.BigInteger('2'); var numOutputs = new box.forge.jsbn.BigInteger('1'); var zpGroupElement_p23_v2 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('2'), p, q); var zpGroupElement_p23_v3 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('3'), p, q); var baseElements = [zpGroupElement_p23_v2, zpGroupElement_p23_v3]; var computationsRules = [[[1, 2], [1, 3]]]; expect(function() { box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); }).toThrow(); }); }); }); describe('calculatePhi ...', function() { it('invalid inputs', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create group var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); // create additional needed parameters var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = new box.forge.jsbn.BigInteger('1'); var baseElements = [zpSubgroup.getGenerator()]; var computationsRules = [[[1, 1]]]; // create PhiFunction var createdPhiFunction = new box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); // create array of exponents var value1 = new box.forge.jsbn.BigInteger('2'); var exponent1 = new box.commons.mathematical.Exponent(zpSubgroup.getQ(), value1); var exponentArray = [exponent1]; var result = createdPhiFunction.calculatePhi(exponentArray); var expectedElement = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('4'), zpSubgroup.getP(), zpSubgroup.getQ()); var expectedResultArray = [expectedElement]; expect(expectedResultArray.equals(result)).toBeTruthy(); }); }); }); }); describe('Prover ...', function() { describe('validate inputs ...', function() { it('validate inputs', function() { cryptolib('proofs', function() {}); }); it('invalid inputs', function() { cryptolib('proofs', function() {}); }); }); describe('prove ...', function() { describe('validate inputs ...', function() { }); }); }); describe('Proof ...', function() { it('validate inputs', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create proof var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var value = new box.forge.jsbn.BigInteger('2'); var hash = new box.commons.mathematical.Exponent(zpSubgroup.getQ(), value); var value1 = new box.forge.jsbn.BigInteger('2'); var exp1 = new box.commons.mathematical.Exponent(zpSubgroup.getQ(), value1); var value2 = new box.forge.jsbn.BigInteger('3'); var exp2 = new box.commons.mathematical.Exponent(zpSubgroup.getQ(), value2); var values = [exp1, exp2]; var createdProof = new box.proofs.Proof(hash, values); expect(createdProof).toBeDefined(); }); }); it('validate equals true', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create proof1 var p1_q = new box.forge.jsbn.BigInteger('11'); var p1_generator = new box.forge.jsbn.BigInteger('2'); var p1_p = new box.forge.jsbn.BigInteger('23'); var p1_zpSubgroup = new box.commons.mathematical.ZpSubgroup(p1_generator, p1_p, p1_q); var p1_value = new box.forge.jsbn.BigInteger('5'); var p1_hash = new box.commons.mathematical.Exponent( p1_zpSubgroup.getQ(), p1_value); var p1_value1 = new box.forge.jsbn.BigInteger('3'); var p1_exp1 = new box.commons.mathematical.Exponent( p1_zpSubgroup.getQ(), p1_value1); var p1_value2 = new box.forge.jsbn.BigInteger('4'); var p1_exp2 = new box.commons.mathematical.Exponent( p1_zpSubgroup.getQ(), p1_value2); var p1_values = [p1_exp1, p1_exp2]; var p1_createdProof = new box.proofs.Proof(p1_hash, p1_values); expect(p1_createdProof).toBeDefined(); // create proof2 var p2_q = new box.forge.jsbn.BigInteger('11'); var p2_generator = new box.forge.jsbn.BigInteger('2'); var p2_p = new box.forge.jsbn.BigInteger('23'); var p2_zpSubgroup = new box.commons.mathematical.ZpSubgroup(p2_generator, p2_p, p2_q); var p2_value = new box.forge.jsbn.BigInteger('5'); var p2_hash = new box.commons.mathematical.Exponent( p2_zpSubgroup.getQ(), p2_value); var p2_value1 = new box.forge.jsbn.BigInteger('3'); var p2_exp1 = new box.commons.mathematical.Exponent( p2_zpSubgroup.getQ(), p2_value1); var p2_value2 = new box.forge.jsbn.BigInteger('4'); var p2_exp2 = new box.commons.mathematical.Exponent( p2_zpSubgroup.getQ(), p2_value2); var p2_values = [p2_exp1, p2_exp2]; var p2_createdProof = new box.proofs.Proof(p2_hash, p2_values); expect(p2_createdProof).toBeDefined(); expect(p1_createdProof.equals(p2_createdProof)).toBeTruthy(); }); }); it('validate equals false', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create proof1 var p1_q = new box.forge.jsbn.BigInteger('11'); var p1_generator = new box.forge.jsbn.BigInteger('2'); var p1_p = new box.forge.jsbn.BigInteger('23'); var p1_zpSubgroup = new box.commons.mathematical.ZpSubgroup(p1_generator, p1_p, p1_q); var p1_value = new box.forge.jsbn.BigInteger('5'); var p1_hash = new box.commons.mathematical.Exponent( p1_zpSubgroup.getQ(), p1_value); var p1_value1 = new box.forge.jsbn.BigInteger('3'); var p1_exp1 = new box.commons.mathematical.Exponent( p1_zpSubgroup.getQ(), p1_value1); var p1_value2 = new box.forge.jsbn.BigInteger('3'); var p1_exp2 = new box.commons.mathematical.Exponent( p1_zpSubgroup.getQ(), p1_value2); var p1_values = [p1_exp1, p1_exp2]; var p1_createdProof = new box.proofs.Proof(p1_hash, p1_values); expect(p1_createdProof).toBeDefined(); // create proof2 var p2_q = new box.forge.jsbn.BigInteger('11'); var p2_generator = new box.forge.jsbn.BigInteger('2'); var p2_p = new box.forge.jsbn.BigInteger('23'); var p2_zpSubgroup = new box.commons.mathematical.ZpSubgroup(p2_generator, p2_p, p2_q); var p2_value = new box.forge.jsbn.BigInteger('5'); var p2_hash = new box.commons.mathematical.Exponent( p2_zpSubgroup.getQ(), p2_value); var p2_value1 = new box.forge.jsbn.BigInteger('3'); var p2_exp1 = new box.commons.mathematical.Exponent( p2_zpSubgroup.getQ(), p2_value1); var p2_value2 = new box.forge.jsbn.BigInteger('4'); var p2_exp2 = new box.commons.mathematical.Exponent( p2_zpSubgroup.getQ(), p2_value2); var p2_values = [p2_exp1, p2_exp2]; var p2_createdProof = new box.proofs.Proof(p2_hash, p2_values); expect(p2_createdProof).toBeDefined(); expect(p1_createdProof.equals(p2_createdProof)).not.toBeTruthy(); }); }); it('stringify correctly to the JSON string: {"zkProof":{"q":"Cw==","hash":"Ag==","values":["Ag==","Aw=="]}}', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create proof var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); var value = new box.forge.jsbn.BigInteger('2'); var hash = new box.commons.mathematical.Exponent(zpSubgroup.getQ(), value); var value1 = new box.forge.jsbn.BigInteger('2'); var exp1 = new box.commons.mathematical.Exponent(zpSubgroup.getQ(), value1); var value2 = new box.forge.jsbn.BigInteger('3'); var exp2 = new box.commons.mathematical.Exponent(zpSubgroup.getQ(), value2); var values = [exp1, exp2]; var proof = new box.proofs.Proof(hash, values); var jsonAsString = proof.stringify(); expect(jsonAsString).toContain('"zkProof"'); expect(jsonAsString).toContain('"q":"Cw=="'); expect(jsonAsString).toContain('"hash":"Ag=="'); expect(jsonAsString).toContain('"values":'); expect(jsonAsString.length) .toBe( '{"zkProof":{"q":"Cw==","hash":"Ag==","values":["Ag==","Aw=="]}}' .length); }); }); it('deserialize correctly from the JSON string: {"zkProof":{"q":"Cw==","hash":"Ag==","values":["Ag==","Aw=="]}}', function() { cryptolib('proofs', 'commons.mathematical', function(box) { var proofAsJson = '{"zkProof":{"q":"Cw==","hash":"Ag==","values":["Ag==","Aw=="]}}'; var deserializedProof = box.proofs.utils.deserializeProof(proofAsJson); var serializedProof = deserializedProof.stringify(); expect(serializedProof).toEqual(proofAsJson); }); }); }); describe('HashBuilder ...', function() { describe('When created with ...', function() { it('valid inputs', function() { cryptolib( 'proofs', 'commons.mathematical', 'primitives.messagedigest', function(box) { var hashbuilder = new box.proofs.HashBuilder(); expect(hashbuilder).toBeDefined(); }); }); }); describe('When buildHashForProof is called ...', function() { describe('passing a one character String ...', function() { it('then expected an exception', function() { cryptolib( 'proofs', 'commons.mathematical', 'primitives.messagedigest', 'commons.utils', function(box) { var hashbuilder = new box.proofs.HashBuilder(); var oneCharacterString = 'a'; var inputObjectArray = []; inputObjectArray.push(oneCharacterString); expect(function() { hashbuilder.buildHashForProof(inputObjectArray); }).toThrow(); }); }); }); describe('get hash twice from same objects ...', function() { it('then same result both times', function() { cryptolib( 'proofs', 'commons.mathematical', 'primitives.messagedigest', 'commons.utils', function(box) { var converters = new box.commons.utils.Converters(); var hashbuilder = new box.proofs.HashBuilder(); // create group and elements var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var group = new box.commons.mathematical.ZpSubgroup(generator, p, q); var ZpGroupElement_p23_v2 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('2'), group.getP(), group.getQ()); var ZpGroupElement_p23_v3 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('3'), group.getP(), group.getQ()); var ZpGroupElement_p23_v4 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('4'), group.getP(), group.getQ()); // Create objects that will be hashed. var _simpleList1 = []; _simpleList1.push(ZpGroupElement_p23_v2); _simpleList1.push(ZpGroupElement_p23_v3); var _simpleList2 = []; _simpleList2.push(ZpGroupElement_p23_v4); var _short_string1 = 'I am a short String'; var _simpleList3 = []; _simpleList3.push(ZpGroupElement_p23_v2); _simpleList3.push(ZpGroupElement_p23_v3); var _simpleList4 = []; _simpleList4.push(ZpGroupElement_p23_v4); var _short_string2 = 'I am a short String'; var bytesB64_1 = hashbuilder.buildHashForProof( _simpleList1, _simpleList2, _short_string1); var bytes1 = converters.base64Decode(bytesB64_1); var result1 = new box.forge.jsbn.BigInteger( converters.bytesFromString(bytes1)); var bytesB64_2 = hashbuilder.buildHashForProof( _simpleList3, _simpleList4, _short_string2); var bytes2 = converters.base64Decode(bytesB64_2); var result2 = new box.forge.jsbn.BigInteger( converters.bytesFromString(bytes2)); expect(result1.equals(result2)).toBeTruthy(); }); }); }); describe( 'passing lists containing Zp subgroup elements and strings ...', function() { it('then expected output', function() { cryptolib( 'proofs', 'commons.mathematical', 'primitives.messagedigest', 'commons.utils', function(box) { var converters = new box.commons.utils.Converters(); var hashbuilder = new box.proofs.HashBuilder(); // create group and elements var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var group = new box.commons.mathematical.ZpSubgroup( generator, p, q); var ZpGroupElement_p23_v2 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('2'), group.getP(), group.getQ()); var ZpGroupElement_p23_v3 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('3'), group.getP(), group.getQ()); var ZpGroupElement_p23_v4 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('4'), group.getP(), group.getQ()); // Create objects that will be hashed. var _simpleList1 = []; _simpleList1.push(ZpGroupElement_p23_v2); _simpleList1.push(ZpGroupElement_p23_v3); var _simpleList2 = []; _simpleList2.push(ZpGroupElement_p23_v4); var _short_string = 'I am a short String'; var bytesB64_1 = hashbuilder.buildHashForProof( _simpleList1, _simpleList2, _short_string); var bytes1 = converters.base64Decode(bytesB64_1); var result = new box.forge.jsbn.BigInteger( converters.bytesFromString(bytes1)); var javaResult = new box.forge.jsbn.BigInteger( '-52725384769643723964651772032205801420047176905115581490667997821371105732649'); expect(javaResult.equals(result)).toBeTruthy(); }); }); }); describe('passing an Exponent ...', function() { it('then expected output', function() { cryptolib( 'proofs', 'commons.mathematical', 'primitives.messagedigest', function() {}); }); }); }); }); describe('Maurer proof ...', function() { it('calculatePhi must be defined', function() { cryptolib('proofs', 'commons.mathematical', function(box) { // create group var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var zpSubgroup = new box.commons.mathematical.ZpSubgroup(generator, p, q); // create additional needed parameters var numInputs = new box.forge.jsbn.BigInteger('1'); var numOutputs = new box.forge.jsbn.BigInteger('1'); var baseElements = [zpSubgroup.getGenerator()]; var computationsRules = [[[1, 1]]]; // create PhiFunction var createdPhiFunction = new box.proofs.PhiFunction( zpSubgroup, numInputs, numOutputs, baseElements, computationsRules); expect(createdPhiFunction).toBeDefined(); // create array of exponents var value1 = new box.forge.jsbn.BigInteger('2'); var exponent1 = new box.commons.mathematical.Exponent(zpSubgroup.getQ(), value1); var exponentArray = [exponent1]; var data = 'testdata'; var prover = new box.proofs.Prover(zpSubgroup, createdPhiFunction); var exponentiatedElement = zpSubgroup.getGenerator().exponentiate(exponent1); var precomputationValues = prover.preCompute(1); var proofResult = prover.prove( [exponentiatedElement], exponentArray, data, precomputationValues); expect(proofResult).toBeTruthy(); }); }); }); describe('Schnorr proof ...', function() { it('should be able to be generate and verify a Schnorr proof', function() { cryptolib('proofs', 'commons', 'primitives.messagedigest', function(box) { // create group var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var group = new box.commons.mathematical.ZpSubgroup(generator, p, q); var exponent = new box.commons.mathematical.Exponent( q, new box.forge.jsbn.BigInteger('8')); var exponentiatedElement = group.getGenerator().exponentiate(exponent); var proofsFactory = new box.proofs.ProofsFactory(); var schnorrProof = proofsFactory .createSchnorrProofGenerator('123456789', '99999999', group) .generate(exponentiatedElement, exponent); var proofTruth = proofsFactory .createSchnorrProofVerifier( exponentiatedElement, '123456789', '99999999', schnorrProof, group) .verify(); expect(proofTruth).toBeTruthy(); }); }); it('should throw an exception in Schnorr proof generator if voterID is null', function() { cryptolib( 'proofs', 'commons', 'primitives.messagedigest', function(box) { // create group var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var group = new box.commons.mathematical.ZpSubgroup(generator, p, q); var exponent = new box.commons.mathematical.Exponent( q, new box.forge.jsbn.BigInteger('8')); var exponentiatedElement = group.getGenerator().exponentiate(exponent); var voterIdGenerator; var electionEventIdGenerator = '99999999'; var proofsFactory = new box.proofs.ProofsFactory(); expect(function() { createSchnorrProof( proofsFactory, group, exponentiatedElement, exponent, voterIdGenerator, electionEventIdGenerator); }).toThrow(); }); }); it('should throw an exception in schnorr proof generator if voterID is empty', function() { cryptolib( 'proofs', 'commons', 'primitives.messagedigest', function(box) { // create group var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var group = new box.commons.mathematical.ZpSubgroup(generator, p, q); var exponent = new box.commons.mathematical.Exponent( q, new box.forge.jsbn.BigInteger('8')); var exponentiatedElement = group.getGenerator().exponentiate(exponent); var voterIdGenerator = ''; var electionEventIdGenerator = '99999999'; var proofsFactory = new box.proofs.ProofsFactory(); expect(function() { createSchnorrProof( proofsFactory, group, exponentiatedElement, exponent, voterIdGenerator, electionEventIdGenerator); }).toThrow(); }); }); it('should throw an exception in Schnorr proof generator if electionEventId is null', function() { cryptolib( 'proofs', 'commons', 'primitives.messagedigest', function(box) { // create group var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var group = new box.commons.mathematical.ZpSubgroup(generator, p, q); var exponent = new box.commons.mathematical.Exponent( q, new box.forge.jsbn.BigInteger('8')); var exponentiatedElement = group.getGenerator().exponentiate(exponent); var voterIdGenerator = '123456789'; var electionEventIdGenerator; var proofsFactory = new box.proofs.ProofsFactory(); expect(function() { createSchnorrProof( proofsFactory, group, exponentiatedElement, exponent, voterIdGenerator, electionEventIdGenerator); }).toThrow(); }); }); it('should throw an exception in schnorr proof generator if electionEventId is empty', function() { cryptolib( 'proofs', 'commons', 'primitives.messagedigest', function(box) { // create group var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var group = new box.commons.mathematical.ZpSubgroup(generator, p, q); var exponent = new box.commons.mathematical.Exponent( q, new box.forge.jsbn.BigInteger('8')); var exponentiatedElement = group.getGenerator().exponentiate(exponent); var voterIdGenerator = '123456789'; var electionEventIdGenerator = ''; var proofsFactory = new box.proofs.ProofsFactory(); expect(function() { createSchnorrProof( proofsFactory, group, exponentiatedElement, exponent, voterIdGenerator, electionEventIdGenerator); }).toThrow(); }); }); it('should throw an exception in Schnorr proof verifier if voterID is null', function() { cryptolib( 'proofs', 'commons', 'primitives.messagedigest', function(box) { // create group var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var group = new box.commons.mathematical.ZpSubgroup(generator, p, q); var exponent = new box.commons.mathematical.Exponent( q, new box.forge.jsbn.BigInteger('8')); var exponentiatedElement = group.getGenerator().exponentiate(exponent); var voterIdGenerator = '123456789'; var electionEventIdGenerator = '99999999'; var voterIdVerifier; var electionEventIdVerifier = '99999999'; var proofsFactory = new box.proofs.ProofsFactory(); var schnorrProof = proofsFactory .createSchnorrProofGenerator( voterIdGenerator, electionEventIdGenerator, group) .generate(exponentiatedElement, exponent); expect(function() { proofsFactory .createSchnorrProofVerifier( exponentiatedElement, voterIdVerifier, electionEventIdVerifier, schnorrProof, group) .verify(); }).toThrow(); }); }); it('should throw an exception in Schnorr proof verifier if voterID is empty', function() { cryptolib( 'proofs', 'commons', 'primitives.messagedigest', function(box) { // create group var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var group = new box.commons.mathematical.ZpSubgroup(generator, p, q); var exponent = new box.commons.mathematical.Exponent( q, new box.forge.jsbn.BigInteger('8')); var exponentiatedElement = group.getGenerator().exponentiate(exponent); var voterIdGenerator = '123456789'; var electionEventIdGenerator = '99999999'; var voterIdVerifier = ''; var electionEventIdVerifier = '99999999'; var proofsFactory = new box.proofs.ProofsFactory(); var schnorrProof = proofsFactory .createSchnorrProofGenerator( voterIdGenerator, electionEventIdGenerator, group) .generate(exponentiatedElement, exponent); expect(function() { proofsFactory .createSchnorrProofVerifier( exponentiatedElement, voterIdVerifier, electionEventIdVerifier, schnorrProof, group) .verify(); }).toThrow(); }); }); it('should throw an exception in Schnorr proof verifier if electionEventId is null', function() { cryptolib( 'proofs', 'commons', 'primitives.messagedigest', function(box) { // create group var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var group = new box.commons.mathematical.ZpSubgroup(generator, p, q); var exponent = new box.commons.mathematical.Exponent( q, new box.forge.jsbn.BigInteger('8')); var exponentiatedElement = group.getGenerator().exponentiate(exponent); var voterIdGenerator = '123456789'; var electionEventIdGenerator = '99999999'; var voterIdVerifier = '123456789'; var electionEventIdVerifier; var proofsFactory = new box.proofs.ProofsFactory(); var schnorrProof = proofsFactory .createSchnorrProofGenerator( voterIdGenerator, electionEventIdGenerator, group) .generate(exponentiatedElement, exponent); expect(function() { proofsFactory .createSchnorrProofVerifier( exponentiatedElement, voterIdVerifier, electionEventIdVerifier, schnorrProof, group) .verify(); }).toThrow(); }); }); it('should throw an exception in Schnorr proof verifier if electionEventId is empty', function() { cryptolib( 'proofs', 'commons', 'primitives.messagedigest', function(box) { // create group var q = new box.forge.jsbn.BigInteger('11'); var generator = new box.forge.jsbn.BigInteger('2'); var p = new box.forge.jsbn.BigInteger('23'); var group = new box.commons.mathematical.ZpSubgroup(generator, p, q); var exponent = new box.commons.mathematical.Exponent( q, new box.forge.jsbn.BigInteger('8')); var exponentiatedElement = group.getGenerator().exponentiate(exponent); var voterIdGenerator = '123456789'; var electionEventIdGenerator = '99999999'; var voterIdVerifier = '123456789'; var electionEventIdVerifier = ''; var proofsFactory = new box.proofs.ProofsFactory(); var schnorrProof = proofsFactory .createSchnorrProofGenerator( voterIdGenerator, electionEventIdGenerator, group) .generate(exponentiatedElement, exponent); expect(function() { proofsFactory .createSchnorrProofVerifier( exponentiatedElement, voterIdVerifier, electionEventIdVerifier, schnorrProof, group) .verify(); }).toThrow(); }); }); describe('plaintext proof', function() { it('must fail if plaintext and the public key have a different number of arguments', function() { cryptolib('*', function(box) { var elGamalCipherFactory = new box.homomorphic.cipher.factory.ElGamalCipherFactory(); var keyFactory = new box.homomorphic.keypair.factory.KeyFactory(); var p = new box.forge.jsbn.BigInteger( '16495768820687182934009927347170440458984298969141051719651115246768228783533993705048522613555003722650163857541125634359204551517133551948222225229585505473854815904204008387572449239572558997742610313328207134588877674958965112510857989409372589489554367815761232020129433262382857561981217475899722020926354221968452402385754809505679432634661210095701454463437258972380072638986797327376359801509825066468445666991457815992978097875265987862649581950696045865510189368336440306143914792406918514769060068547350680676698071521344166677089027364466838527577675388855690260527795812471209293838170074431021658585769'); var q = new box.forge.jsbn.BigInteger( '96020784172851661018443454307652214686331639842501459760074411037927395553939'); var generator = new box.forge.jsbn.BigInteger( '15130260694873909459986577784204643986832006548758872568127622990613286376947389953860539257554587993925082794507831758880350292337036239661614300430033670574377146869864951070388980213523097422627922584301566881102629991359716406049006152033115595975218156523898904324261190660093347613804122603060933508651584944555007181780395855126908781477484110624848678463182770318846991956864510428932259181036820923323061517278008748271670358287455340697499004281391354210072366308177032171585041936224750556137265259765883084633653387023221827373593952176436229429968550363326770646572341416840037353790767464212018954641189'); var plaintextValues = '13001958155330604183283440349326249836910073645746606152086317081542370925085323829577576343220220970830242334422088928335776849693699317596697308070491655988846936544490170854760622263229593132359288598939754030438763377074672036413960553517345827407874240954931856460473275871494952759213809834622191632962928152282758068810785997095964792534886071457598558200037994837193502017861972726981702601645743757363301481452380559572428601079773415878406878889283104921714313573036550932216793644548235628221219857860491590917419188368179146906649074848254341715041556794836535625862564803932425535053708105664756328176096,13231973095563029671832096284884900786942379344314765999736867442501058904676516417925101650742389109597711424534876455182391728375468332757263296899395351639193353410112338073499025899736418030529915324365551044922832874533047175715575665120707774002324384088317703371342441254493502521221058572909498259802514124188958407279318160157200557318801491755304390175475424809222021529440615330205038504228764024791004717836281566455683657139407029417762297815388016430137008344688954594677000059036704922079131336478242363366789868164308084428340745898909076987038168924165852440487400698910077949024596427386762477753127,14962213442437221630882804374502807481065630653554446432724314309377638233420429625929060616149342043360565572219423869257414407292350550499520720685455656488232644853879526758539416856088474668103469469539535531657659096824387210346084505215030036305938457977750754924998601715702575511194945674310421459334341817535064482476480331751171219419177177690275196093512303662432640330876384877571377755052302164787402266089676321850441055346812973279399849013829646051767527082830058880156180804337513629780923908712327566442241827419862207132399832645578550470975229103528239481602587884774035574980636031799832387127824'; plaintextValues = plaintextValues.split(','); var publickey = '2310052637281374826163980155072703478550584783282353794746356503851736624950501110627753937319986533000522391643440057809085228551963268616650076198499939080674555452672248616965754928293235729345758867884335314010776031118255924016690941973710021793693357184670835265674549998079458749041612609723185323556418090275187898731901111571900886838242789201627029788753318822261542649942667275986354422715719555421167864656006766965757148569592487004683308842191788591435697129834559463075935646313837018575516319421503514590374988521988732632646137082482614398122769481744648900076625388202771688539721397175709860657215,10992040365912330212603556159890860989323436780424734140469776597559966083776288793792880271187249577475862540041272265165115141691436552098724587148672885376255101720449710739879257167893375710652999579682329540866493597320896396042034863583144965792072687133983833723367505914551649613644957007736294052065759536432864892568886279889430332858208212502323472429844596803009794879201124168960173108172884523529447057933188670605500761004550561618533233760048349811136008540506656716161194168608193768775892759430117403245548580741988574926317015003026743034307396424854331578214723160905311258827711514036727758661443,2966454546948674594238484453818820495774263494738027649885606698735626946977004754473084281799793802225340057166391055854897568455044693120227990997044954520274944912364134982880734979624278026290300479874061515681112538596438177835791333982353892136013223338695390663410151102503147241467125785231395240349671275198727614663753021483991961941587552003516822754894985284436598456509038426029451562110689110854200741545361500678654576568967692431517292344770939502725349301506972598902856573261152531261931708724855752770349361196880952259389543735606329934472812841863925491905824596299316439858950888740168931063033,16685125032225465591271616129024153088399594055921872535905780296582091131024932497146054111843749963435248897831820496896855297302629640382562118371399923587479991981933850508478973979849045483506501618718824692791050899387832529345913319557326115349466503641556936384534756871248087479236266210661587928787040614097509670326965654744522366069845631192304570814294808544467147342154545110452347943098767091892623807533767816665018437155453169438229244628337513271777636288916880160385420829994354060040651547330045332962210808881666427991175014815542151556166234899209736414331653334634166108740897978989610512241'; publickey = publickey.split(','); var group = new box.commons.mathematical.ZpSubgroup(generator, p, q); // create public key var value, groupElement; var elements = []; for (var i = 0; i < publickey.length; i++) { value = new box.forge.jsbn.BigInteger('' + publickey[i]); groupElement = new box.commons.mathematical.ZpGroupElement( value, group.getP(), group.getQ()); elements.push(groupElement); } var elGamalPublicKey = keyFactory.createPublicKey(elements, group); // plaintext var plaintext = []; for (i = 0; i < plaintextValues.length; i++) { value = new box.forge.jsbn.BigInteger(plaintextValues[i]); groupElement = new box.commons.mathematical.ZpGroupElement( value, group.getP(), group.getQ()); plaintext.push(groupElement); } // get encrypters var encrypter = elGamalCipherFactory.createEncrypter(elGamalPublicKey); var ciphertext = encrypter.encryptGroupElements(plaintext); expect(function() { box.proofs.service.createPlaintextProof( elGamalPublicKey, ciphertext, plaintext, ciphertext.getR(), group); }).toThrow(); }); }); }); }); describe('ProofPreComputedValues ... ', function() { it('should be serialized correctly to JSON format', function() { cryptolib('*', function(box) { var p = new box.forge.jsbn.BigInteger('23'); var q = new box.forge.jsbn.BigInteger('11'); var exponent0 = new box.commons.mathematical.Exponent( q, new box.forge.jsbn.BigInteger('2')); var exponent1 = new box.commons.mathematical.Exponent( q, new box.forge.jsbn.BigInteger('8')); var exponent2 = new box.commons.mathematical.Exponent( q, new box.forge.jsbn.BigInteger('9')); var exponents = [exponent0, exponent1, exponent2]; var zpGroupElement_p23_v2 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('2'), p, q); var zpGroupElement_p23_v3 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('3'), p, q); var zpGroupElement_p23_v4 = new box.commons.mathematical.ZpGroupElement( new box.forge.jsbn.BigInteger('4'), p, q); var phiOutputs = [ zpGroupElement_p23_v2, zpGroupElement_p23_v3, zpGroupElement_p23_v4 ]; var precomputationValues = new box.proofs.ProofPreComputedValues(exponents, phiOutputs); var jsonAsString = precomputationValues.stringify(); expect(jsonAsString).toContain('"preComputed":'); expect(jsonAsString).toContain('"p":"Fw=="'); expect(jsonAsString).toContain('"q":"Cw=="'); expect(jsonAsString).toContain('"exponents":["Ag==","CA==","CQ=="]'); expect(jsonAsString).toContain('"phiOutputs":["Ag==","Aw==","BA=="]'); expect(jsonAsString.length) .toBe( '{"preComputed":{"p":"Fw==","q":"Cw==","exponents":["Ag==","CA==","CQ=="],"phiOutputs":["Ag==","Aw==","BA=="]}}' .length); }); }); it('should be deserialized correctly from JSON format', function() { cryptolib('*', function(box) { var preComputedValues = box.proofs.utils.deserializeProofPreComputedValues( '{"preComputed":{"p":"Fw==","q":"Cw==","exponents":["Ag==","CA==","CQ=="],"phiOutputs":["Ag==","Aw==","BA=="]}}'); expect(preComputedValues).toBeDefined(); expect(preComputedValues.getExponents().length).toEqual(3); expect(preComputedValues.getExponents()[0].getQ().toString()) .toEqual('11'); expect(preComputedValues.getExponents()[0].getValue().toString()) .toEqual('2'); expect(preComputedValues.getExponents()[1].getValue().toString()) .toEqual('8'); expect(preComputedValues.getExponents()[2].getValue().toString()) .toEqual('9'); expect(preComputedValues.getPhiOutputs().length).toEqual(3); expect(preComputedValues.getPhiOutputs()[0].getP().toString()) .toEqual('23'); expect(preComputedValues.getPhiOutputs()[0].getQ().toString()) .toEqual('11'); expect( preComputedValues.getPhiOutputs()[0].getElementValue().toString()) .toEqual('2'); expect( preComputedValues.getPhiOutputs()[1].getElementValue().toString()) .toEqual('3'); expect( preComputedValues.getPhiOutputs()[2].getElementValue().toString()) .toEqual('4'); }); }); }); function createSchnorrProof( proofsFactory, group, exponentiatedElement, exponent, voterIdGenerator, electionEventIdGenerator) { return proofsFactory.createSchnorrProofGenerator(group).generate( exponentiatedElement, exponent, voterIdGenerator, electionEventIdGenerator); } });