123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /*
- * Copyright 2018 Scytl Secure Electronic Voting SA
- *
- * All rights reserved
- *
- * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
- */
- /* jshint node:true */
- 'use strict';
- var HashGenerator = require('./hash-generator');
- var codec = require('scytl-codec');
- module.exports = ZeroKnowledgeProofVerifier;
- /**
- * @class ZeroKnowledgeProofVerifier
- * @classdesc Encapsulates a zero-knowledge proof of knowledge verifier that
- * uses the PHI function defined in Maurer's unified framework.
- * @private
- * @param {MessageDigestService}
- * messageDigestService The message digest service.
- * @param {MathematicalService}
- * mathService The mathematical service.
- */
- function ZeroKnowledgeProofVerifier(messageDigestService, mathService) {
- /**
- * Verifies a zero-knowledge proof of knowledge.
- *
- * @function verify
- * @memberof ZeroKnowledgeProofVerifier
- * @param {ZpSubgroup}
- * group The Zp subgroup to which all exponents and Zp group
- * elements required for the proof verification are associated or
- * belong, respectively.
- * @param {ZeroKnowledgeProof}
- * proof The zero-knowledge proof of knowledge to verify.
- * @param {PhiFunction}
- * phiFunction The PHI function used for the verification.
- * @param {ZpGroupElement[]}
- * publicValues The public values used to verify the proof.
- * @param {Uint8Array|string}
- * data Auxiliary data.
- * @param {ZpGroupElement[]|ProgressMeter}
- * [elementsOrProgressMeter=Not used] The possible Zp group
- * elements used to generate the ciphertext of an OR
- * zero-knowledge proof <b>OR</b> a progress meter.
- * @param {number}
- * [progressMeter=Not used] A parameter that can be used as a
- * progress meter, for the case in which the previous parameter
- * was of type <code>ZpGroupElements[]</code>.
- * @returns {boolean} <code>true</code> if the zero-knowledge proof of
- * knowledge was verified, <code>false</code> otherwise.
- */
- this.verify = function(
- group, proof, phiFunction, publicValues, data, elementsOrProgressMeter,
- progressMeter) {
- var elements;
- if (!isArray(elementsOrProgressMeter)) {
- progressMeter = elementsOrProgressMeter;
- } else {
- elements = elementsOrProgressMeter;
- }
- var proofHash = proof.hash;
- var phiOutputs;
- var generatedValues;
- if (typeof elements === 'undefined') {
- phiOutputs = phiFunction.calculate(proof.values, progressMeter);
- generatedValues = generateValues(publicValues, phiOutputs, proofHash);
- } else {
- var numElements = elements.length;
- var proofValues = proof.values;
- var challenges = proofValues.slice(0, numElements);
- var phiInputs = proofValues.slice(numElements, numElements * 2);
- phiOutputs = phiFunction.calculate(phiInputs, progressMeter);
- generatedValues =
- generateValues(publicValues, phiOutputs, elements, challenges);
- }
- var calculatedHash =
- generateHash(group, publicValues, generatedValues, data);
- return proofHash.equals(calculatedHash);
- };
- function generateValues(
- publicValues, phiOutputs, proofHashOrElements, challenges) {
- var proofHash;
- var elements;
- if (!isArray(proofHashOrElements)) {
- proofHash = proofHashOrElements;
- } else {
- elements = proofHashOrElements;
- }
- var generatedValues = [];
- if (typeof proofHash !== 'undefined') {
- for (var i = 0; i < phiOutputs.length; i++) {
- generatedValues.push(phiOutputs[i].multiply(
- publicValues[i].exponentiate(proofHash.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]);
- generatedValues.push(phiOutputs[offset].multiply(gammaFactor));
- generatedValues.push(phiOutputs[offset + 1].multiply(phiFactor));
- }
- }
- return generatedValues;
- }
- function generateHash(group, publicValues, generatedValues, data) {
- var hashGenerator = new HashGenerator(messageDigestService);
- var hashBytes = hashGenerator.generate(publicValues, generatedValues, data);
- var hashByteArray = Array.apply([], hashBytes);
- hashByteArray.unshift(0);
- var value = codec.bytesToBigInteger(hashBytes);
- return mathService.newExponent(group.q, value);
- }
- function isArray(a) {
- return (!!a) && (a.constructor === Array);
- }
- }
|