Reputation: 640
I'm working on a project with Indy Plenum, and I encountered an issue with generating DIDs and verification keys. I'm using the following function to generate them from a 32-character seed:
import sys
import argparse
from plenum.common.signer_did import DidSigner
def generate_did_verkey(seed: str):
"""
Generate DID and verification key using the provided seed.
Args:
seed (str): A 32-character long seed value.
Returns:
tuple: A tuple containing the DID and verification key.
"""
if len(seed) != 32:
raise ValueError("The seed must be exactly 32 characters long.")
seed_value = seed.encode()
signer = DidSigner(seed=seed_value)
did = signer.identifier
verkey = signer.verkey
return did, verkey
Even though I'm passing a seed that is exactly 32 characters long, the DidSigner
class in Indy Plenum sometimes gives me a DID that is 22 characters long (which is expected and works), but other times it gives me a 21-character DID, which causes issues later when I try to use it with an Indy node function (throws an error due to invalid DID length).
Similarly, the verification key (verkey
) is sometimes 23 characters (correct), but occasionally it gives me a 22-character verkey, which also causes problems down the line.
I’m not sure why the lengths of the DIDs and verkeys are inconsistent when the input seed is always 32 characters. I created a small script to call generate_did_verkey(seed)
10 times with random seeds, and here are the results:
root@indy-pool-4-nodes-node-1-79bf89ccd6-b7gt4:/indy_node/indy_network# python3 test_get_did_and_verkey.py
Seed 1: 6Tzxx5GR3VOqurfEzYhPmhyYgvGgdsPx
DID: GzbU6UywWsndZhov6aLVD9 (Length: 22)
VerKey: ~2TxDRQRCPrXQHiNdSq77Mt (Length: 23)
Seed 2: Jp8WBrwxHXn5YCVL2pNKwKwrJuxoQIjI
DID: 7yMvyQ3tcCYVgsid5ky9Nq (Length: 22)
VerKey: ~QDUxbkNknGdFidzQtPG758 (Length: 23)
Seed 3: zAgaUG7vK7ZFI5J4g4yUkB0rxAXNcNSO
DID: TmGcz2c5fdSjwuhmxpuJRg (Length: 22)
VerKey: ~M8dRGxpfHPpfWPUrkchpui (Length: 23)
Seed 4: 4AG44VWxPNkufirKFJztcjzv4VlgHN6B
DID: 6f8mNreThwNJ7AJ5xsaY73 (Length: 22)
VerKey: ~7MkCDmm5hxcwNd2VnmiB7V (Length: 23)
Seed 5: h01iyHIGs7wGr1TANq5cMOMfv30pRk5C
DID: 7fNPiLQjpmnQjGJ9KyCJc7 (Length: 22)
VerKey: ~7ewe36QjzNMkFAsKVtficY (Length: 23)
Seed 6: ZG6DxtYzVqQDXuNMsUzNAL6cjnTQqwmO
DID: 3vBqosKemC4M16pwQd3BR6 (Length: 22)
VerKey: ~HJvaYU3BtWJxHucaCbG9gK (Length: 23)
Seed 7: ZafyqLLqhENdJMfBOaFsKuz8OFRKpNv1
DID: N8mXH8kXon5P5nJ5KVQK53 (Length: 22)
VerKey: ~2suZ4eyHmVJwQdPmLDvoZs (Length: 23)
Seed 8: ONCWCJvCHO6speTaJU3JkGjEP51PoisD
DID: JdhBRD8B8NqDTBqbArZZ2e (Length: 22)
VerKey: ~3J7Sp26EGGUXbKD2fCCftp (Length: 23)
Seed 9: IXQ1sHoi5w3hLdX4FRJYB3qYdPJ6Cqgw
DID: rbTbLZs69hX1zRJnzHu8Q (Length: 21)
VerKey: ~N2H55kCg8LcTEC4Jqh7dJA (Length: 23)
Seed 10: qjJkRI0iGmqkM6CTgmFwZcrRqTAoWKHQ
DID: FDmCMrGuMFphpafEQopZWz (Length: 22)
VerKey: ~7XuxKGQEDzookBv6wZksxR (Length: 23)
Has anyone experienced this issue with DidSigner
in Indy Plenum
before? Is there something wrong with how I'm generating the DIDs or using DidSigner
?
Upvotes: 1
Views: 42
Reputation: 103
The DID generation function that uses your seed turns your seed into a Base58 value;
Base58 has some edge cases in which it can create extra bytes.
Base58 removes leading zeros in the binary input.
I had the same issue, I just check the string lengths and recreate the seed then rerun until the correct length's are found (My problem was ACA-PY's functions don't accept the incorrect length values, you might still be able to use the DID and Verkey's if you dont use ACA-PY, note, I have not tested this.).
When you call:
signer = DidSigner(seed=seed_value)
did = signer.identifier
verkey = signer.verkey
return did, verkey
First this is called signer_did.py:
def __init__(self, identifier, verkey=None, rawVerkey=None):
self.abbreviated = None
if (verkey is None or verkey == '') and (rawVerkey is None or rawVerkey == ''):
if identifier:
self._identifier = identifier
if (verkey is None and rawVerkey is None):
self._verkey = None
else:
self._verkey = ''
return
if not ((verkey or rawVerkey) and not (verkey and rawVerkey)):
raise ValueError(
"Both verkey {} and rawVerkey {} can't be specified"
.format(verkey, rawVerkey)
)
if identifier:
self._identifier = identifier
if rawVerkey:
self._verkey = rawToFriendly(rawVerkey)
self.abbreviated = False
else:
if verkey.startswith("~"):
self._verkey = verkey[1:]
self.abbreviated = True
else:
self._verkey = verkey
self.abbreviated = False
else:
verraw = rawVerkey or friendlyToRaw(verkey)
self._identifier = rawToFriendly(verraw[:16]) **#The issue comes from here.**
self._verkey = rawToFriendly(verraw[16:]) **#Also might create an issue here.**
self.abbreviated = True
def rawToFriendly(raw):
return base58.b58encode(raw).decode("utf-8")
I think the problem arises from this function, you are hitting some edge cases.
Upvotes: 1