This document specifies the minimum required features for interoperability between Pkarr implementations.
Pkarr uses z-base32 encoding to turn the 32 bytes of ed25519 public keys as Top-level domains compatible with DNS and URIs.
While a TLD should work with any URI scheme, sometimes printing the encoded public-key alone is lacking context, so it is advisable to add pk:
;
pk:o4dksfbqk85ogzdb5osziw6befigbuxmuxkuxq8434q89uj56uyy`
Implementations should be able to parse both pk:<zbase32 encoded key>
, standalone <zbase-32 encoded key>
, and preferably any 52 character TLD in any valid URI.
The canonical serialization then for Signed Pkarr packet is as follows:
SignedPacket = public-key signature timestamp dns-packet
public-key = 32 OCTET ; ed25519 public key
signature = 64 OCTET ; ed25519 signature over the timestamp and encoded DNS packet
timestamp = 8 OCTET ; big-endian UNIX timestamp in microseconds
dns-packet = * OCTET ; compressed encoded DNS answer packet, less than 1000 bytes
All resource records in the packet should be relative to the TLD (public key) that signs the packet, for example:
foo 300 A 104.21.59.30
should be converted to
foo.o4dksfbqk85ogzdb5osziw6befigbuxmuxkuxq8434q89uj56uyy 300 A 104.21.59.30
Because the TLD in Pkarr is so long, packets should be compressed when encoded. But implementations should however be able to parse uncompressed packets.
Signing follows the bep_0044 specification for signing Mutable Items, enabling SignedPackets to be published on the Mainline DHT.
The signable timestamp and dns packet is bencoded as follows:
signable = prefix dns-packet
prefix = "3:seqi" timestamp "e1:v" dns-packet-length ":"
dns-packet = * OCTET ; compressed encoded DNS answer packet, less than 1000 bytes
timestamp = 1*DIGIT ; Integer representing the timestamp
dns-packet-length = 1*DIGIT ; Integer representing the length of the encoded DNS packet
Implementations should verify the following upon receiving a candidate signed packet for public key:
Signed packets are published and resolved through Mainline Dht, using the extension to store mutable arbitrary data.
To publish a signed packet, it should be converted to a DHT put message
arguments:
DHT message field | Signed packet field |
---|---|
k | public_key bytes |
seq | timestamp |
sig | signature |
v | encoded dns packet |
The cas
, and salt
fields are ignored.
To lookups a public_key
, DHT get message
on the sha1
hash of the public_key (ignoring salt
), and optionally using the timestamp
of the most recent known signed packet for that public_key, as a seq
argument:
DHT message argument | Signed packet field |
---|---|
target | sha1(public_key) |
seq | timestamp |