feat: add z-base-32 encoder for iroh EndpointId hex form#145
Merged
zachsmith1 merged 2 commits intomainfrom Apr 30, 2026
Merged
feat: add z-base-32 encoder for iroh EndpointId hex form#145zachsmith1 merged 2 commits intomainfrom
zachsmith1 merged 2 commits intomainfrom
Conversation
Adds internal/iroh.EndpointHexToZ32, the encoding boundary between the hex form iroh exposes via Display (and that desktop agents write to Connector.Status.ConnectionDetails.PublicKey.Id) and the z-base-32 form iroh's DNS resolver uses to construct "_iroh.<z32>.<origin>" discovery lookup names. Verified against iroh's own z32 crate test vector (z32-1.3.0/src/lib.rs public_key test): the 32-byte public key [241, 32, 213, 46, ...] encodes to "6ropkm1nz98qqwnotqz1tryk3mrfiw9u16iwzp1usci6kbqdfwho". This is the first PR in the iroh DNS discovery controller series; no behavior change yet. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the tv42/zbase32 dependency with encoding/base32 configured with the Zooko z-base-32 alphabet and no padding — the bit-packing is identical to RFC 4648 base32, so the stdlib encoder produces byte-identical output. Drops one third-party dep. TestZ32EncodingMatchesIrohUpstream runs every (bytes, z32) pair from iroh's z32 crate test table (z32-1.3.0/src/lib.rs TEST_DATA + public_key) through the new stdlib-based encoder, spanning input lengths 0–32. All ten vectors agree, confirming alphabet, bit-packing, and trailing-bit handling match the Rust implementation iroh actually uses.
scotwells
approved these changes
Apr 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
internal/iroh.EndpointHexToZ32helper: parses the lowercase-hexEndpointIdform that desktop clients write toConnector.Status.ConnectionDetails.PublicKey.Idand re-encodes the 32 raw bytes as z-base-32, the form iroh's DNS resolver uses for_iroh.<z32>.<origin>discovery lookups.encoding/base32configured with the Zooko alphabet and no padding — z-base-32 is RFC 4648 base32 bit-packing with a different alphabet, so stdlib produces byte-identical output. No external dependency.DNSRecordSet.Why hex→z32 lives here
EndpointId::Displayis lowercase hex (iroh-base/src/key.rs:199-203), so the desktop agent writes hex into the Connector'sIdfield.EndpointId::from_strwhich accepts hex or base32 — so the gateway works with whatever string form is on disk.EndpointId::to_z32()to construct the lookup name (iroh-0.95.1/src/discovery/dns.rs:22-25,test_utils.rs:510). z-base-32 uses a distinct alphabet (ybndrfg8ejkmcpqxot1uwisza345h769) from RFC 4648 base32.Verification
TestZ32EncodingMatchesIrohUpstreamruns every(bytes, z32)pair from iroh's own z32 crate test table (z32-1.3.0/src/lib.rsTEST_DATA+ the 32-bytepublic_keytest) through the stdlib-based encoder. All ten vectors agree byte-for-byte across input lengths 0–32, confirming alphabet, bit-packing, and trailing-bit handling match.TestEndpointHexToZ32covers the wrapper: known-good vector, invalid hex, odd length, too few/many bytes, empty input.go build ./...compiles.