/// <summary> /// If verifier knows Integer B, returns the default bit-decomposition. Returns Null if verifier does not know integer B. /// If bit[i] = 0, output[i] = verifier.G^0. /// If bit[i] = 1, output[i] = verifier.G. /// </summary> /// <param name="verifier">Verifier parameters.</param> /// <returns></returns> private static DLRepOfGroupElement[] DefaultOpenDecompositionOfIntegerB(VerifierRangeProofParameters verifier) { if (!verifier.IntegerBIsKnown) { return(null); } FieldZqElement integerB = verifier.FieldZq.GetElement((uint)verifier.RangeNormalizedIntegerB); int decompositionLength = ComputeDecompositionLength(verifier); BitArray bitsB = VerifierBitDecompositionParameters.GetBitDecomposition(integerB, decompositionLength, verifier.FieldZq); PedersenCommitment[] defaultBitDecomposition = new PedersenCommitment[bitsB.Length]; GroupElement [] bases = new GroupElement [2] { verifier.G, verifier.H }; FieldZqElement [] exponent0 = new FieldZqElement[2] { verifier.FieldZq.Zero, verifier.FieldZq.Zero, }; FieldZqElement [] exponent1 = new FieldZqElement[2] { verifier.FieldZq.One, verifier.FieldZq.Zero, }; for (int i = 0; i < defaultBitDecomposition.Length; ++i) { if (!bitsB.Get(i)) { defaultBitDecomposition[i] = new PedersenCommitment(bases, exponent0, verifier.Group); } else { defaultBitDecomposition[i] = new PedersenCommitment(bases, exponent1, verifier.Group); } } return(defaultBitDecomposition); }
/// <summary> /// Constructs a bit decomposition of openCommitment.CommittedValue and /// generates the appropriate ProverBitDecompositionParameters. /// If decompositionLength is too short, automatically chooses /// minimum required length. /// </summary> /// <param name="openCommitment">Pedersen Commitment to some value</param> /// <param name="decompositionLength">Number of bits in bit-decomposition.</param> /// <param name="parameterSet">Parameter set</param> /// <returns></returns> public ProverBitDecompositionParameters( PedersenCommitment openCommitment, int decompositionLength, CryptoParameters crypto) : base(crypto) { BitArray bits = VerifierBitDecompositionParameters.GetBitDecomposition(openCommitment.CommittedValue, decompositionLength, this.FieldZq); PedersenCommitment [] openBitDecomposition = new PedersenCommitment[bits.Length]; for (int bitIndex = 0; bitIndex < bits.Length; ++bitIndex) { if (bits.Get(bitIndex)) { openBitDecomposition[bitIndex] = new PedersenCommitment(crypto.FieldZq.One, crypto); } else { openBitDecomposition[bitIndex] = new PedersenCommitment(crypto.FieldZq.Zero, crypto); } } this.setProverParameters(openBitDecomposition, openCommitment); }
/// <summary> /// If verifier knows Integer B, returns the default bit-decomposition. Returns Null if verifier does not know integer B. /// If bit[i] = 0, output[i] = verifier.G^0. /// If bit[i] = 1, output[i] = verifier.G. /// </summary> /// <param name="verifier">Verifier parameters.</param> /// <returns></returns> private static GroupElement[] DefaultClosedDecompositionOfIntegerB(VerifierRangeProofParameters verifier) { if (!verifier.IntegerBIsKnown) { return(null); } FieldZqElement integerB = verifier.FieldZq.GetElement((uint)verifier.RangeNormalizedIntegerB); int decompositionLength = ComputeDecompositionLength(verifier); BitArray bitsB = VerifierBitDecompositionParameters.GetBitDecomposition(integerB, decompositionLength, verifier.FieldZq); GroupElement[] defaultBitDecomposition = new GroupElement[bitsB.Length]; for (int i = 0; i < defaultBitDecomposition.Length; ++i) { if (bitsB.Get(i)) { defaultBitDecomposition[i] = verifier.G; } else { defaultBitDecomposition[i] = verifier.Group.Identity; } } return(defaultBitDecomposition); }
/// <summary> /// Constructor. Takes as input an integer, creates a Pedersen Commitment to it, and generates /// a sequence of Pedersen Commitments to its bit decomposition. /// </summary> /// <param name="integer">Creates a Pedersen Commitment to this value.</param> /// <param name="decompositionLength">Minimum number of integers in the decomposition.</param> /// <param name="crypto">Cryptographic parameters.</param> /// <param name="hideCommittedValue">Decomposed integer is secret.</param> public ProverBitDecompositionParameters(FieldZqElement integer, int decompositionLength, CryptoParameters crypto, bool hideCommittedValue = true) : base(crypto) { BitArray bits = VerifierBitDecompositionParameters.GetBitDecomposition(integer, decompositionLength, this.FieldZq); PedersenCommitment[] openCommittedBits = new PedersenCommitment[bits.Length]; PedersenCommitment openCommitment; if (hideCommittedValue) { for (int i = 0; i < bits.Length; ++i) { FieldZqElement curBit = this.FieldZq.Zero; if (bits.Get(i)) { curBit = this.FieldZq.One; } openCommittedBits[i] = new PedersenCommitment(curBit, this); } openCommitment = new PedersenCommitment(integer, this); } else { for (int i = 0; i < bits.Length; ++i) { FieldZqElement curBit = this.FieldZq.Zero; if (bits.Get(i)) { curBit = this.FieldZq.One; } openCommittedBits[i] = new PedersenCommitment(this.G, this.H, curBit, this.FieldZq.Zero, this.Group); } openCommitment = new PedersenCommitment(this.G, this.H, integer, this.FieldZq.Zero, this.Group); } this.setProverParameters(openCommittedBits, openCommitment); }
/// <summary> /// Sets verifier parameters for situations when the committed value is known /// to the verifier. Computes the bit decomposition for committedValue /// ClosedCommittment = G^committedValue /// ClosedCommittedBit[i] = G^bit[i] /// </summary> /// <param name="committedValue">Committed value.</param> /// <param name="decompositionLength">Minimum bit decomposition length.</param> public void setVerifierParameters(FieldZqElement committedValue, int decompositionLength) { if (committedValue == null) { base.setVerifierParameters(null); return; } BitArray commitedBits = VerifierBitDecompositionParameters.GetBitDecomposition(committedValue, decompositionLength, this.FieldZq); GroupElement[] publicValues = new GroupElement[commitedBits.Length + 1]; for (int i = 0; i < commitedBits.Length; ++i) { if (!commitedBits.Get(i)) { publicValues[i] = this.Group.Identity; } else { publicValues[i] = this.G; } } publicValues[publicValues.Length - 1] = this.G.Exponentiate(committedValue); this.setVerifierParameters(publicValues); }
/// <summary> /// Verifies that the ProverRangeProofParameters are valid. /// </summary> /// <returns>True if parameters are valid.</returns> new public bool Verify() { if (!base.Verify()) { return(false); } // check that they're in range BitArray maxValueBits = VerifierBitDecompositionParameters.GetBitDecomposition(this.GetRangeNormalizedFieldZqElement(this.MaxValue), 0, this.FieldZq); int decompositionLength = maxValueBits.Length; BitArray minValueBits = VerifierBitDecompositionParameters.GetBitDecomposition(this.GetRangeNormalizedFieldZqElement(this.MinValue), decompositionLength, this.FieldZq); // check integer A and integer B exist if (this.OpenIntegerA == null) { return(false); } BitArray bitA = VerifierBitDecompositionParameters.GetBitDecomposition(this.RangeNormalizedOpenIntegerA.ExponentAtIndex(0), decompositionLength, this.FieldZq); BitArray bitB; if (this.IntegerBIsKnown) { bitB = VerifierBitDecompositionParameters.GetBitDecomposition(this.GetRangeNormalizedFieldZqElement(this.IntegerB), decompositionLength, this.FieldZq); } else { if (this.OpenIntegerB == null) { return(false); } bitB = VerifierBitDecompositionParameters.GetBitDecomposition(this.RangeNormalizedOpenIntegerB.ExponentAtIndex(0), decompositionLength, this.FieldZq); } // make sure integerA and integerB are in range. if ((Compare(bitA, minValueBits) < 0) || (Compare(bitA, maxValueBits) > 0) || (Compare(bitB, minValueBits) < 0) || (Compare(bitB, maxValueBits) > 0)) { return(false); } // now compare integerA and integerB based on range proof type. switch (this.RangeProofType) { case VerifierRangeProofParameters.ProofType.GREATER_THAN: if (Compare(bitA, bitB) <= 0) { return(false); } break; case VerifierRangeProofParameters.ProofType.GREATER_THAN_OR_EQUAL_TO: if (Compare(bitA, bitB) < 0) { return(false); } break; case VerifierRangeProofParameters.ProofType.LESS_THAN: if (Compare(bitA, bitB) >= 0) { return(false); } break; case VerifierRangeProofParameters.ProofType.LESS_THAN_OR_EQUAL_TO: if (Compare(bitA, bitB) > 0) { return(false); } break; } return(true); }