Skip to content

Commit

Permalink
Replaced ProofInput on ProofRequest
Browse files Browse the repository at this point in the history
  • Loading branch information
Artemkaaas committed Jul 12, 2017
1 parent 56782e0 commit 120c070
Show file tree
Hide file tree
Showing 12 changed files with 365 additions and 275 deletions.
14 changes: 7 additions & 7 deletions anoncreds/protocol/prover.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
NonRevocationClaimInitializer, \
NonRevocationProofBuilder
from anoncreds.protocol.types import PrimaryClaim, NonRevocationClaim, Proof, \
InitProof, ProofInput, ProofClaims, \
InitProof, ProofRequest, ProofClaims, \
FullProof, \
Schema, ID, SchemaKey, ClaimRequest, Claims, RequestedProof, AggregatedProof, ProofInfo, ClaimAttributeValues
from anoncreds.protocol.utils import get_hash_as_int, isCryptoInteger
Expand Down Expand Up @@ -99,16 +99,16 @@ async def processClaims(self, allClaims: Dict[ID, Claims]):
res.append(await self.processClaim(schemaId, claim_attributes, claim_signature))
return res

async def presentProof(self, proofInput: ProofInput) -> FullProof:
async def presentProof(self, proofRequest: ProofRequest) -> FullProof:
"""
Presents a proof to the verifier.
:param proofInput: description of a proof to be presented (revealed
:param proofRequest: description of a proof to be presented (revealed
attributes, predicates, timestamps for non-revocation)
:return: a proof (both primary and non-revocation) and revealed attributes (initial non-encoded values)
"""
claims, requestedProof = await self._findClaims(proofInput)
proof = await self._prepareProof(claims, proofInput.nonce, requestedProof)
claims, requestedProof = await self._findClaims(proofRequest)
proof = await self._prepareProof(claims, proofRequest.nonce, requestedProof)
return proof

#
Expand Down Expand Up @@ -151,9 +151,9 @@ async def _initNonRevocationClaim(self, schemaId: ID,
# PRESENT PROOF
#

async def _findClaims(self, proofInput: ProofInput) -> (
async def _findClaims(self, proofRequest: ProofRequest) -> (
Dict[SchemaKey, ProofClaims], Dict[str, Any]):
revealedAttrs, predicates = proofInput.revealedAttrs, proofInput.predicates
revealedAttrs, predicates = proofRequest.verifiableAttributes, proofRequest.predicates

foundRevealedAttrs = {}
foundPredicates = {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from anoncreds.protocol.revocation.accumulators.non_revocation_common import \
createTauListExpectedValues, \
createTauListValues
from anoncreds.protocol.types import T, NonRevocProof, ID, ProofInput
from anoncreds.protocol.types import T, NonRevocProof, ID, ProofRequest
from anoncreds.protocol.utils import int_to_ZR
from anoncreds.protocol.wallet.wallet import Wallet
from config.config import cmod
Expand All @@ -14,16 +14,16 @@ class NonRevocationProofVerifier:
def __init__(self, wallet: Wallet):
self._wallet = wallet

async def verifyNonRevocation(self, proofInput: ProofInput, schema_seq_no,
async def verifyNonRevocation(self, proofRequest: ProofRequest, schema_seq_no,
cHash, nonRevocProof: NonRevocProof) \
-> Sequence[T]:
if await self._wallet.shouldUpdateAccumulator(
schemaId=ID(seqId=schema_seq_no),
ts=proofInput.ts,
seqNo=proofInput.seqNo):
ts=proofRequest.ts,
seqNo=proofRequest.seqNo):
await self._wallet.updateAccumulator(schemaId=ID(schemaId=schema_seq_no),
ts=proofInput.ts,
seqNo=proofInput.seqNo)
ts=proofRequest.ts,
seqNo=proofRequest.seqNo)

pkR = await self._wallet.getPublicKeyRevocation(ID(schemaId=schema_seq_no))
accum = await self._wallet.getAccumulator(ID(schemaId=schema_seq_no))
Expand Down
126 changes: 92 additions & 34 deletions anoncreds/protocol/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
fromDictWithStrValues, deserializeFromStr, encodeAttr, crypto_int_to_str, to_crypto_int, isCryptoInteger, \
intToArrayBytes, bytesToInt
from config.config import cmod

from typing import NamedTuple
import uuid

class AttribType:
def __init__(self, name: str, encode: bool):
Expand Down Expand Up @@ -281,7 +282,7 @@ def from_str_dict(cls, d):
type = d['p_type']
schema_seq_no = int(d['schema_seq_no']) if d['schema_seq_no'] else None
issuer_did = int(d['issuer_did']) if d['issuer_did'] else None
return Predicate(attrName=attrName, value=value, type=type,
return PredicateGE(attrName=attrName, value=value, type=type,
schema_seq_no=schema_seq_no, issuer_did=issuer_did)


Expand Down Expand Up @@ -428,39 +429,8 @@ def __str__(self):
return os.linesep.join(rtn)


class ProofInput(
namedtuple('ProofInput', 'nonce, revealedAttrs, predicates, ts, seqNo'),
NamedTupleStrSerializer):
def __new__(cls, nonce=None, revealedAttrs=None, predicates=None, ts=None, seqNo=None):
return super(ProofInput, cls).__new__(cls, nonce, revealedAttrs or {},
predicates or {},
ts, seqNo)

@classmethod
def fromStrDict(cls, d):
d = fromDictWithStrValues(d)
revealedAttrs = {k: AttributeInfo.fromStrDict(v) for k, v in d['revealedAttrs'].items()}
predicates = {k: Predicate.fromStrDict(v) for k, v in d['predicates'].items()}
result = cls(**d)
return result._replace(revealedAttrs=revealedAttrs, predicates=predicates)

def to_str_dict(self):
return {
'nonce': str(self.nonce),
'revealedAttrs': {k: v.to_str_dict() for k, v in self.revealedAttrs.items()},
'predicates': {k: v.to_str_dict() for k, v in self.predicates.items()}
}

@classmethod
def from_str_dict(cls, d):
nonce = int(d['nonce'])
revealedAttrs = {k: AttributeInfo.from_str_dict(v) for k, v in d['revealedAttrs'].items()}
predicates = {k: Predicate.from_str_dict(v) for k, v in d['predicates'].items()}
return ProofInput(nonce=nonce, revealedAttrs=revealedAttrs, predicates=predicates)


class AttributeInfo(
namedtuple('ProofInput', 'name, schema_seq_no, issuer_did'),
namedtuple('AttributeInfo', 'name, schema_seq_no, issuer_did'),
NamedTupleStrSerializer):
def __new__(cls, name=None, schema_seq_no=None, issuer_did=None):
return super(AttributeInfo, cls).__new__(cls, name, schema_seq_no, issuer_did)
Expand Down Expand Up @@ -846,3 +816,91 @@ def from_str_dict(cls, d):
raw = d[0]
encoded = int(to_crypto_int(d[1]))
return ClaimAttributeValues(raw=raw, encoded=encoded)


AvailableClaim = NamedTuple("AvailableClaim", [("name", str),
("version", str),
("origin", str)])


class ProofRequest:
def __init__(self, name, version, nonce, attributes=[], verifiableAttributes=[], predicates=[]):
self.name = name
self.version = version
self.nonce = nonce
self.attributes = attributes
self.verifiableAttributes = \
{str(uuid.uuid4()): AttributeInfo(name=a) for a in verifiableAttributes} if \
isinstance(verifiableAttributes, list) else verifiableAttributes
self.predicates = {str(uuid.uuid4()): PredicateGE(attrName=p['attrName'], value=p['value']) for p in
predicates} if isinstance(predicates, list) else predicates
self.fulfilledByClaims = []
self.selfAttestedAttrs = {}
self.ts = None
self.seqNo = None
# TODO _F_ need to add support for predicates on unrevealed attibutes

def __eq__(self, other):
return self.__dict__ == other.__dict__

@property
def toDict(self):
return {
"name": self.name,
"version": self.version,
"nonce": self.nonce,
"attributes": self.attributes,
"requested_attrs": self.verifiableAttributes
}

def to_str_dict(self):
return {
"name": self.name,
"version": self.version,
"nonce": str(self.nonce),
"requested_attrs": {k: v.to_str_dict() for k, v in self.verifiableAttributes.items()},
"requested_predicates": {k: v.to_str_dict() for k, v in self.predicates.items()}
}

@staticmethod
def from_str_dict(d):
return ProofRequest(name=d['name'],
version=d['version'],
nonce=int(d['nonce']),
attributes=d['attributes'] if 'attributes' in d else [],
verifiableAttributes={k: AttributeInfo.from_str_dict(v) for k, v in
d['requested_attrs'].items()},
predicates={k: PredicateGE.from_str_dict(v) for k, v in d['requested_predicates'].items()})

@property
def attributeValues(self):
return \
'Attributes:' + '\n ' + \
format("\n ".join(
['{}: {}'.format(k, v)
for k, v in self.attributes])) + '\n'

@property
def verifiableClaimAttributeValues(self):
return \
'Verifiable Attributes:' + '\n ' + \
format("\n ".join(
['{}'.format(v.name)
for k, v in self.verifiableAttributes.items()])) + '\n'

@property
def predicateValues(self):
return \
'Predicates:' + '\n ' + \
format("\n ".join(
['{}'.format(v.attrName)
for k, v in self.predicates.items()])) + '\n'

@property
def fixedInfo(self):
return 'Status: Requested' + '\n' \
'Name: ' + self.name + '\n' \
'Version: ' + self.version + '\n'

def __str__(self):
return self.fixedInfo + self.attributeValues + self.verifiableClaimAttributeValues
18 changes: 9 additions & 9 deletions anoncreds/protocol/verifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
PrimaryProofVerifier
from anoncreds.protocol.revocation.accumulators.non_revocation_proof_verifier import \
NonRevocationProofVerifier
from anoncreds.protocol.types import FullProof, ProofInput
from anoncreds.protocol.types import FullProof, ProofRequest
from anoncreds.protocol.utils import get_hash_as_int, isCryptoInteger
from anoncreds.protocol.wallet.wallet import Wallet
from config.config import cmod
Expand All @@ -24,37 +24,37 @@ def verifierId(self):
def generateNonce(self):
return cmod.integer(cmod.randomBits(LARGE_NONCE))

async def verify(self, proofInput: ProofInput, proof: FullProof):
async def verify(self, proofRequest: ProofRequest, proof: FullProof):
"""
Verifies a proof from the prover.
:param proofInput: description of a proof to be presented (revealed
:param proofRequest: description of a proof to be presented (revealed
attributes, predicates, timestamps for non-revocation)
:param proof: a proof
:return: True if verified successfully and false otherwise.
"""

if proofInput.revealedAttrs.keys() != proof.requestedProof.revealed_attrs.keys():
if proofRequest.verifiableAttributes.keys() != proof.requestedProof.revealed_attrs.keys():
raise ValueError('Received attributes ={} do not correspond to requested={}'.format(
proof.requestedProof.revealed_attrs.keys(), proofInput.revealedAttrs.keys()))
proof.requestedProof.revealed_attrs.keys(), proofRequest.verifiableAttributes.keys()))

if proofInput.predicates.keys() != proof.requestedProof.predicates.keys():
if proofRequest.predicates.keys() != proof.requestedProof.predicates.keys():
raise ValueError('Received predicates ={} do not correspond to requested={}'.format(
proof.requestedProof.predicates.keys(), proofInput.predicates.keys()))
proof.requestedProof.predicates.keys(), proofRequest.predicates.keys()))

TauList = []
for (uuid, proofItem) in proof.proofs.items():
if proofItem.proof.nonRevocProof:
TauList += await self._nonRevocVerifier.verifyNonRevocation(
proofInput, proofItem.schema_seq_no, proof.aggregatedProof.cHash,
proofRequest, proofItem.schema_seq_no, proof.aggregatedProof.cHash,
proofItem.proof.nonRevocProof)
if proofItem.proof.primaryProof:
TauList += await self._primaryVerifier.verify(proofItem.schema_seq_no,
proof.aggregatedProof.cHash,
proofItem.proof.primaryProof)

CHver = self._get_hash(proof.aggregatedProof.CList, self._prepare_collection(TauList),
cmod.integer(proofInput.nonce))
cmod.integer(proofRequest.nonce))

return CHver == proof.aggregatedProof.cHash

Expand Down
9 changes: 4 additions & 5 deletions anoncreds/test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from anoncreds.protocol.prover import Prover
from anoncreds.protocol.repo.attributes_repo import AttributeRepoInMemory
from anoncreds.protocol.repo.public_repo import PublicRepoInMemory
from anoncreds.protocol.types import AttribDef, AttribType, ID, ProofInput
from anoncreds.protocol.types import AttribDef, AttribType, ID, ProofRequest
from anoncreds.protocol.verifier import Verifier
from anoncreds.protocol.wallet.issuer_wallet import IssuerWalletInMemory
from anoncreds.protocol.wallet.prover_wallet import ProverWalletInMemory
Expand Down Expand Up @@ -273,7 +273,6 @@ def genNonce(verifier):
return verifier.generateNonce()


async def presentProofAndVerify(verifier: Verifier, proofInput: ProofInput, prover):
proofInput = ProofInput(verifier.generateNonce(), proofInput.revealedAttrs, proofInput.predicates)
proof = await prover.presentProof(proofInput)
return await verifier.verify(proofInput, proof)
async def presentProofAndVerify(verifier: Verifier, proofRequest: ProofRequest, prover):
proof = await prover.presentProof(proofRequest)
return await verifier.verify(proofRequest, proof)
52 changes: 24 additions & 28 deletions anoncreds/test/test_anoncred_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from anoncreds.protocol.prover import Prover
from anoncreds.protocol.repo.attributes_repo import AttributeRepoInMemory
from anoncreds.protocol.repo.public_repo import PublicRepoInMemory
from anoncreds.protocol.types import ProofInput, PredicateGE, \
from anoncreds.protocol.types import ProofRequest, PredicateGE, \
ID, AttributeInfo
from anoncreds.protocol.verifier import Verifier
from anoncreds.protocol.wallet.issuer_wallet import IssuerWalletInMemory
Expand Down Expand Up @@ -46,14 +46,13 @@ async def testSingleIssuerSingleProver(primes1):
# 6. proof Claims
verifier = Verifier(WalletInMemory('verifier1', publicRepo))

proofInput = ProofInput(
verifier.generateNonce(),
{'attr_uuid': AttributeInfo('name', schema.seqId)},
{'predicate_uuid': PredicateGE('age', 18)})
proofRequest = ProofRequest("proof1", "1.0", verifier.generateNonce(),
verifiableAttributes={'attr_uuid': AttributeInfo('name', schema.seqId)},
predicates={'predicate_uuid': PredicateGE('age', 18)})

proof = await prover.presentProof(proofInput)
proof = await prover.presentProof(proofRequest)
assert proof.requestedProof.revealed_attrs['attr_uuid'][1] == 'Alex'
assert await verifier.verify(proofInput, proof)
assert await verifier.verify(proofRequest, proof)


@pytest.mark.skipif('sys.platform == "win32"', reason='SOV-86')
Expand Down Expand Up @@ -99,19 +98,18 @@ async def testMultiplIssuersSingleProver(primes1, primes2):
# 6. proof Claims
verifier = Verifier(WalletInMemory('verifier1', publicRepo))

proofInput = ProofInput(
verifier.generateNonce(),
{'attr_uuid1': AttributeInfo('name', schema1.seqId),
'attr_uuid2': AttributeInfo('status', schema2.seqId)},
{'predicate_uuid1': PredicateGE('age', 18),
'predicate_uuid2': PredicateGE('period', 5)})
proofRequest = ProofRequest("proof1", "1.0", verifier.generateNonce(),
verifiableAttributes={'attr_uuid1': AttributeInfo('name', schema1.seqId),
'attr_uuid2': AttributeInfo('status', schema2.seqId)},
predicates={'predicate_uuid1': PredicateGE('age', 18),
'predicate_uuid2': PredicateGE('period', 5)})

proof = await prover.presentProof(proofInput)
proof = await prover.presentProof(proofRequest)

assert proof.requestedProof.revealed_attrs['attr_uuid1'][1] == 'Alex'
assert proof.requestedProof.revealed_attrs['attr_uuid2'][1] == 'FULL'

assert await verifier.verify(proofInput, proof)
assert await verifier.verify(proofRequest, proof)


@pytest.mark.skipif('sys.platform == "win32"', reason='SOV-86')
Expand Down Expand Up @@ -153,16 +151,15 @@ async def testSingleIssuerMultipleCredDefsSingleProver(primes1, primes2):
# 6. proof Claims
verifier = Verifier(WalletInMemory('verifier1', publicRepo))

proofInput = ProofInput(
verifier.generateNonce(),
{'attr_uuid1': AttributeInfo('name', schema1.seqId)},
{'predicate_uuid1': PredicateGE('age', 18),
'predicate_uuid2': PredicateGE('period', 5)})
proofRequest = ProofRequest("proof1", "1.0", verifier.generateNonce(),
verifiableAttributes={'attr_uuid1': AttributeInfo('name', schema1.seqId)},
predicates={'predicate_uuid1': PredicateGE('age', 18),
'predicate_uuid2': PredicateGE('period', 5)})

proof = await prover.presentProof(proofInput)
proof = await prover.presentProof(proofRequest)

assert proof.requestedProof.revealed_attrs['attr_uuid1'][1] == 'Alex'
assert await verifier.verify(proofInput, proof)
assert await verifier.verify(proofRequest, proof)


@pytest.mark.asyncio
Expand Down Expand Up @@ -196,12 +193,11 @@ async def testSingleIssuerSingleProverPrimaryOnly(primes1):
# 6. proof Claims
verifier = Verifier(WalletInMemory('verifier1', publicRepo))

proofInput = ProofInput(
verifier.generateNonce(),
{'attr_uuid1': AttributeInfo('name', schema.seqId)},
{'predicate_uuid1': PredicateGE('age', 18)})
proofRequest = ProofRequest("proof1", "1.0", verifier.generateNonce(),
verifiableAttributes={'attr_uuid1': AttributeInfo('name', schema.seqId)},
predicates={'predicate_uuid1': PredicateGE('age', 18)})

proof = await prover.presentProof(proofInput)
proof = await prover.presentProof(proofRequest)

assert proof.requestedProof.revealed_attrs['attr_uuid1'][1] == 'Alex'
assert await verifier.verify(proofInput, proof)
assert await verifier.verify(proofRequest, proof)
Loading

0 comments on commit 120c070

Please sign in to comment.