Packages

A standalone Elixir implementation of the Libp2p networking stack

Current section

Files

Jump to
libp2p_elixir lib libp2p peer_id.ex
Raw

lib/libp2p/peer_id.ex

defmodule Libp2p.PeerId do
@moduledoc """
PeerId derivation and formatting.
PeerId bytes are a multihash of the libp2p-crypto protobuf-encoded public key.
Per `peer-ids/peer-ids.md`:
- If the protobuf-encoded public key is **<= 42 bytes**, use the **identity** multihash.
- Otherwise, use **sha2-256** multihash.
"""
alias Libp2p.Base58btc
alias Libp2p.Crypto.PublicKeyPB
alias Libp2p.Varint
# multihash codes (varints; these fit in 1 byte for our use)
@mh_identity 0x00
@mh_sha2_256 0x12
@sha2_256_len 32
@identity_max 42
@type t :: binary()
@spec from_secp256k1_pubkey_compressed(binary()) :: t()
def from_secp256k1_pubkey_compressed(pubkey33) when is_binary(pubkey33) and byte_size(pubkey33) == 33 do
pk_pb = PublicKeyPB.encode_public_key(:secp256k1, pubkey33)
from_public_key_protobuf(pk_pb)
end
@spec from_public_key_protobuf(binary()) :: t()
def from_public_key_protobuf(pk_pb) when is_binary(pk_pb) do
if byte_size(pk_pb) <= @identity_max do
# identity multihash: code + length(varint) + bytes
Varint.encode_u64(@mh_identity) <> Varint.encode_u64(byte_size(pk_pb)) <> pk_pb
else
digest = :crypto.hash(:sha256, pk_pb)
Varint.encode_u64(@mh_sha2_256) <> Varint.encode_u64(@sha2_256_len) <> digest
end
end
@spec to_base58(t()) :: binary()
def to_base58(peer_id_bytes) when is_binary(peer_id_bytes) do
Base58btc.encode(peer_id_bytes)
end
@spec from_base58(binary()) :: t()
def from_base58(str) when is_binary(str) do
Base58btc.decode(str)
end
end