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 test_ip_roundtrip(): """Tests that a payload can be serialized to bytes and then deserialized with verification for a hard-coded secret. """ s = Signer(qb64="AgjD4nRlycmM5cPcAkfOATAp8wVldRsnc9f1tiwctXlw", transferable=False) now = datetime.datetime.now(datetime.timezone.utc) payload = build_witness_ip(s, "10.0.0.8", "0a:ff:c2:43:91:5c::") r = parse_verify_witness_ip(payload) assert r is not None assert r["ip4"] == "10.0.0.8" assert r["ip6"] == "a:ff:c2:43:91:5c::" assert (r["timestamp"] - now).seconds < 5 assert r["verfer"].raw == s.verfer.raw
async def _put_witness(args): """Runs the put witness IP information command. """ s = Signer(qb64=args["qb64"], transferable=False) target = path.abspath(path.expanduser(args["ip"])) if path.isfile(target): with open(target, 'r') as f: ip = json.load(f) log.debug(f"Witness IP information is being set to {ip}.") else: msg.warn(f"The IP information file {target} does not exist.") r = await CLIENT.set_witness_ip(s, **ip) print_save(r, args) return r
def build_witness_ip(signer: Signer, ip4: str = None, ip6: str = None): """Updates the IP address for the *non-transferable* witness identifier represented by `signer`. Note that the public key registered with the DHT will be obtained from :attr:`Signer.verfer`. Args: signer (Signer): used to sign the request passed to the DHT. ip4 (str): IPv4 address that this witness is listening at. ip6 (str): IPv6 address that this witness is listening at. Returns: bytearray: payload that can be sent directly to the DHT using a :class:`DhtTcpClient`. """ assert ip4 is not None or ip6 is not None body = { "v": signer.verfer.qb64b, "4": None if ip4 is None else socket.inet_pton(socket.AF_INET, ip4), # 4 bytes "6": None if ip6 is None else socket.inet_pton(socket.AF_INET6, ip6), # 16 bytes "t": nowIso8601() # 32 bytes } # For ED25519 verfer, the total msgpack body will be ~128 bytes. To make room # for additional (and perhaps quantum-proof) public keys later, we'll allow # a maximum of 1KB for the Witness IP payload. So we allow a maximum of three # bytes as the leading prefix which specifies how large the body payload is. # Along the same lines, let's leave 3 bytes to specify the signature size # Later we will have to support possibly multiple signature types, not # just ED25519. b = msgpack.packb(body) s = signer.sign(b).raw bsize, ssize = f"{len(b):03x}".encode(), f"{len(s):03x}".encode() return bytearray(bsize + ssize + b + s)
def test_uselogger(): """ Test using logger to """ # Some secrets to use on the events secrets = [ 'ArwXoACJgOleVZ2PY7kXn7rA0II0mHYDhc6WrBH8fDAc', 'A6zz7M08-HQSFq92sJ8KJOT2cZ47x7pXFQLPB0pckB3Q', 'AcwFTk-wgk3ZT2buPRIbK-zxgPx-TKbaegQvPEivN90Y', 'Alntkt3u6dDgiQxTATr01dy8M72uuaZEf9eTdM-70Gk8', 'A1-QxDkso9-MR1A8rZz_Naw6fgaAtayda8hrbkRVVu1E', 'AKuYMe09COczwf2nIoD5AE119n7GLFOVFlNLxZcKuswc', 'AxFfJTcSuEE11FINfXMqWttkZGnUZ8KaREhrnyAXTsjw', 'ALq-w1UKkdrppwZzGTtz4PWYEeWm0-sDHzOv5sq96xJY' ] # create signers from the secrets signers = [Signer(qb64=secret) for secret in secrets] # faster assert [siger.qb64 for siger in signers] == secrets with openLogger() as lgr: # Event 0 Inception Transferable (nxt digest not empty) 2 0f 3 multisig keys = [ signers[0].verfer.qb64, signers[1].verfer.qb64, signers[2].verfer.qb64 ] count = len(keys) nxtkeys = [ signers[3].verfer.qb64, signers[4].verfer.qb64, signers[5].verfer.qb64 ] sith = 2 code = CryOneDex.Blake3_256 # Blake3 digest of incepting data serder = incept(keys=keys, code=code, sith=sith, nxt=Nexter(keys=nxtkeys).qb64) # sign serialization sigers = [signers[i].sign(serder.raw, index=i) for i in range(count)] # create key event verifier state kever = Kever(serder=serder, sigers=sigers, logger=lgr) # Event 1 Rotation Transferable keys = nxtkeys nxtkeys = [ signers[5].verfer.qb64, signers[6].verfer.qb64, signers[7].verfer.qb64 ] serder = rotate(pre=kever.prefixer.qb64, keys=keys, sith=sith, dig=kever.diger.qb64, nxt=Nexter(keys=nxtkeys).qb64, sn=1) # sign serialization sigers = [ signers[i].sign(serder.raw, index=i - count) for i in range(count, count + count) ] # update key event verifier state kever.update(serder=serder, sigers=sigers) # Event 2 Interaction serder = interact(pre=kever.prefixer.qb64, dig=kever.diger.qb64, sn=2) # sign serialization (keys don't change for signing) sigers = [ signers[i].sign(serder.raw, index=i - count) for i in range(count, count + count) ] # update key event verifier state kever.update(serder=serder, sigers=sigers) assert not os.path.exists(lgr.path) """ End Test """
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_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"}' )
def test_parser(): """ Test the support functionality for Parser stream processor """ logger.setLevel("ERROR") # Test sequence of events given set of secrets secrets = [ 'ArwXoACJgOleVZ2PY7kXn7rA0II0mHYDhc6WrBH8fDAc', 'A6zz7M08-HQSFq92sJ8KJOT2cZ47x7pXFQLPB0pckB3Q', 'AcwFTk-wgk3ZT2buPRIbK-zxgPx-TKbaegQvPEivN90Y', 'Alntkt3u6dDgiQxTATr01dy8M72uuaZEf9eTdM-70Gk8', 'A1-QxDkso9-MR1A8rZz_Naw6fgaAtayda8hrbkRVVu1E', 'AKuYMe09COczwf2nIoD5AE119n7GLFOVFlNLxZcKuswc', 'AxFfJTcSuEE11FINfXMqWttkZGnUZ8KaREhrnyAXTsjw', 'ALq-w1UKkdrppwZzGTtz4PWYEeWm0-sDHzOv5sq96xJY' ] with openDB("controller") as conDB, openDB("validator") as valDB: event_digs = [] # list of event digs in sequence # create event stream msgs = bytearray() # create signers signers = [Signer(qb64=secret) for secret in secrets] # faster assert [signer.qb64 for signer in signers] == secrets # Event 0 Inception Transferable (nxt digest not empty) serder = incept(keys=[signers[0].verfer.qb64], nxt=Nexter(keys=[signers[1].verfer.qb64]).qb64) event_digs.append(serder.dig) # create sig counter counter = Counter(CtrDex.ControllerIdxSigs) # default is count = 1 # sign serialization siger = signers[0].sign(serder.raw, index=0) # return siger # create key event verifier state kever = Kever(serder=serder, sigers=[siger], db=conDB) #extend key event stream msgs.extend(serder.raw) msgs.extend(counter.qb64b) msgs.extend(siger.qb64b) assert msgs == bytearray( b'{"v":"KERI10JSON0000ed_","i":"DSuhyBcPZEZLK-fcw5tzHn2N46wRCG_ZOo' b'eKtWTOunRA","s":"0","t":"icp","kt":"1","k":["DSuhyBcPZEZLK-fcw5t' b'zHn2N46wRCG_ZOoeKtWTOunRA"],"n":"EPYuj8mq_PYYsoBKkzX1kxSPGYBWaIy' b'a3slgCOyOtlqU","bt":"0","b":[],"c":[],"a":[]}-AABAAmagesCSY8QhYY' b'HCJXEWpsGD62qoLt2uyT0_Mq5lZPR88JyS5UrwFKFdcjPqyKc_SKaKDJhkGWCk07' b'k_kVkjyCA') # Event 1 Rotation Transferable serder = rotate(pre=kever.prefixer.qb64, keys=[signers[1].verfer.qb64], dig=kever.serder.diger.qb64, nxt=Nexter(keys=[signers[2].verfer.qb64]).qb64, sn=1) event_digs.append(serder.dig) # create sig counter counter = Counter(CtrDex.ControllerIdxSigs) # default is count = 1 # sign serialization siger = signers[1].sign(serder.raw, index=0) # returns siger # update key event verifier state kever.update(serder=serder, sigers=[siger]) #extend key event stream msgs.extend(serder.raw) msgs.extend(counter.qb64b) msgs.extend(siger.qb64b) # Event 2 Rotation Transferable serder = rotate(pre=kever.prefixer.qb64, keys=[signers[2].verfer.qb64], dig=kever.serder.diger.qb64, nxt=Nexter(keys=[signers[3].verfer.qb64]).qb64, sn=2) event_digs.append(serder.dig) # create sig counter counter = Counter(CtrDex.ControllerIdxSigs) # default is count = 1 # sign serialization siger = signers[2].sign(serder.raw, index=0) # update key event verifier state kever.update(serder=serder, sigers=[siger]) #extend key event stream msgs.extend(serder.raw) msgs.extend(counter.qb64b) msgs.extend(siger.qb64b) # Event 3 Interaction serder = interact(pre=kever.prefixer.qb64, dig=kever.serder.diger.qb64, sn=3) event_digs.append(serder.dig) # create sig counter counter = Counter(CtrDex.ControllerIdxSigs) # default is count = 1 # sign serialization siger = signers[2].sign(serder.raw, index=0) # update key event verifier state kever.update(serder=serder, sigers=[siger]) #extend key event stream msgs.extend(serder.raw) msgs.extend(counter.qb64b) msgs.extend(siger.qb64b) # Event 4 Interaction serder = interact(pre=kever.prefixer.qb64, dig=kever.serder.diger.qb64, sn=4) event_digs.append(serder.dig) # create sig counter counter = Counter(CtrDex.ControllerIdxSigs) # default is count = 1 # sign serialization siger = signers[2].sign(serder.raw, index=0) # update key event verifier state kever.update(serder=serder, sigers=[siger]) #extend key event stream msgs.extend(serder.raw) msgs.extend(counter.qb64b) msgs.extend(siger.qb64b) # Event 5 Rotation Transferable serder = rotate(pre=kever.prefixer.qb64, keys=[signers[3].verfer.qb64], dig=kever.serder.diger.qb64, nxt=Nexter(keys=[signers[4].verfer.qb64]).qb64, sn=5) event_digs.append(serder.dig) # create sig counter counter = Counter(CtrDex.ControllerIdxSigs) # default is count = 1 # sign serialization siger = signers[3].sign(serder.raw, index=0) # update key event verifier state kever.update(serder=serder, sigers=[siger]) #extend key event stream msgs.extend(serder.raw) msgs.extend(counter.qb64b) msgs.extend(siger.qb64b) # Event 6 Interaction serder = interact(pre=kever.prefixer.qb64, dig=kever.serder.diger.qb64, sn=6) event_digs.append(serder.dig) # create sig counter counter = Counter(CtrDex.ControllerIdxSigs) # default is count = 1 # sign serialization siger = signers[3].sign(serder.raw, index=0) # update key event verifier state kever.update(serder=serder, sigers=[siger]) #extend key event stream msgs.extend(serder.raw) msgs.extend(counter.qb64b) msgs.extend(siger.qb64b) # Event 7 Rotation to null NonTransferable Abandon # nxt digest is empty serder = rotate(pre=kever.prefixer.qb64, keys=[signers[4].verfer.qb64], dig=kever.serder.diger.qb64, nxt="", sn=7) event_digs.append(serder.dig) # create sig counter counter = Counter(CtrDex.ControllerIdxSigs) # default is count = 1 # sign serialization siger = signers[4].sign(serder.raw, index=0) # update key event verifier state kever.update(serder=serder, sigers=[siger]) #extend key event stream msgs.extend(serder.raw) msgs.extend(counter.qb64b) msgs.extend(siger.qb64b) # Event 8 Interaction serder = interact(pre=kever.prefixer.qb64, dig=kever.serder.diger.qb64, sn=8) # create sig counter counter = Counter(CtrDex.ControllerIdxSigs) # default is count = 1 # sign serialization siger = signers[4].sign(serder.raw, index=0) # update key event verifier state with pytest.raises( ValidationError): # nulled so reject any more events kever.update(serder=serder, sigers=[siger]) #extend key event stream msgs.extend(serder.raw) msgs.extend(counter.qb64b) msgs.extend(siger.qb64b) # Event 8 Rotation serder = rotate(pre=kever.prefixer.qb64, keys=[signers[4].verfer.qb64], dig=kever.serder.diger.qb64, nxt=Nexter(keys=[signers[5].verfer.qb64]).qb64, sn=8) # create sig counter counter = Counter(CtrDex.ControllerIdxSigs) # default is count = 1 # sign serialization siger = signers[4].sign(serder.raw, index=0) # update key event verifier state with pytest.raises( ValidationError): # nontransferable so reject update kever.update(serder=serder, sigers=[siger]) #extend key event stream msgs.extend(serder.raw) msgs.extend(counter.qb64b) msgs.extend(siger.qb64b) assert len(msgs) == 3171 pre = kever.prefixer.qb64 db_digs = [ bytes(val).decode("utf-8") for val in kever.db.getKelIter(pre) ] assert db_digs == event_digs kevery = Kevery(db=valDB) parser = parsing.Parser(kvy=kevery) parser.parse(ims=bytearray(msgs)) # make copy assert parser.ims == bytearray(b'') # emptied assert pre in kevery.kevers vkever = kevery.kevers[pre] assert vkever.sn == kever.sn assert vkever.verfers[0].qb64 == kever.verfers[0].qb64 assert vkever.verfers[0].qb64 == signers[4].verfer.qb64 db_digs = [ bytes(val).decode("utf-8") for val in kevery.db.getKelIter(pre) ] assert db_digs == event_digs parser = parsing.Parser() # no kevery parser.parse(ims=msgs) assert parser.ims == bytearray(b'') assert not os.path.exists(kevery.db.path) assert not os.path.exists(kever.db.path) """ Done Test """