in UProveCrypto/CollaborativeIssuance.cs [316:440]
public static PreIssuanceProof CreateProof(ProverPreIssuanceParameters pipp, out FieldZqElement beta0, byte[] message)
{
// validate paramters first
pipp.Validate();
bool supportDevice = (pipp.DevicePublicKey == null) ? false : true;
IssuerParameters ip = pipp.IP;
FieldZq Zq = ip.Zq;
Group Gq = ip.Gq;
Dictionary<string, FieldZqElement> responses = new Dictionary<string, FieldZqElement>();
// these will be used if there is a carry-over attribute
CommitmentPrivateValues cpv = null;
PresentationProof presProof = null;
GroupElement[] C = null;
GroupElement[] tildeC = null;
FieldZqElement[] tildeR = null;
// Generate random values
beta0 = Zq.GetRandomElement(true);
FieldZqElement tildeBeta0 = Zq.GetRandomElement(true);
FieldZqElement rho = Zq.GetRandomElement(true);
FieldZqElement tildeRho = Zq.GetRandomElement(true);
FieldZqElement tilde_d = Zq.GetRandomElement(true);
FieldZqElement[] tildeX = new FieldZqElement[ip.G.Length - 1];
for (int i = 1; i < ip.G.Length - 1; i++)
{
if (!pipp.K.Contains(i))
{
tildeX[i] = Zq.GetRandomElement(true);
}
}
// Compute the U-Prove presentation proof, if there are carry-over attributes
if(pipp.HasCarryOverAttributes)
{
// generate the presentation proof
int[] disclosed = new int[] { };
ProverPresentationProtocolParameters pppp = new ProverPresentationProtocolParameters(pipp.SourceIP, disclosed, message, pipp.KeyAndToken, pipp.SourceAttributes);
pppp.Committed = pipp.Corig;
// TODO: What if the source token is device protected? need to handle this as well. (a pointer to the device should be included in pipp
//if (device != null)
//{
// pppp.SetDeviceData(deviceMessage, device.GetPresentationContext());
//}-
// For now just fail:
if (pipp.KeyAndToken.Token.IsDeviceProtected)
{
throw new NotImplementedException("Device protected tokens may not be used for carry-over attributes");
}
presProof = PresentationProof.Generate(pppp, out cpv);
//set C
C = new GroupElement[pipp.C.Length];
// Generate random values for the commitment randomizers
tildeR = Zq.GetRandomElements(pipp.C.Length, true);
tildeC = new GroupElement[C.Length];
for (int i = 0; i < C.Length; i++)
{
C[i] = presProof.Commitments[i].TildeC;
tildeC[i] = Gq.MultiExponentiate(Gq.G, ip.G[1], tildeX[pipp.C[i]], tildeR[i]);
}
} // end if cary-over attributes
// Compute gamma
GroupElement gamma = ProtocolHelper.ComputeIssuanceInput(ip, pipp.Attributes, pipp.TI, pipp.DevicePublicKey);
// Compute h0, Cgamma, Ch0, tildeD, tildeT:
GroupElement h0 = gamma.Exponentiate(beta0);
GroupElement Cgamma = gamma.Multiply(Gq.G.Exponentiate(rho)); // Cgamma = gamma*(g^rho)
GroupElement Ch0 = Cgamma.Exponentiate(beta0);
GroupElement tildeD = Gq.G.Exponentiate(tilde_d);
GroupElement tildeT = Cgamma.Exponentiate(tildeBeta0);
// Compute tildeCgamma:
List<GroupElement> bases = new List<GroupElement>();
List<FieldZqElement> exponents = new List<FieldZqElement>();
bases.Add(Gq.G);
exponents.Add(tildeRho);
for (int i = 1; i < ip.G.Length-1; i++)
{
if (!pipp.K.Contains(i)) // i \not\in K
{
bases.Add(ip.G[i]);
exponents.Add(tildeX[i]);
}
}
GroupElement tildeCgamma = Gq.MultiExponentiate(bases.ToArray(), exponents.ToArray());
// TODO: if device protected, then multiply tildeCgamma by the public key
// Note: We leave TI out, (i.e., (g_t)^(x_t) because t \in K implicitly.
// Compute the challenge
byte[] c = ComputeChallenge(ip, h0, Cgamma, Ch0, C, tildeD, tildeCgamma, tildeT, tildeC, message);
FieldZqElement negc = Zq.GetElementFromDigest(c).Negate();
// Compute the responses
responses.Add("sBeta0", tildeBeta0.Add(beta0.Multiply(negc))); // sBeta0 = tildeBeta0 - beta0*c
responses.Add("sD", tilde_d.Add(beta0.Multiply(rho).Multiply(negc))); // sD = tilde_d - beta0*rho*c
responses.Add("sRho", tildeRho.Add(rho.Multiply(negc))); // sRho = tildeRho - rho*c
for (int i = 1; i < ip.G.Length-1; i++)
{
if (!pipp.K.Contains(i)) // in \not\in K
{
FieldZqElement xi = ProtocolHelper.ComputeXi(ip, i-1, pipp.Attributes[i-1]);
responses.Add("sx" + i, tildeX[i].Add(xi.Multiply(negc))); // sxi = tildeX[i] - xi*c
}
}
if (pipp.HasCarryOverAttributes)
{
for (int i = 0; i < C.Length; i++)
{
responses.Add("sR"+i, tildeR[i].Add(cpv.TildeO[i].Multiply(negc))); // sRi = tildeR[i] - tildeO[i]*c
}
}
return new PreIssuanceProof(h0, Cgamma, Ch0, c, responses,
pipp.HasCarryOverAttributes ? presProof : null);
}