/** * check whether the issuer public key is correct * * @return true iff valid */ public bool Check() { // check formalities of IdemixIssuerPublicKey if (AttributeNames == null || Hsk == null || HRand == null || HAttrs == null || BarG1 == null || BarG1.IsInfinity() || BarG2 == null || HAttrs.Length < AttributeNames.Length) { return(false); } for (int i = 0; i < AttributeNames.Length; i++) { if (HAttrs[i] == null) { return(false); } } // check proofs ECP2 t1 = IdemixUtils.GenG2.Mul(ProofS); ECP t2 = BarG1.Mul(ProofS); t1.Add(W.Mul(BIG.ModNeg(ProofC, IdemixUtils.GROUP_ORDER))); t2.Add(BarG2.Mul(BIG.ModNeg(ProofC, IdemixUtils.GROUP_ORDER))); // Generating proofData that will contain 3 elements in G1 (of size 2*FIELD_BYTES+1)and 3 elements in G2 (of size 4 * FIELD_BYTES) byte[] proofData = new byte[0]; proofData = proofData.Append(t1.ToBytes()); proofData = proofData.Append(t2.ToBytes()); proofData = proofData.Append(IdemixUtils.GenG2.ToBytes()); proofData = proofData.Append(BarG1.ToBytes()); proofData = proofData.Append(W.ToBytes()); proofData = proofData.Append(BarG2.ToBytes()); // Hash proofData to hproofdata and compare with proofC return(Enumerable.SequenceEqual(proofData.HashModOrder().ToBytes(), ProofC.ToBytes())); }
/** * Constructor * * @param attributeNames the names of attributes as String array (must not contain duplicates) * @param isk the issuer secret key */ public IdemixIssuerPublicKey(string[] attributeNames, BIG isk) { // check null input if (attributeNames == null || isk == null) { throw new ArgumentException("Cannot create IdemixIssuerPublicKey from null input"); } // Checking if attribute names are unique HashSet <string> map = new HashSet <string>(); foreach (string item in attributeNames) { if (map.Contains(item)) { throw new ArgumentException("Attribute " + item + " appears multiple times in attributeNames"); } map.Add(item); } RAND rng = IdemixUtils.GetRand(); // Attaching Attribute Names array correctly AttributeNames = attributeNames; // Computing W value W = IdemixUtils.GenG2.Mul(isk); // Filling up HAttributes correctly in Issuer Public Key, length // preserving HAttrs = new ECP[attributeNames.Length]; for (int i = 0; i < attributeNames.Length; i++) { HAttrs[i] = IdemixUtils.GenG1.Mul(rng.RandModOrder()); } // Generating Hsk value Hsk = IdemixUtils.GenG1.Mul(rng.RandModOrder()); // Generating HRand value HRand = IdemixUtils.GenG1.Mul(rng.RandModOrder()); // Generating BarG1 value BarG1 = IdemixUtils.GenG1.Mul(rng.RandModOrder()); // Generating BarG2 value BarG2 = BarG1.Mul(isk); // Zero Knowledge Proofs // Computing t1 and t2 values with random local variable r for later use BIG r = rng.RandModOrder(); ECP2 t1 = IdemixUtils.GenG2.Mul(r); ECP t2 = BarG1.Mul(r); // Generating proofData that will contain 3 elements in G1 (of size 2*FIELD_BYTES+1)and 3 elements in G2 (of size 4 * FIELD_BYTES) byte[] proofData = new byte[0]; proofData = proofData.Append(t1.ToBytes()); proofData = proofData.Append(t2.ToBytes()); proofData = proofData.Append(IdemixUtils.GenG2.ToBytes()); proofData = proofData.Append(BarG1.ToBytes()); proofData = proofData.Append(W.ToBytes()); proofData = proofData.Append(BarG2.ToBytes()); // Hashing proofData to proofC ProofC = proofData.HashModOrder(); // Computing ProofS = (ProofC*isk) + r mod GROUP_ORDER ProofS = BIG.ModMul(ProofC, isk, IdemixUtils.GROUP_ORDER).Plus(r); ProofS.Mod(IdemixUtils.GROUP_ORDER); // Compute Hash of IdemixIssuerPublicKey byte[] serializedIpk = ToProto().ToByteArray(); Hash = serializedIpk.HashModOrder().ToBytes(); }