/// <summary> /// Constructs a new <code>IssuerSetupParameters</code> instance. /// </summary> public IssuerSetupParameters() { ip = new IssuerParameters(); // set the defaults ip.UidH = "SHA-256"; GroupConstruction = GroupType.Subgroup; }
public static PresentationProof Generate(IssuerParameters ip, int[] disclosed, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes) { GroupElement gs = null; FieldZqElement[] unused; return(Generate(ip, disclosed, null, 0, gs, message, messageD, deviceContext, upkt, attributes, null, out unused)); }
/// <summary> /// Computes the value x_i. /// A field element is computed from an attribute value /// </summary> /// <param name="ip"> The issuer paramters</param> /// <param name="i"> The index of the attribute</param> /// <param name="A"> An array contianing the attributes</param> /// <returns></returns> public static FieldZqElement ComputeXi(IssuerParameters ip, int i, byte[] A) { FieldZqElement xi; if (ip.E[i] == 0x01) // hash { if (A == null) { xi = ip.Zq.Zero; } else { HashFunction hash = ip.HashFunction; hash.Hash(A); xi = ip.Zq.GetElementFromDigest(hash.Digest); } } else if (ip.E[i] == 0x00) // do not hash { if (A == null) { throw new ArgumentNullException("A", "A can't be null when ip.E[i] == 0x00"); } else { xi = ip.Zq.GetElement(A); } } else { throw new ArgumentException("invalid E[" + i + "] value"); } return(xi); }
void IParametrizedDeserialization.FinishDeserialization(IssuerParameters ip) { try { if (!this.deserializationStarted) { throw new SerializationException("deserialization not started"); } AlphaInverse = _alphaInverse.ToFieldElementArray(ip.Zq); Beta2 = _beta2.ToFieldElementArray(ip.Zq); H = _h.ToGroupElementArray(ip.Gq); SigmaZPrime = _sigmaZPrime.ToGroupElementArray(ip.Gq); SigmaAPrime = _sigmaAPrime.ToGroupElementArray(ip.Gq); SigmaBPrime = _sigmaBPrime.ToGroupElementArray(ip.Gq); SigmaCPrime = _sigmaCPrime.ToFieldElementArray(ip.Zq); Validate(); } catch { throw; } finally { this.deserializationStarted = false; } }
/// <summary> /// Constructs a <code>VerifierPresentationProtocolParameters</code> instance. /// </summary> /// <param name="ip">The issuer parameters.</param> /// <param name="disclosed">Disclosed attribute indices.</param> /// <param name="message">Presentation message.</param> /// <param name="token">Presented token.</param> public VerifierPresentationProtocolParameters(IssuerParameters ip, int[] disclosed, byte[] message, UProveToken token) { IP = ip; Disclosed = disclosed; Message = message; Token = token; }
/// <summary> /// Constructs a new <code>Prover</code> instance. /// </summary> /// <param name="ip">The Issuer parameters.</param> /// <param name="psms">The post second message state.</param> public Prover(IssuerParameters ip, PostSecondMessageState psms) { psms.Validate(); this.ip = ip; this.numberOfTokens = psms.AlphaInverse.Length; this.TI = psms.TI; this.PI = psms.PI; this.isDeviceProtected = psms.IsDeviceProtected; this.beta2 = psms.Beta2; this.h = psms.H; this.sigmaZPrime = psms.SigmaZPrime; this.sigmaAPrime = psms.SigmaAPrime; this.sigmaBPrime = psms.SigmaBPrime; this.sigmaCPrime = psms.SigmaCPrime; ukat = new UProveKeyAndToken[numberOfTokens]; for (int i = 0; i < numberOfTokens; i++) { ukat[i] = new UProveKeyAndToken(); ukat[i].PrivateKey = psms.AlphaInverse[i]; } state = State.Second; }
/// <summary> /// Verifies a U-Prove token signature. /// </summary> /// <param name="ip">The Issuer parameters corresponding to the U-Prove token.</param> /// <param name="upt">The U-Prove token to verify.</param> /// <exception cref="InvalidUProveArtifactException">If the U-Prove token is invalid.</exception> public static void VerifyTokenSignature(IssuerParameters ip, UProveToken upt) { Group Gq = ip.Gq; FieldZq Zq = ip.Zq; if (upt.H == Gq.Identity) { throw new InvalidUProveArtifactException("Invalid U-Prove token (public key H = 1)"); } GroupElement[] bases = new GroupElement[2]; FieldZqElement[] exponents = new FieldZqElement[2]; HashFunction hash = ip.HashFunction; hash.Hash(upt.H); hash.Hash(upt.PI); hash.Hash(upt.SigmaZPrime); bases[0] = Gq.G; exponents[0] = upt.SigmaRPrime; bases[1] = ip.G[0]; exponents[1] = upt.SigmaCPrime.Negate(); hash.Hash(Gq.MultiExponentiate(bases, exponents)); bases[0] = upt.H; exponents[0] = upt.SigmaRPrime; bases[1] = upt.SigmaZPrime; exponents[1] = upt.SigmaCPrime.Negate(); hash.Hash(Gq.MultiExponentiate(bases, exponents)); if (upt.SigmaCPrime != Zq.GetElementFromDigest(hash.Digest)) { throw new InvalidUProveArtifactException("Invalid U-Prove token signature"); } }
void IParametrizedDeserialization.FinishDeserialization(IssuerParameters ip) { try { if (!this.deserializationStarted) { throw new SerializationException("deserialization not started"); } h0 = _h0.ToGroupElement(ip); CGamma = _CGamma.ToGroupElement(ip); Ch0 = _Ch0.ToGroupElement(ip); if (_responses_values.Length != _responses_keys.Length) { throw new UProveSerializationException("number of response keys does not match number of response values"); } responses = new Dictionary <string, FieldZqElement>(); for (int i = 0; i < _responses_keys.Length; i++) { responses.Add(_responses_keys[i], _responses_values[i].ToFieldElement(ip)); } if (presentation != null) { (presentation as IParametrizedDeserialization).FinishDeserialization(ip); } } catch { throw; } finally { this.deserializationStarted = false; } }
// Private helper function private static byte[] ComputeChallenge(IssuerParameters ip, GroupElement h0, GroupElement CGamma, GroupElement Ch0, GroupElement[] C, GroupElement tildeD, GroupElement tildeCgamma, GroupElement tildeT, GroupElement[] tildeC, byte[] message) { HashFunction H = ip.HashFunction; H.Hash(ip.Digest(false)); H.Hash(h0); H.Hash(CGamma); H.Hash(Ch0); H.Hash(C); H.Hash(tildeD); H.Hash(tildeCgamma); H.Hash(tildeT); H.Hash(tildeC); H.Hash(message); byte[] digest = H.Digest; #if DEBUG Debug.WriteLine("h0 = " + BitConverter.ToString(h0.GetEncoded())); Debug.WriteLine("CGamma = " + BitConverter.ToString(CGamma.GetEncoded())); Debug.WriteLine("Ch0 = " + BitConverter.ToString(Ch0.GetEncoded())); if (tildeC != null) { Debug.WriteLine("tildeC[0] = " + BitConverter.ToString(tildeC[0].GetEncoded())); } Debug.WriteLine("tildeD = " + BitConverter.ToString(tildeD.GetEncoded())); Debug.WriteLine("tildeT = " + BitConverter.ToString(tildeT.GetEncoded())); Debug.WriteLine("tildeCgamma = " + BitConverter.ToString(tildeCgamma.GetEncoded())); Debug.WriteLine("digest = " + BitConverter.ToString(digest)); #endif return(digest); }
/// <summary> /// Constructs a new <code>Prover</code> instance. /// </summary> /// <param name="ip">The Issuer parameters.</param> /// <param name="numberOfTokens">Number of tokens to issue.</param> /// <param name="gamma">The gamma value encoding the token attributes.</param> /// <param name="TI">The token information field value.</param> /// <param name="PI">The Prover information field value.</param> /// <param name="preGeneratedRandomData">Optional pregenerated ProverRandomData instance.</param> /// <param name="isDeviceProtected">True if the token is to be device-protected, false otherwise.</param> /// <param name="batchValidationSecurityLevel">The security level of the batch token signature validation. Given a security level <code>l</code>, /// the probability for the Prover to accept an invalid token is <code>2^-l</code>. If set to 0, than /// regular validation is used. A value of 20 is recommended.</param> internal Prover(IssuerParameters ip, int numberOfTokens, GroupElement gamma, byte[] TI, byte[] PI, ProverRandomData preGeneratedRandomData, bool isDeviceProtected, ushort batchValidationSecurityLevel) { if (ip == null) { throw new ArgumentNullException("ip"); } this.ip = ip; if (numberOfTokens <= 0) { throw new ArgumentException("numberOfTokens must be greater than 0"); } this.numberOfTokens = numberOfTokens; this.TI = TI; this.PI = PI; if (preGeneratedRandomData != null && (preGeneratedRandomData.Alpha.Length != numberOfTokens || preGeneratedRandomData.Beta1.Length != numberOfTokens || preGeneratedRandomData.Beta2.Length != numberOfTokens)) { throw new ArgumentException("invalid preGeneratedRandomData"); } this.isDeviceProtected = isDeviceProtected; this.batchValidationSecurityLevel = batchValidationSecurityLevel; this.gamma = gamma; Precompute(gamma, preGeneratedRandomData); }
private void Precompute(GroupElement gamma, FieldZqElement[] preGenW) { IssuerParameters ip = ikap.IssuerParameters; Group Gq = ip.Gq; FieldZq Zq = ip.Zq; sigmaZ = gamma.Exponentiate(ikap.PrivateKey); if (preGenW == null) { w = Zq.GetRandomElements(numberOfTokens, false); } else { w = preGenW; } sigmaA = new GroupElement[numberOfTokens]; sigmaB = new GroupElement[numberOfTokens]; for (int i = 0; i < numberOfTokens; i++) { sigmaA[i] = Gq.G.Exponentiate(w[i]); sigmaB[i] = gamma.Exponentiate(w[i]); } state = State.Initialized; }
public static PresentationProof Generate(IssuerParameters ip, int[] disclosed, int[] committed, int pseudonymAttribIndex, GroupElement gs, byte[] message, byte[] messageD, IDevicePresentationContext deviceContext, UProveKeyAndToken upkt, byte[][] attributes, ProofGenerationRandomData preGenW, out FieldZqElement[] tildeO) { CommitmentPrivateValues cpv; PresentationProof proof = Generate(ip, disclosed, committed, pseudonymAttribIndex, gs, message, messageD, deviceContext, upkt, attributes, preGenW, out cpv); tildeO = cpv.TildeO; return(proof); }
/// <summary> /// Constructs a <code>ProverPresentationProtocolParameters</code> instance. /// </summary> /// <param name="ip">The issuer parameters.</param> /// <param name="disclosed">Disclosed attribute indices.</param> /// <param name="message">Presentation message.</param> /// <param name="keyAndToken">Presented key and token.</param> /// <param name="attributes">Token attributes.</param> public ProverPresentationProtocolParameters(IssuerParameters ip, int[] disclosed, byte[] message, UProveKeyAndToken keyAndToken, byte[][] attributes) { IP = ip; Disclosed = disclosed; Message = message; KeyAndToken = keyAndToken; Attributes = attributes; }
/// <summary> /// Generates the Issuer parameters cryptographic data, <code>ip</code> will be updated with the cryptographic data. /// </summary> /// <param name="ip">An instanciated Issuer parameters; the Gq and E properties must be set.</param> /// <param name="gValues">The issuer generators to use, or null.</param> /// <param name="supportDevice">Indicates if the device generator must be generated.</param> /// <returns>The Issuer parameters private key.</returns> internal static FieldZqElement GenerateIssuerParametersCryptoData(IssuerParameters ip, GroupElement[] gValues, bool supportDevice) { if (ip == null) { throw new ArgumentNullException("ip"); } if (ip.Gq == null) { throw new ArgumentException("Group description is not set"); } //int n = ip.E == null ? 0 : ip.E.Length; // extension by Fablei int n = ip.MaxNumberOfAttributes; Group Gq = ip.Gq; ip.G = new GroupElement[n + 2]; FieldZqElement privateKey; if (gValues == null) { FieldZqElement[] y = ip.Zq.GetRandomElements(n + 2, false); privateKey = y[0]; for (int i = 0; i < (n + 2); i++) { ip.G[i] = Gq.G.Exponentiate(y[i]); } } else { // g_0 privateKey = ip.Zq.GetRandomElement(false); ip.G[0] = Gq.G.Exponentiate(privateKey); // g_1,..,g_n for (int i = 1; i < (n + 1); i++) { ip.G[i] = gValues[i - 1]; } // g_t int t = n + 1; ip.G[t] = gValues[gValues.Length - 1]; } if (supportDevice) { if (ip.Gd == null) { ip.Gd = Gq.G.Exponentiate(ip.Zq.GetRandomElement(false)); } } return(privateKey); }
internal static FieldZqElement ComputeXt(IssuerParameters ip, byte[] TI, bool supportDevice) { HashFunction hash = ip.HashFunction; hash.Hash((byte)1); hash.Hash(ip.Digest(supportDevice)); hash.Hash(TI); return(ip.Zq.GetElementFromDigest(hash.Digest)); }
/// <summary> /// Constructs new issuance protocol parameters for the Prover. /// </summary> /// <param name="ip">The Issuer parameters.</param> public ProverProtocolParameters(IssuerParameters ip) { if (ip == null) { throw new ArgumentNullException("ip"); } IssuerParameters = ip; BatchValidationSecurityLevel = 0; // defaults to normal validation }
/// <summary> /// Computes the U-Prove token identifier. /// </summary> /// <param name="ip">The issuer parameters associated with <code>upt</code>.</param> /// <param name="upt">The U-Prove token from which to compute the identifier.</param> /// <returns></returns> public static byte[] ComputeTokenID(IssuerParameters ip, UProveToken upt) { HashFunction hash = ip.HashFunction; hash.Hash(upt.H); hash.Hash(upt.SigmaZPrime); hash.Hash(upt.SigmaCPrime); hash.Hash(upt.SigmaRPrime); return(hash.Digest); }
internal static FieldZqElement GenerateChallenge(IssuerParameters ip, UProveToken upt, byte[] a, int pseudonymIndex, byte[] ap, GroupElement Ps, byte[] m, byte[] md, int[] disclosed, FieldZqElement[] disclosedX, int[] committed, CommitmentValues[] commitments, out byte[] mdPrime) { bool hasCommitments = (committed != null && committed.Length > 0); if (hasCommitments) { if (committed.Length != commitments.Length) { throw new ArgumentException("Inconsistent committed indices and commitment values"); } } HashFunction hash = ip.HashFunction; hash.Hash(ComputeTokenID(ip, upt)); hash.Hash(a); hash.Hash(disclosed); hash.Hash(disclosedX); if (!hasCommitments) { hash.HashNull(); // C hash.HashNull(); // < {tildeC} > hash.HashNull(); // < {tildeA} > } else { hash.Hash(committed); hash.Hash(commitments.Length); // length of < {tildeC} > for (int i = 0; i < commitments.Length; i++) { hash.Hash(commitments[i].TildeC); } hash.Hash(commitments.Length); // length of < {tildeA} > for (int i = 0; i < commitments.Length; i++) { hash.Hash(commitments[i].TildeA); } } hash.Hash(pseudonymIndex == PresentationProof.DeviceAttributeIndex ? 0 : pseudonymIndex); hash.Hash(ap); hash.Hash(Ps); hash.Hash(m); mdPrime = hash.Digest; if (upt.IsDeviceProtected) { hash = ip.HashFunction; hash.Hash(md); hash.Hash(mdPrime); return(ip.Zq.GetElementFromDigest(hash.Digest)); } else { return(ip.Zq.GetElementFromDigest(mdPrime)); } }
/// <summary> /// Constructs a new <code>IssuerSetupParameters</code> instance. /// </summary> /// <param name="maxNumberOfAttributes">maximum number of attributes, the issuer will be able to include into an issued token - extension by Fablei</param> public IssuerSetupParameters(int maxNumberOfAttributes) { ip = new IssuerParameters(maxNumberOfAttributes); // extension by Fablei MaxNumberOfAttributes = maxNumberOfAttributes; // set the defaults ip.UidH = "SHA-256"; GroupConstruction = GroupType.ECC; }
/// <summary> /// Convert a base64 string to a GroupElement using Gq from an IssuerParameters object. /// </summary> /// <param name="encodedString">The encoded string to convert.</param> /// <param name="issuerParameters">The issuer parameters object to use for conversion.</param> /// <returns>The converted object.</returns> public static GroupElement ToGroupElement(this String encodedString, IssuerParameters issuerParameters) { if (encodedString == null) { return(null); } if (issuerParameters == null) { throw new ArgumentNullException("issuerParameters"); } return(issuerParameters.Gq.CreateGroupElement(encodedString.ToByteArray())); }
/// <summary> /// Convert a base64 string to a FieldElement using FieldZq from a particular IssuerParameters object. /// </summary> /// <param name="encodedString">The encoded string to convert.</param> /// <param name="issuerParameters">The IssuerParameters object.</param> /// <returns>The converted object.</returns> public static FieldZqElement ToFieldElement(this String encodedString, IssuerParameters issuerParameters) { if (encodedString == null) { return(null); } if (issuerParameters == null) { throw new ArgumentNullException("issuerParameters"); } return(issuerParameters.Zq.GetElement(Convert.FromBase64String(encodedString))); }
/// <summary> /// Constructs an IssuerKeyAndParameters instance. /// </summary> /// <param name="privateKey">The private key.</param> /// <param name="issuerParameters">The Issuer parameters.</param> public IssuerKeyAndParameters(FieldZqElement privateKey, IssuerParameters issuerParameters) { if (privateKey == null) { throw new ArgumentNullException("privateKey"); } if (issuerParameters == null) { throw new ArgumentNullException("issuerParameters"); } this.privateKey = privateKey; this.issuerParameters = issuerParameters; }
internal void OnDeserialized(StreamingContext context) { if (_issuerParameters == null) { throw new UProveSerializationException("ip"); } if (_privateKey == null) { throw new UProveSerializationException("key"); } this.issuerParameters = _issuerParameters; this.privateKey = _privateKey.ToFieldElement(this.issuerParameters); }
void IParametrizedDeserialization.FinishDeserialization(IssuerParameters ip) { try { if (!this.deserializationStarted) { throw new SerializationException("deserialization not started"); } bool hasCommitments = false; if (_ta != null || _tc != null || _tr != null) { if (_ta == null || _tc == null || _tr == null || _ta.Length != _tc.Length || _ta.Length != _tr.Length) { throw new UProveSerializationException("Inconsistent commitment values"); } hasCommitments = true; } this.R = new FieldZqElement[_r.Length]; for (int i = 0; i < _r.Length; i++) { this.R[i] = _r[i].ToFieldZqElement(ip.Zq); } if (_ps != null) { this.Ps = _ps.ToGroupElement(ip); } if (hasCommitments) { this.Commitments = new CommitmentValues[_tc.Length]; for (int i = 0; i < _tc.Length; i++) { this.Commitments[i] = new CommitmentValues( _tc[i].ToGroupElement(ip), _ta[i].ToByteArray(), _tr[i].ToFieldElement(ip)); } } } catch { throw; } finally { this.deserializationStarted = false; } }
/// <summary> /// Constructs an Issuer parameters instance from a serialized string /// </summary> public IssuerParameters(string serializedIssuerParameters) { IssuerParameters.serializer = new Serializer(); IssuerParameters issuerParameters = this.Deserialize <IssuerParameters>(serializedIssuerParameters); this.uidp = issuerParameters.uidp; this.group = issuerParameters.group; this.uidh = issuerParameters.uidh; this.g = issuerParameters.g; this.gd = issuerParameters.gd; this.e = issuerParameters.e; this.s = issuerParameters.s; this.usesRecommendedParameters = issuerParameters.usesRecommendedParameters; }
/// <summary> /// Constructs an Issuer parameters instance from a serialized string /// </summary> public IssuerParameters(string serializedIssuerParameters) { IssuerParameters.serializer = new Serializer(); IssuerParameters issuerParameters = this.Deserialize <IssuerParameters>(serializedIssuerParameters); this.uidp = issuerParameters.uidp; this.group = issuerParameters.group; this.uidh = issuerParameters.uidh; this.g = issuerParameters.g; this.gd = issuerParameters.gd; this.e = issuerParameters.e; this.s = issuerParameters.s; this.usesRecommendedParameters = issuerParameters.usesRecommendedParameters; // extension by Fablei MaxNumberOfAttributes = issuerParameters.MaxNumberOfAttributes; }
void IParametrizedDeserialization.FinishDeserialization(IssuerParameters ip) { try { if (!this.deserializationStarted) { throw new SerializationException("deserialization not started"); } this.sigmaR = _sigmaR.ToFieldElementArray(ip.Zq); } catch { throw; } finally { this.deserializationStarted = false; } }
/// <summary> /// Computes the value <c>gamma</c>, an input to the issuance protocol. /// </summary> /// <param name="ip">The issuer parameters</param> /// <param name="A"> The attribute values, or null if the token contains no attributes </param> /// <param name="TI">The token information field</param> /// <param name="hd">The device public key, or <c>null</c> if device binding is not supported by the issuer paramters.</param> /// <returns>The group element gamma </returns> public static GroupElement ComputeIssuanceInput(IssuerParameters ip, byte[][] A, byte[] TI, GroupElement hd) { if (ip == null) { throw new ArgumentNullException("Issuer parameters are null"); } int n = 0; bool supportDevice = (hd != null); if (supportDevice && !ip.IsDeviceSupported) { throw new InvalidOperationException("Issuer parameters does not support devices"); } if (A != null) { n = A.Length; } Group Gq = ip.Gq; GroupElement[] bases = new GroupElement[n + 1]; FieldZqElement[] exponents = new FieldZqElement[n + 1]; for (int i = 0; i < n; i++) { FieldZqElement xi = ComputeXi(ip, i, A[i]); bases[i] = ip.G[i + 1]; exponents[i] = xi; } FieldZqElement xt = ComputeXt(ip, TI, supportDevice); bases[n] = ip.G[n + 1]; exponents[n] = xt; GroupElement gamma = ip.G[0] * Gq.MultiExponentiate(bases, exponents); // Multiply-in the device public key for device-protected tokens if (supportDevice) { gamma = gamma * hd; } return(gamma); }
/// <summary> /// Indicates that attributes are carried over from the source token into the new one. /// </summary> /// <param name="sourceIndex">The indices of the attributes in the existing token.</param> /// <param name="destinationIndex">The indices of the attributes in the new token.</param> /// /// <param name="sourceIP">The Issuer Parameters used to issue the source token. This can be the same as <c>Ip</c> if the /// same Issuer issues the source and new tokens.</param> /// <param name="sourceToken">The source token.</param> public void CarryOverAttribute(int[] sourceIndex, int[] destinationIndex, IssuerParameters sourceIP, UProveToken sourceToken) { if (sourceIndex == null || destinationIndex == null || sourceIP == null || sourceToken == null) { throw new ArgumentNullException("arguments can't be null"); } if (sourceIndex.Length != destinationIndex.Length) { throw new ArgumentException("sourceIndex and destinationIndex must have the same lenght"); } if (!sourceToken.Uidp.SequenceEqual <byte>(sourceIP.UidP)) { throw new ArgumentException("sourceToken and sourceIP do not match"); } C = destinationIndex; Corig = sourceIndex; SourceIP = sourceIP; Tokens = sourceToken; HasCarryOverAttributes = true; }
void IParametrizedDeserialization.FinishDeserialization(IssuerParameters ip) { try { if (!this.deserializationStarted) { throw new SerializationException("deserialization not started"); } this.PrivateKey = _key.ToFieldZqElement(ip.Zq); (this.Token as IParametrizedDeserialization).FinishDeserialization(ip); } catch { throw; } finally { this.deserializationStarted = false; } }