def gen_nontransferable_serialized_aid(): with openDB() as bsr: # Inception: Non-transferable (ephemeral) case signer0 = Signer( transferable=False) # original signing keypair non transferable assert signer0.code == CryOneDex.Ed25519_Seed assert signer0.verfer.code == CryOneDex.Ed25519N keys0 = [signer0.verfer.qb64] serder = incept(keys=keys0) # default nxt is empty so abandoned # Derive AID from ked aid0 = Prefixer(ked=serder.ked, code=CryOneDex.Ed25519N) # update ked with pre serder.ked["pre"] = aid0.qb64 # Serialize ked0 tser0 = Serder(ked=serder.ked) # sign serialization skp0 = Signer() # original signing keypair transferable default tsig0 = skp0.sign(tser0.raw, index=0) # verify signature assert skp0.verfer.verify(tsig0.raw, tser0.raw) # not sure why this errors out when enabled; I guess kevers can't be used with nontransferable ids # kever = Kever(serder=tser0, sigers=[tsig0], baser=bsr) # no error # return base 64 serialization of signed aid return tsig0.qb64
def kever(): # Setup inception key event dict salt = b'\x05\xaa\x8f-S\x9a\xe9\xfaU\x9c\x02\x9c\x9b\x08Hu' salter = Salter(raw=salt) # create current key sith = 1 # one signer # original signing keypair transferable default skp0 = salter.signer(path="A", temp=True) keys = [skp0.verfer.qb64] # create next key # next signing keypair transferable is default skp1 = salter.signer(path="N", temp=True) nxtkeys = [skp1.verfer.qb64] # compute nxt digest nexter = Nexter(keys=nxtkeys) nxt = nexter.qb64 assert nxt == "E_d8cX6vuQwmD5P62_b663OeaVCLbiBFsirRHJsHn9co" # transferable so nxt is not empty sn = 0 # inception event so 0 toad = 0 # no witnesses nsigs = 1 # one attached signature unspecified index ked0 = dict( v=Versify(kind=Serials.json, size=0), i="", # qual base 64 prefix s="{:x}".format(sn), # hex string no leading zeros lowercase t=Ilks.icp, kt="{:x}".format(sith), # hex string no leading zeros lowercase k=keys, # list of signing keys each qual Base64 n=nxt, # hash qual Base64 wt="{:x}".format(toad), # hex string no leading zeros lowercase w=[], # list of qual Base64 may be empty c=[], # list of config ordered mappings may be empty ) # Derive AID from ked aid0 = Prefixer(ked=ked0, code=MtrDex.Ed25519) assert aid0.code == MtrDex.Ed25519 assert aid0.qb64 == skp0.verfer.qb64 == 'DBQOqSaf6GqVAoPxb4UARrklS8kLYj3JqsR6b4AASDd4' # update ked with pre ked0["i"] = aid0.qb64 # Serialize ked0 tser0 = Serder(ked=ked0) # sign serialization tsig0 = skp0.sign(tser0.raw, index=0) # verify signature assert skp0.verfer.verify(tsig0.raw, tser0.raw) return Kever(serder=tser0, sigers=[tsig0])
def incept( pre, toad=None, baks=None, cnfg=None, version=Version, kind=Serials.json, code=None, ): """ Returns serder of vcp message event Utility function to create a Registry inception event Parameters: pre is issuer identifier prefix qb64 cnfg is list of strings TraitDex of configuration traits toad is int, or str hex of backer threshold baks is the initial list of backers prefixes for VCs in the Registry version is the API version kind is the event type code is default code for Prefixer """ vs = Versify(version=version, kind=kind, size=0) isn = 0 ilk = Ilks.vcp cnfg = cnfg if cnfg is not None else [] baks = baks if baks is not None else [] if TraitDex.NoBackers in cnfg and len(baks) > 0: raise ValueError("{} backers specified for NB vcp, 0 allowed".format( len(baks))) if len(oset(baks)) != len(baks): raise ValueError("Invalid baks = {}, has duplicates.".format(baks)) if isinstance(toad, str): toad = "{:x}".format(toad) elif toad is None: if not baks: toad = 0 else: # compute default f and m for len(baks) toad = ample(len(baks)) if baks: if toad < 1 or toad > len(baks): # out of bounds toad raise ValueError("Invalid toad = {} for baks = {}".format( toad, baks)) else: if toad != 0: # invalid toad raise ValueError("Invalid toad = {} for baks = {}".format( toad, baks)) ked = dict( v=vs, # version string i="", # qb64 prefix ii=pre, s="{:x}".format(isn), # hex string no leading zeros lowercase t=ilk, c=cnfg, bt="{:x}".format(toad), # hex string no leading zeros lowercase b=baks # list of qb64 may be empty ) prefixer = Prefixer(ked=ked, code=code, allows=[MtrDex.Blake3_256 ]) # Derive AID from ked and code ked["i"] = prefixer.qb64 # update pre element in ked with pre qb64 return Serder(ked=ked) # return serialized ked
def gen_serialized_aid(witnesses): # taken from https://github.com/decentralized-identity/keripy/blob/6b85417ce1188543493efff48f95ebabd12fb0c6/tests/core/test_eventing.py with openDB() as bsr: # Transferable case # Setup inception key event dict # create current key sith = 1 # one signer skp0 = Signer() # original signing keypair transferable default assert skp0.code == CryOneDex.Ed25519_Seed assert skp0.verfer.code == CryOneDex.Ed25519 keys = [skp0.verfer.qb64] # create next key nxtsith = 1 # one signer skp1 = Signer() # next signing keypair transferable is default assert skp1.code == CryOneDex.Ed25519_Seed assert skp1.verfer.code == CryOneDex.Ed25519 nxtkeys = [skp1.verfer.qb64] # compute nxt digest nexter = Nexter(sith=nxtsith, keys=nxtkeys) nxt = nexter.qb64 # transferable so nxt is not empty sn = 0 # inception event so 0 toad = len(witnesses) nsigs = 1 # one attached signature unspecified index ked0 = dict( vs=Versify(kind=Serials.json, size=0), pre="", # qual base 64 prefix sn="{:x}".format(sn), # hex string no leading zeros lowercase ilk=Ilks.icp, sith="{:x}".format(sith), # hex string no leading zeros lowercase keys=keys, # list of signing keys each qual Base64 nxt=nxt, # hash qual Base64 toad="{:x}".format(toad), # hex string no leading zeros lowercase # I think these are always necessary for direct mode wits=witnesses or [], # list of qual Base64 may be empty cnfg=[], # list of config ordered mappings may be empty ) # Derive AID from ked aid0 = Prefixer(ked=ked0, code=CryOneDex.Ed25519) assert aid0.code == CryOneDex.Ed25519 assert aid0.qb64 == skp0.verfer.qb64 # update ked with pre ked0["pre"] = aid0.qb64 # Serialize ked0 tser0 = Serder(ked=ked0) # sign serialization tsig0 = skp0.sign(tser0.raw, index=0) # verify signature assert skp0.verfer.verify(tsig0.raw, tser0.raw) kever = Kever(serder=tser0, sigers=[tsig0], baser=bsr) # no error # return base 64 serialization of signed aid # return tsig0.qb64 return tsig0, tser0, tsig0.qb64
def test_proving(): sidSalt = coring.Salter(raw=b'0123456789abcdef').qb64 with basing.openDB(name="sid") as sidDB, \ keeping.openKS(name="sid") as sidKS: sidHab = habbing.Habitat(ks=sidKS, db=sidDB, salt=sidSalt, temp=True) assert sidHab.pre == "E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E" sed = dict() sed["$id"] = "" sed["$schema"] = "http://json-schema.org/draft-07/schema#" sed.update( dict(type="object", properties=dict(id=dict(type="string"), lei=dict(type="string")))) schemer = scheming.Schemer(sed=sed, typ=scheming.JSONSchema(), code=coring.MtrDex.Blake3_256) credSubject = dict( id= "did:keri:Efaavv0oadfghasdfn443fhbyyr4v", # this needs to be generated from a KEL lei="254900OPPU84GM83MG36", issuanceDate="2021-06-27T21:26:21.233257+00:00", ) cache = CacheResolver() cache.add(schemer.said, schemer.raw) creder = credential(issuer=sidHab.pre, schema=schemer.said, subject=credSubject, typ=JSONSchema(resolver=cache)) msg = sidHab.endorse(serder=creder) assert msg == ( b'{"v":"KERI10JSON000136_","i":"EgaaYOPdG7vootT99cmClvwOoM-hjUIpv5Xl6hFuTcyM",' b'"x":"EeCCZi1R5xHUlhsyQNm_7NrUQTEKZH5P9vBomnc9AihY","ti":"E4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE-YfcI9E",' b'"d":{"id":"did:keri:Efaavv0oadfghasdfn443fhbyyr4v","lei":"254900OPPU84GM83MG36",' b'"issuanceDate":"2021-06-27T21:26:21.233257+00:00"}}-VA0-FABE4YPqsEOaPNaZxVIbY-Gx2bJgP-c7AH_K7pEE' b'-YfcI9E0AAAAAAAAAAAAAAAAAAAAAAAElHzHwX3V6itsD2Ksg_CNBbUNTBYzLYw-AxDNI7_ZmaI' b'-AABAA0pXbQllgzXr88IczAnsPrdhgFKs9wNQvfSfzyrtcvbTwq-U1DmBluAklntCqH1AbBL6TWLZIDGi83BHLWJ82CA' ) creder = Credentialer(raw=msg, typ=JSONSchema(resolver=cache)) proof = msg[creder.size:] ctr = Counter(qb64b=proof, strip=True) assert ctr.code == CtrDex.AttachedMaterialQuadlets assert ctr.count == 52 pags = ctr.count * 4 assert len(proof) == pags ctr = Counter(qb64b=proof, strip=True) assert ctr.code == CtrDex.TransIndexedSigGroups assert ctr.count == 1 prefixer = Prefixer(qb64b=proof, strip=True) assert prefixer.qb64 == sidHab.pre seqner = Seqner(qb64b=proof, strip=True) assert seqner.sn == sidHab.kever.sn diger = Diger(qb64b=proof, strip=True) assert diger.qb64 == sidHab.kever.serder.dig ictr = Counter(qb64b=proof, strip=True) assert ictr.code == CtrDex.ControllerIdxSigs isigers = [] for i in range(ictr.count): isiger = Siger(qb64b=proof, strip=True) isiger.verfer = sidHab.kever.serder.verfers[i] isigers.append(isiger) assert len(isigers) == 1 siger = isigers[0] assert siger.verfer.verify(siger.raw, creder.raw) is True
def test_prefixer(): pre = "DntNTPnDFBnmlO6J44LXCrzZTAmpe-82b7BmQGtL4QhM" vs = Versify(version=Version, kind=Serials.json, size=0) with pytest.raises(EmptyMaterialError): prefixer = Prefixer() # vcp, backers allowed no backers ked = dict(v=vs, i="", ii=pre, s="{:x}".format(0), t=Ilks.vcp, c=[], b=[]) prefixer = Prefixer(ked=ked, code=MtrDex.Blake3_256) assert prefixer.qb64 == "E_TB9WKVB4Zx-Wu3-u1_RQWy2ZrDccaOj2xUpHQcg0MA" assert prefixer.verify(ked=ked) is True assert prefixer.verify(ked=ked, prefixed=True) is False # Invalid event type ked = dict(v=vs, i="", ii=pre, s="{:x}".format(0), t=Ilks.iss, c=[], b=[]) with pytest.raises(DerivationError): prefixer = Prefixer(ked=ked, code=MtrDex.Blake3_256) # vcp, no backers allowed ked = dict(v=vs, i="", ii=pre, s="{:x}".format(0), t=Ilks.vcp, c=[TraitDex.NoBackers], b=[]) prefixer = Prefixer(ked=ked, code=MtrDex.Blake3_256) assert prefixer.qb64 == "EEDVlhKzGXA6C7n1igQF8m4WfTAEuwuvitgoM4DI3iCs" assert prefixer.verify(ked=ked) is True assert prefixer.verify(ked=ked, prefixed=True) is False bak1 = "EXvR3p8V95W8J7Ui4-mEzZ79S-A1esAnJo1Kmzq80Jkc" bak2 = "DSEpNJeSJjxo6oAxkNE8eCOJg2HRPstqkeHWBAvN9XNU" bak3 = "Dvxo-P4W_Z0xXTfoA3_4DMPn7oi0mLCElOWJDpC0nQXw" # vcp, one backer ked = dict(v=vs, i="", ii=pre, s="{:x}".format(0), t=Ilks.vcp, c=[], b=[bak1]) prefixer = Prefixer(ked=ked, code=MtrDex.Blake3_256) assert prefixer.qb64 == "E_e9zbZI8WCMNoaY1b-3aEVB59M6dc2Br8EDJ1_ozK-8" assert prefixer.verify(ked=ked) is True assert prefixer.verify(ked=ked, prefixed=True) is False # vcp, many backers ked = dict(v=vs, i="", ii=pre, s="{:x}".format(0), t=Ilks.vcp, c=[], b=[bak1, bak2, bak3]) prefixer = Prefixer(ked=ked, code=MtrDex.Blake3_256) assert prefixer.qb64 == "EEuFeIT3_0_IAaNg8D-5AxO6UtQCmD17n77iksL048Go" assert prefixer.verify(ked=ked) is True assert prefixer.verify(ked=ked, prefixed=True) is False """ End Test """
def test_tever_backers(mockHelpingNowUTC): # registry with backer and receipt with basing.openDB() as db, keeping.openKS() as kpr, viring.openReg( ) as reg: valSecret = 'AgjD4nRlycmM5cPcAkfOATAp8wVldRsnc9f1tiwctXlw' # create receipt signer prefixer default code is non-transferable valSigner = Signer(qb64=valSecret, transferable=False) valPrefixer = Prefixer(qb64=valSigner.verfer.qb64) valpre = valPrefixer.qb64 assert valpre == 'B8KY1sKmgyjAiUDdUBPNPyrSz_ad_Qf9yzhDNZlEKiMc' hab = buildHab(db, kpr) vcp = eventing.incept(hab.pre, baks=[valpre], toad=1, cnfg=[], code=MtrDex.Blake3_256) regk = vcp.pre valCigar = valSigner.sign(ser=vcp.raw, index=0) # successfully anchor to a rotation event rseal = SealEvent(i=regk, s=vcp.ked["s"], d=vcp.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger tev = Tever(serder=vcp, seqner=seqner, diger=diger, bigers=[valCigar], db=db, reger=reg) dgkey = dgKey(pre=regk, dig=vcp.dig) assert reg.getTvt(dgkey) == ( b'{"v":"KERI10JSON0000d7_","i":"EBZR8LxEozgFa6UXwtSAmiXsmdChrT7Hr-jcxc9NFfrU",' b'"ii":"EaKJ0FoLxO1TYmyuprguKO7kJ7Hbn0m0Wuk5aMtSrMtY","s":"0","t":"vcp","c":[],' b'"bt":"1",' b'"b":["B8KY1sKmgyjAiUDdUBPNPyrSz_ad_Qf9yzhDNZlEKiMc"]}') assert reg.getAnc( dgkey ) == b'0AAAAAAAAAAAAAAAAAAAAAAQEpWPsFsCcsu5SpVH0416qHx3gvG0CWlrP_i7BVdbmRBg' assert reg.getTel(snKey( pre=regk, sn=0)) == b'EJTWiS0ebp8VSyLr38x73dAHdUqivisUtAaGpEHt5HDc' assert [bytes(tib) for tib in reg.getTibs(dgkey)] == [ b'AAGhpPxAoltsRAnqxf7NsBzWSxWYLZ_ALImVVBiTlzJSdlATxRp_hBK4AbOzu-a900hwRxa0RX-yVWbVJA6oxoBw' ] assert reg.getTwe(snKey(pre=regk, sn=0)) is None debSecret = 'AKUotEE0eAheKdDJh9QvNmSEmO_bjIav8V_GmctGpuCQ' # create receipt signer prefixer default code is non-transferable debSigner = Signer(qb64=debSecret, transferable=False) debPrefixer = Prefixer(qb64=debSigner.verfer.qb64) debpre = debPrefixer.qb64 assert debpre == 'BbWeWTNGXPMQrVuJmScNQn81YF7T2fhh2kXwT8E_NbeI' vrt = eventing.rotate(regk, dig=vcp.dig, baks=[valpre], adds=[debpre]) valCigar = valSigner.sign(ser=vrt.raw, index=0) debCigar = debSigner.sign(ser=vrt.raw, index=1) # successfully anchor to a rotation event rseal = SealEvent(regk, vrt.ked["s"], vrt.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger tev.update(serder=vrt, seqner=seqner, diger=diger, bigers=[valCigar, debCigar]) assert tev.baks == [ 'B8KY1sKmgyjAiUDdUBPNPyrSz_ad_Qf9yzhDNZlEKiMc', 'BbWeWTNGXPMQrVuJmScNQn81YF7T2fhh2kXwT8E_NbeI' ] vcdig = b'EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU' bis = eventing.backerIssue(vcdig=vcdig.decode("utf-8"), regk=regk, regsn=tev.sn, regd=tev.serder.dig) valCigar = valSigner.sign(ser=bis.raw, index=0) debCigar = debSigner.sign(ser=bis.raw, index=1) # successfully anchor to a rotation event rseal = SealEvent(bis.ked["i"], bis.ked["s"], bis.diger.qb64) rot = hab.rotate(data=[rseal._asdict()]) rotser = Serder(raw=rot) seqner = Seqner(sn=int(rotser.ked["s"], 16)) diger = rotser.diger tev.update(bis, seqner=seqner, diger=diger, bigers=[valCigar, debCigar]) vci = nsKey([regk, vcdig]) dgkey = dgKey(pre=vci, dig=bis.dig) assert bytes(reg.getTvt(dgkey)) == ( b'{"v":"KERI10JSON00012d_","i":"EEBp64Aw2rsjdJpAR0e2qCq3jX7q7gLld3LjAwZgaLXU",' b'"ii":"EBZR8LxEozgFa6UXwtSAmiXsmdChrT7Hr-jcxc9NFfrU","s":"0","t":"bis","ra":{' b'"i":"EBZR8LxEozgFa6UXwtSAmiXsmdChrT7Hr-jcxc9NFfrU","s":1,"d":"EZH2Cfw3nvcMRg' b'Y31Jyc2zHVh4a0LO_bVZ4EmL4V8Ol8"},"dt":"2021-01-01T00:00:00.000000+00:00"}' )