[solved] How do I get the CIDv1 peer id of a key pair?

The short go file at ipfs-key/main.go at master · whyrusleeping/ipfs-key · GitHub generates keypairs and prints the peer ID in the 12D3KooW… format. I’d like to obtain the keys in the k51qzi5uqu5d… format.

I can obtain the k51… format using ipfs key import some-name private-key-file followed by ipfs key list -l, but I’m looking for a way to obtain the k51… in go, or at least without using an external process.

After a lot of searching, I found https://cid.ipfs.io/ which shows that, after decoding, that site shows some very similar info for the following two hashes (obtained using the standalone key generator and ipfs key import):

12D3KooWPVYKwhPsyD1kpaaVNvJoqd4tdZR4VgxVmo9NSzWVQjCj
k51qzi5uqu5dl8wlbw09j1cpr1i456yb3mv0r5wnpx3wz6qq8pnppkvgqdepc8

Once converted to CIDv1 base32, they become:

bafyaajaiaejcbszrcftl53w5t63k6tgiyk7uvrdr3to6pjy76azeib2h4ccm6dgi
bafzaajaiaejcbszrcftl53w5t63k6tgiyk7uvrdr3to6pjy76azeib2h4ccm6dgi

Aside from the bafy/bafz (which seems to indicate the codec 0x70 vs 0x72), there’s no difference.

I know how to convert the CIDv1 base32 bafy or bafz to a CIDv1 base36 k50 / k51 using ipfs cid format -b base36 baf…, and from what I understand it’s a simple base conversion.

I’m still stumped about how I would get the CIDv1 base32 format from the 12D3KooW…, it seems that the multicodec identifier 0x72 gets inserted somehow into the mix (because the 12D… hash has everything implicit) and there’s something related to protobuf, but I haven’t used that.

So I guess my question is, “how do I protobuf the multicodec :-p to get from 12D… to one of the CIDv1 encodings?”.

Thanks a lot :slight_smile:

2 Likes

You’re right, CIDv0 are all-implicit, meaning CID begging with Q or 1 (identity) will always be base58btc encoded.
In case of Q CIDv0, the hash algorithm will be sha2-256, otherwise for 1 CIDv0, this is indeed an identity multihash.
So you can simply decode the entire 12D3KooWPVYKwhPsyD1kpaaVNvJoqd4tdZR4VgxVmo9NSzWVQjCj as base58btc.
It will give you the following multihash (as hex): 002408011220CB311166BEEEDD9FB6AF4CC8C2BF4AC471DCDDE7A71FF032440747E084CF0CC8
We have:

  • 00 for the hash function, here: identity
  • 24 for the length in bytes (0x24 = 36 bytes = 288 bits) of the digest
  • The following is the identity digest.

You can now create the new identity using the CIDv1 you want.
For instance, we’ll create the CIDv1 base36 you asked for:

First, we add the multicodec prefix libp2p-key (0x72) and the CIDv1 prefix (0x01).
Then, we encode the whole 0172002408011220CB311166BEEEDD9FB6AF4CC8C2BF4AC471DCDDE7A71FF032440747E084CF0CC8 as base36.
We get this: 51qzi5uqu50cgk08ogw8k8ck8swgoo4kww0k08k4gscwcsccg4sscog0ssw0c
We add the k base36 multibase-prefix, and we get:
k51qzi5uqu50cgk08ogw8k8ck8swgoo4kww0k08k4gscwcsccg4sscog0ssw0c

And there you go! (but you could also use the multibase/multihash/multicodec or CID lib).
(see GitHub - multiformats/cid: Self-describing content-addressed identifiers for distributed systems for more info)

2 Likes

Thanks a lot! Exactly what I was looking for and couldn’t infer by guesswork :slight_smile:

1 Like