//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the Apache License Version 2.0.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
package com.microsoft.uprove;
import java.io.IOException;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Arrays;
import junit.framework.TestCase;
public class EndToEndTest extends TestCase {
public EndToEndTest(String name) {
super(name);
}
public void testLongRun() throws NoSuchProviderException, NoSuchAlgorithmException, IllegalStateException, IOException, InvalidProofException {
/*
* issuer parameters setup
*/
int numberOfAttribs = 100;
IssuerSetupParameters isp = new IssuerSetupParameters();
byte[] encodingBytes = new byte[numberOfAttribs];
for (int i = 0; i < numberOfAttribs; i++)
{
encodingBytes[i] = (byte) (i%2); // alternate between 0 (direct encoding) and 1 (hash)
}
isp.setEncodingBytes(encodingBytes);
isp.setHashAlgorithmUID("SHA1");
isp.setParametersUID("unique UID".getBytes());
isp.setSpecification("specification".getBytes());
IssuerKeyAndParameters ikap = isp.generate();
IssuerParameters ip = ikap.getIssuerParameters();
ip.validate();
/*
* token issuance
*/
// protocol parameters
byte[][] attributes = new byte[numberOfAttribs][];
attributes[0] = BigInteger.ZERO.toByteArray();
attributes[1] = null;
attributes[2] = BigInteger.ONE.toByteArray();
attributes[3] = "This is a very long value that doesn't fit in one attribute, but this is ok since we hash this value".getBytes();
FieldZq Zq = ip.getGroup().getZq();
for (int index = 4; index < numberOfAttribs; index++)
{
// for the rest, we just encode random Zq values
attributes[index] = Zq.getRandomElement(false).toByteArray();
}
byte[] tokenInformation = new byte[] { };
byte[] proverInformation = new byte[] { };
int numberOfTokens = 250;
// issuer generates first issuance message
IssuerProtocolParameters issuerProtocolParams = new IssuerProtocolParameters();
issuerProtocolParams.setIssuerKeyAndParameters(ikap);
issuerProtocolParams.setNumberOfTokens(numberOfTokens);
issuerProtocolParams.setTokenAttributes(attributes);
issuerProtocolParams.setTokenInformation(tokenInformation);
Issuer issuer = issuerProtocolParams.generate();
byte[][] message1 = issuer.generateFirstMessage();
// prover generates second issuance message
ProverProtocolParameters proverProtocolParams = new ProverProtocolParameters();
proverProtocolParams.setIssuerParameters(ip);
proverProtocolParams.setNumberOfTokens(numberOfTokens);
proverProtocolParams.setTokenAttributes(attributes);
proverProtocolParams.setTokenInformation(tokenInformation);
proverProtocolParams.setProverInformation(proverInformation);
Prover prover = proverProtocolParams.generate();
byte[][] message2 = prover.generateSecondMessage(message1);
// issuer generates third issuance message
byte[][] message3 = issuer.generateThirdMessage(message2);
// prover generates the U-Prove tokens
UProveKeyAndToken[] upkt = prover.generateTokens(message3);
/*
* token presentation
*/
// Presentation
for (int i = 1; i <= numberOfAttribs; i++)
{
// disclose each attribute one by one
int[] disclosed = new int[] { i };
byte[] message = "this is the presentation message, this can be a very long message".getBytes();
// prover chooses a token to use
UProveKeyAndToken keyAndToken = upkt[0];
// prover generates the presentation proof
PresentationProof proof = PresentationProtocol.generatePresentationProof(ip, disclosed, message, null, keyAndToken, attributes);
// prover transmits the U-Prove token and presentation proof to the verifier
UProveToken token = keyAndToken.getToken();
// verifier verifies the presentation proof
PresentationProtocol.verifyPresentationProof(ip, disclosed, message, null, token, proof);
}
}
public void testEndToEnd() throws IOException, InvalidProofException, NoSuchProviderException, NoSuchAlgorithmException {
String[] mdAlgos = new String[]{ "SHA-1", "SHA-256", "SHA-512" };
int attributeLength = 10;
for ( String messageDigestAlg : mdAlgos )
{
for (int numberOfAttribs = 0; numberOfAttribs <= 3; numberOfAttribs++)
{
byte[] E = new byte[numberOfAttribs];
byte[][] attributes = new byte[numberOfAttribs][];
int[] indexesToDisclose = new int[numberOfAttribs];
for (byte e = 0; e <= 1; e++)
{
for (int supportDevice = 0; supportDevice <= 1; supportDevice++)
{
// Issuer setup
IssuerSetupParameters isp = new IssuerSetupParameters();
isp.setParametersUID("unique UID".getBytes());
isp.setHashAlgorithmUID(messageDigestAlg);
Arrays.fill(E, e);
isp.setEncodingBytes(E);
isp.setSpecification("specification".getBytes());
isp.setSupportDevice(supportDevice == 1);
IssuerKeyAndParameters ikap = isp.generate();
IssuerParameters ip = ikap.getIssuerParameters();
ip.validate();
// Device setup
Device device = null;
byte[] deviceZetaParameter = null;
byte[] devicePublicKey = null;
if (supportDevice == 1)
{
DeviceSetupParameters deviceSetupParams = new DeviceSetupParameters();
deviceSetupParams.setIssuerParameters(ip);
device = deviceSetupParams.generate();
int dIndex = ip.getProverIssuanceValues().length-1;
deviceZetaParameter = device.GetDeviceParameter(ip.getProverIssuanceValues()[dIndex]);
devicePublicKey = device.GetDevicePublicKey();
}
// Issuance
for (int index = 0; index < numberOfAttribs; index++)
{
attributes[index] = RandomSource.getRandomBytes( attributeLength );
}
byte[] tokenInformation = "token information".getBytes();
byte[] proverInformation = "prover information".getBytes();
int numberOfTokens = (int)Math.pow(2, numberOfAttribs);
Issuer issuer = new IssuerProtocolParameters( numberOfTokens, ikap, attributes, tokenInformation, devicePublicKey ).generate();
byte[][] msg1 = issuer.generateFirstMessage();
ProverProtocolParameters ppp = new ProverProtocolParameters(numberOfTokens, ip, attributes, tokenInformation, proverInformation);
ppp.setDeviceParameters(devicePublicKey, deviceZetaParameter);
Prover prover = ppp.generate();
byte[][] msg2 = prover.generateSecondMessage(msg1);
byte[][] msg3 = issuer.generateThirdMessage(msg2);
// issue token
UProveKeyAndToken[] upkt = prover.generateTokens(msg3);
// Presentation
for (int i = 0; i < numberOfTokens; i++)
{
int numToDisclose = 0;
for (int index = 0; index < numberOfAttribs; index++)
{
if ((((int)Math.pow(2, index)) & i) != 0)
{
indexesToDisclose[numToDisclose++] = index + 1;
}
}
int[] disclosed = Arrays.copyOf(indexesToDisclose, numToDisclose);
byte[] message = "message".getBytes();
byte[] deviceMessage = "message for Device".getBytes();
if (supportDevice == 1)
{
DeviceManager.RegisterDevice(device);
}
// generate the presentation proof
PresentationProof proof =
PresentationProtocol.generatePresentationProof(ip, disclosed, message, deviceMessage, upkt[i], attributes);
// verify the presentation proof
PresentationProtocol.verifyPresentationProof(ip, disclosed, message, deviceMessage, upkt[i].getToken(), proof);
//
// negative cases
//
if (numberOfAttribs > 0)
{
// modify issuer params (swap g0 and z0);
IssuerParameters ip2 = new IssuerParameters();
ip2.setParametersUID(ip.getParametersUID());
ip2.setEncodingBytes(ip.getEncodingBytes());
ip2.setGroup(ip.getGroup());
ip2.setHashAlgorithmUID(ip.getHashAlgorithmUID());
ip2.setProverIssuanceValues(ip.getProverIssuanceValues());
ip2.setPublicKey(ip.getPublicKey());
ip2.setSpecification("wrong issuer params".getBytes());
try { PresentationProtocol.verifyPresentationProof(ip2, disclosed, message, null, upkt[i].getToken(), proof); fail(); }
catch (InvalidProofException ipe) { }
// modify disclosed list
int[] disclosed2;
if (disclosed.length == 0)
{
disclosed2 = new int[] { 1 };
}
else
{
disclosed2 = new int[] { };
}
try { PresentationProtocol.verifyPresentationProof(ip, disclosed2, message, null, upkt[i].getToken(), proof); fail(); }
catch (InvalidProofException ipe) { }
// modify message
try { PresentationProtocol.verifyPresentationProof(ip, disclosed, "wrong message".getBytes(), null, upkt[i].getToken(), proof); fail(); }
catch (InvalidProofException ipe) { }
// modify token
try { PresentationProtocol.verifyPresentationProof(ip, disclosed, message, null, upkt[(i+1)%numberOfTokens].getToken(), proof); fail(); }
catch (InvalidProofException ipe) { }
// modify proof
proof.setA("wrong proof".getBytes());
try { PresentationProtocol.verifyPresentationProof(ip, disclosed, message, null, upkt[i].getToken(), proof); fail(); }
catch (InvalidProofException ipe) { }
}
}
}
}
}
}
}
}