iroh & IPFS
Iroh is an IPFS system. It uses content identifiers (CIDs). Content addressing is a powerful primitive that belongs at the foundation of the internet.
Iroh is not an IPFS implementation. An implementation of IPFS should be able to interoperate with kubo the reference implementation of nearly all IPFS Specs. Iroh can interoperate with kubo by bridging the two technologies, but by default one shouldn't expect to be able to add content to kubo and get it out with iroh, or vice versa.
Why not just make iroh an IPFS implementation?
At first, we did! We wrote a ground-up implementation of IPFS in rust called Beetle. We switched away because Iroh has different design goals than IPFS, and after writing an implementation, we realized couldn't achieve those goals & keep the implementation 'badge'. Iroh aims to be the smallest working foundation for building apps with sublinear scaling. The word small is the challenging one here. IPFS is designed to upgrade the entire web. To do that it has to accommodate numerous use cases and requirements that we couldn't build into iroh while keeping the project small.
Comparison Table
Here's a quick rundown on some of the core technical distinctions between IPFS & iroh:
Concept | Iroh | Kubo |
---|---|---|
CID Usage | Used for root hashes on the Blob layer | Used for all blocks |
Hash Function | BLAKE3 | Various, SHA2 by default |
Maximum Block Size | none | 1MiB |
Data Layout | Key-Value | Directed Acyclic Graphs (DAGs) |
Data Model | "Bring your own" | IPLD or "Bring your own" |
Syncing | documents | none |
Networking Stack | iroh-net | libp2p |
Public Key Cryptography | ED25519 Keys | Various, ED25519 by default |
Naming system | none | IPNS, DNSLink |
Content Storage | User Files + Cache | Internal Repository |
Verification Checkpoints | send and receive | receive |
CID Interop
If you create a file that is less than 256Kib, kubo can be configured to emit the same content:
# configure IPFS to use the BLAKE3 hash algorithm, and wrap in a directory to match iroh's default behavior
$ ipfs add file.txt --hash blake3 --wrap-with-directory
added bafkr4ig4ljhnxasawambeqcsymycobuw7ftxdjr3iusquxax2maa5artku file.txt
added bafyb4ig2hp3tqb762mg7bvuixfimok7tyn4a3b3vswlkvcphppj7j2pemi
$ iroh add file.txt
Adding file.txt as /Users/b5/file.txt...
- /Users/b5/file.txt: 12B bafkr4ig4ljhnxasawambeqcsymycobuw7ftxdjr3iusquxax2maa5artku
Total: 12B
Collection: bafkr4iatacaewbfgoqe7d4mcxtuhfxbbog57t7xpvppqgvyr2bzswlb4fy
The CID for file.txt
in both systems is bafkr4ig4ljhnxasawambeqcsymycobuw7ftxdjr3iusquxax2maa5artku
. The collection CIDs are different because directories work differently, but this small overlap between iroh & IPFS forms a foundation we can build all sorts of interop from.
If we create a file that's larger than 256Kb, however, things break down:
# create a random 1M file
$ head -c 1000000 </dev/urandom > file
$ ipfs add --hash blake3 --wrap-with-directory file.txt
added bafyb4idt2x6f35tsvvkic3uxn5377gvjohpu7ejlxjdgno73lb4yzwrca4 file
added bafyb4ia4lras4leu2lwpc57lg3xk2c4bdacabuzpunbjrl7piwug4lojiq
$ iroh add file
Adding file as /Users/b5/code/iroh.computer/file...
- /Users/b5/code/iroh.computer/file.txt: 976.56 KiB bafkr4ihr5vpp33v5ufos2dneywofls3gx67b5jmraxcn77odsu3yqcsohq
Total: 976.56 KiB
Collection: bafkr4id2xleuzonckwul47dwmaktqw6dgpudvfzmdxkitv6qmg7bwxy7hu
This is because under the hood IPFS is cutting the input file up into blocks of data so that each block can be incrementally verified during transfer. Iroh does not do this, and so the hashes are different. To address this, we need CID translation.
CID Translation
CID Translations have not been implemented in iroh yet.
CID translations are signed documents that state a content equivelancy between hashes in two different systems. Here's what a CID translation would look like for the random 1M file example above, expressed in JSON:
{
"eq": {
"iroh": "bafkr4ihr5vpp33v5ufos2dneywofls3gx67b5jmraxcn77odsu3yqcsohq",
"kubo": "bafyb4idt2x6f35tsvvkic3uxn5377gvjohpu7ejlxjdgno73lb4yzwrca4"
},
"author": "3pwjma35aeu7mmmjolslefpnlsdztyp4zwf4zwx32nnvlmzko4aa",
"signature": "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}
In english this would read "author 3pwjma35...
has said this iroh CID and that kubo CID are equal content. They point to the same bytes".
Using translations requires trusting the author of the translation. The "author" field is an iroh public key, which can be used to verify the signature field. The signature is the contents of the "eq" object.