From 193d5987a92cc4363b16e066c1fcc1e69f1581f3 Mon Sep 17 00:00:00 2001 From: Kent Bull Date: Tue, 31 Dec 2024 10:07:52 -0700 Subject: [PATCH] fix: add nonces in prep for private creds --- src/keri/app/cli/commands/vc/create.py | 19 +++++++++++++++---- src/keri/vc/proving.py | 14 ++++++++------ src/keri/vdr/credentialing.py | 14 ++++++++++---- tests/vc/test_proving.py | 9 +++++---- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/keri/app/cli/commands/vc/create.py b/src/keri/app/cli/commands/vc/create.py index 7cd815cae..ce8c5bf50 100644 --- a/src/keri/app/cli/commands/vc/create.py +++ b/src/keri/app/cli/commands/vc/create.py @@ -1,5 +1,6 @@ import argparse import json +from typing import Optional from keri import help from hio.base import doing @@ -36,6 +37,8 @@ parser.add_argument('--alias', '-a', help='human readable alias for the new identifier prefix', required=True) parser.add_argument("--private", help="flag to indicate if this credential needs privacy preserving features", action="store_true") +parser.add_argument("--private-credential-nonce", help="(str) nonce for vc", action="store") +parser.add_argument("--private-subject-nonce", help="(str) nonce for subject", action="store") parser.add_argument('--passcode', '-p', help='22 character encryption passcode for keystore (is not saved)', dest="bran", default=None) # passcode => bran parser.add_argument("--time", help="timestamp for the credential creation", required=False, default=None) @@ -99,7 +102,10 @@ def issueCredential(args): rules=rules, credential=credential, timestamp=args.time, - private=args.private) + private=args.private, + private_credential_nonce=args.private_credential_nonce, + private_subject_nonce=args.private_subject_nonce, + ) doers = [issueDoer] return doers @@ -112,7 +118,8 @@ class CredentialIssuer(doing.DoDoer): """ def __init__(self, name, alias, base, bran, registryName=None, schema=None, edges=None, recipient=None, data=None, - rules=None, credential=None, timestamp=None, private=False): + rules=None, credential=None, timestamp=None, private:bool=False, private_credential_nonce:Optional[str]=None, + private_subject_nonce:Optional[str]=None,): """ Create DoDoer for issuing a credential and managing the processes needed to complete issuance Parameters: @@ -124,7 +131,9 @@ def __init__(self, name, alias, base, bran, registryName=None, schema=None, edge data: (dict) credential data dict credential: (dict) full credential to issue when joining a multisig issuance out (str): Filename for credential output - private: (bool) privacy preserving + private (bool): apply nonce used for privacy preserving ACDC + private_credential_nonce (Optional[str]): nonce used for privacy vc + private_subject_nonce (Optional[str]): nonce used for subject """ self.name = name @@ -173,7 +182,9 @@ def __init__(self, name, alias, base, bran, registryName=None, schema=None, edge source=edges, rules=rules, data=data, - private=private) + private=private, + private_credential_nonce=private_credential_nonce, + private_subject_nonce=private_subject_nonce) else: self.creder = serdering.SerderACDC(sad=credential) # proving.Creder(ked=credential) self.credentialer.validate(creder=self.creder) diff --git a/src/keri/vc/proving.py b/src/keri/vc/proving.py index e724648a5..d99f85b4c 100644 --- a/src/keri/vc/proving.py +++ b/src/keri/vc/proving.py @@ -5,7 +5,7 @@ """ from collections.abc import Iterable -from typing import Union +from typing import Union, Optional from .. import help from ..core import coring, serdering @@ -23,8 +23,9 @@ def credential(schema, issuer, data, recipient=None, - private=False, - salt=None, + private: bool = False, + private_credential_nonce: Optional[str] = None, + private_subject_nonce: Optional[str] = None, status=None, source=None, rules=None, @@ -40,7 +41,8 @@ def credential(schema, recipient (Option[str|None]): qb64 identifier prefix of the recipient data (dict): of the values being assigned to the subject of this credential private (bool): apply nonce used for privacy preserving ACDC - salt (string): salt for nonce + private_credential_nonce (Optional[str]): nonce used for privacy vc + private_subject_nonce (Optional[str]): nonce used for subject source (dict | list): of source credentials to which this credential is chained rules (dict | list): ACDC rules section for credential version (Version): version instance @@ -62,8 +64,8 @@ def credential(schema, ) if private: - vc["u"] = salt if salt is not None else coring.Salter().qb64 - subject["u"] = salt if salt is not None else coring.Salter().qb64 + vc["u"] = private_credential_nonce if private_credential_nonce is not None else coring.Salter().qb64 + subject["u"] = private_subject_nonce if private_subject_nonce is not None else coring.Salter().qb64 if recipient is not None: subject['i'] = recipient diff --git a/src/keri/vdr/credentialing.py b/src/keri/vdr/credentialing.py index 8a85c8e54..fd97b8f9e 100644 --- a/src/keri/vdr/credentialing.py +++ b/src/keri/vdr/credentialing.py @@ -5,6 +5,8 @@ VC issuer support """ +from typing import Optional + from hio.base import doing from hio.help import decking @@ -472,7 +474,7 @@ def revoke(self, said, dt=None): raise kering.ValidationError("Invalid revoke of {} that has not been issued " "pre={}.".format(vci, self.regk)) ievt = self.reger.getTvt(dgKey(pre=vci, dig=vcser)) - iserder = serdering.serderACDC(raw=bytes(ievt)) # Serder(raw=bytes(ievt)) + iserder = serdering.SerderACDC(raw=bytes(ievt)) # Serder(raw=bytes(ievt)) if self.noBackers: serder = eventing.revoke(vcdig=vci, regk=self.regk, dig=iserder.said, dt=dt) @@ -770,7 +772,8 @@ def __init__(self, hby, rgy, registrar, verifier): super(Credentialer, self).__init__(doers=doers) - def create(self, regname, recp: str, schema, source, rules, data, private=False): + def create(self, regname, recp: str, schema, source, rules, data, private: bool = False, + private_credential_nonce: Optional[str] = None, private_subject_nonce: Optional[str] = None): """ Create and validate a credential returning the fully populated Creder Parameters: @@ -780,7 +783,9 @@ def create(self, regname, recp: str, schema, source, rules, data, private=False) source: rules: data: - private: add nonce for privacy preserving + private (bool): apply nonce used for privacy preserving ACDC + private_credential_nonce (Optional[str]): nonce used for privacy vc + private_subject_nonce (Optional[str]): nonce used for subject Returns: Creder: Creder class for the issued credential @@ -800,7 +805,8 @@ def create(self, regname, recp: str, schema, source, rules, data, private=False) recipient=recp, data=data, source=source, - private=private, + private_credential_nonce=private_credential_nonce, + private_subject_nonce=private_subject_nonce, rules=rules, status=registry.regk) self.validate(creder) diff --git a/tests/vc/test_proving.py b/tests/vc/test_proving.py index bdb273be1..128209153 100644 --- a/tests/vc/test_proving.py +++ b/tests/vc/test_proving.py @@ -248,18 +248,19 @@ def test_privacy_preserving_credential(mockHelpingNowIso8601): cred = credential(schema="EZllThM1rLBSMZ_ozM1uAnFvSfC0N1jaQ42aKU5sCZ5Q", recipient="EM_S2MdMaKgP6P2Yyno6-flV6GqrwPencTIw8tCMR7iB", private=True, - salt=salt, + private_credential_nonce=coring.Salter(raw=b'0123456789abcdef').qb64, + private_subject_nonce=coring.Salter(raw=b'abcdef0123456789').qb64, issuer="EMZeK1yLZd1JV6Ktdq_YUt-YbyoTWB9UMcFzuiDly2Y6", data=d, status="ETQoH02zJRCTNz-Wl3nnkUD_RVSzSwcoNvmfa18AWt3M") assert cred.size == len(cred.raw) assert "u" in cred.sad print(cred.raw) - assert cred.raw == (b'{"v":"ACDC10JSON00021c_","d":"ELFOCm58xUlId994cS6m6bsfYOkNHEKoe15Cav-Sj8__",' + assert cred.raw == (b'{"v":"ACDC10JSON00021c_","d":"EMMDzhHHlpQP0XNMRThDeIFkYD1WkDHF7Tp-8kt8X5pn",' b'"u":"0AAwMTIzNDU2Nzg5YWJjZGVm","i":"EMZeK1yLZd1JV6Ktdq_YUt-YbyoTWB9UMcFzuiDl' b'y2Y6","ri":"ETQoH02zJRCTNz-Wl3nnkUD_RVSzSwcoNvmfa18AWt3M","s":"EZllThM1rLBSM' - b'Z_ozM1uAnFvSfC0N1jaQ42aKU5sCZ5Q","a":{"d":"EFwWs1d_fe_VeLZ0vQQKO-gkRvGrpfWAR' - b'bI4e9tzcqlV","u":"0AAwMTIzNDU2Nzg5YWJjZGVm","i":"EM_S2MdMaKgP6P2Yyno6-flV6Gq' + b'Z_ozM1uAnFvSfC0N1jaQ42aKU5sCZ5Q","a":{"d":"EK3MRnlg-bMUnHtYKyZ8HD_IbBeI0v4N8' + b'YB4UnNVBqrv","u":"0ABhYmNkZWYwMTIzNDU2Nzg5","i":"EM_S2MdMaKgP6P2Yyno6-flV6Gq' b'rwPencTIw8tCMR7iB","dt":"2021-06-27T21:26:21.233257+00:00","LEI":"254900OPPU' b'84GM83MG36","personLegalName":"John Doe","engagementContextRole":"Project Ma' b'nager"}}')