{"id":34156588,"url":"https://github.com/hashmatter/libp2p-onion-routing","last_synced_at":"2026-03-11T02:02:51.157Z","repository":{"id":41512141,"uuid":"158697025","full_name":"hashmatter/libp2p-onion-routing","owner":"hashmatter","description":"in-dht onion routing using libp2p","archived":false,"fork":false,"pushed_at":"2020-03-30T12:33:26.000Z","size":8014,"stargazers_count":29,"open_issues_count":0,"forks_count":8,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-12-18T00:42:43.379Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://hashmatter.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hashmatter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-22T12:36:37.000Z","updated_at":"2025-01-26T04:30:40.000Z","dependencies_parsed_at":"2022-09-21T11:20:18.530Z","dependency_job_id":null,"html_url":"https://github.com/hashmatter/libp2p-onion-routing","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hashmatter/libp2p-onion-routing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashmatter%2Flibp2p-onion-routing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashmatter%2Flibp2p-onion-routing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashmatter%2Flibp2p-onion-routing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashmatter%2Flibp2p-onion-routing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hashmatter","download_url":"https://codeload.github.com/hashmatter/libp2p-onion-routing/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hashmatter%2Flibp2p-onion-routing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30367800,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T21:41:54.280Z","status":"online","status_checked_at":"2026-03-11T02:00:07.027Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-15T07:18:34.181Z","updated_at":"2026-03-11T02:02:51.145Z","avatar_url":"https://github.com/hashmatter.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## libp2p-onion-routing\n\n`libp2p-onion-routing` demonstrates how to use onion routing for a\nstrong privacy preserving routing protocol to be used over DHTs and other\ndecentralized networks. The onion routing aims at protecting users from \nlocal passive adversaries that spoof DHT requests to link lookups to its initiators.\n\nWe will release a video tutorial  \nwhere we go through the code and explain how use delegated lookups in \nlibp2p with onion routing and [p3lib-sphinx](https://github.com/hashmatter/p3lib).\n\n### How?\n\n[p3lib-sphinx](https://github.com/hashmatter/p3lib) is used to construct and\nprocess the onion packet.\n\n**1) *Initiator* selects set of relay nodes and gets its public keys and addresses**\n\n```go\n// discovers and connects to numRelays relays\npinfo, relayAddrs, relayPubKeys, err := selectRelays(ctx, numRelays, timeout,\nhost, kad)\n```\n\nIn production, the `selectRelays()` should select a set of relays anonymously,\ni.e., no one should be able to infer which relays were selected.\n\n**2) *Initiator* constructs the onion packet**\n\n```go\n// the payload consist of information for the exit relay (last relay in the\n// circuit) to perform the a DHT lookup. in this example, the initiator\n// delegates the lookup of the content addressed file 'QmSAR...K8Eem721p'\nvar payload [256]byte\ncopy(payload[:], []byte(\"GET QmSAR9Zw6bvVqMt35uBfnETaWkmxhZ6mWyQeRK8Eem721p\")[:])\n\n// the final address is not relevant in this context since the exit relay will\n// perform a network request (DHT lookup) rather than\n// connecting to a specific peer.\nfinalAddr := []byte(\"\")\n\n// uses p3lib-sphinx library to construct an onion routing packet\npacket, err := sphinx.NewPacket(\u0026privKey, relayPubKeys, finalAddr, relayAddrs, payload)\n```\n\n**3) *Initiator* encodes and forwards the onion packet to first relay**\n\n```go\n// encodes onion packet and wires it to the first relay in the circuit\nvar buf bytes.Buffer\nenc := gob.NewEncoder(\u0026buf)\nenc.Encode(packet)\n\n// forward packet to first relay. the relay that the packet is relayed must\n// map to the first relay in the input when constructing the onion packet\nfirstRelay := pinfo[0]\nstream, _ := host.NewStream(context.Background(), firstRelay.ID, protoPacket)\n_, err = stream.Write(buf.Bytes())\nstream.Close()\n```\n\n**4) *Relay* receives the onion packet, processes it and gets the address\nof next relay**\n\n```go\nvar packet sphinx.Packet\nout, _ := ioutil.ReadAll(stream)\n\nr := bytes.NewReader(out)\n\ndec := gob.NewDecoder(r)\ndec.Decode(\u0026packet)\n\nnextAddr, nextPacket, err := relayContext.ProcessPacket(\u0026packet)\n```\n\n**5) Step 5 repeats until last relay processes the packet**\n\n**6) After processing the packet, the *last Relay* performs DHT lookup set by\ninitiator**\n\n```go\nif nextPacket.IsLast() {\n\tlog.Println(\"LAST PACKET | exit relayer information:\")\n\n\tperformDelegatedRequest(nextPacket.Payload[:])\n\treturn\n}\n```\n\nThe circuit nodes (relays) are able to process\nthe received by \"peeling\" a layer of the onion and forward the packet to the\nnext relay. Once the packet has been all processed and forwarded by all relays \nin the circuit, the last relay will have enough information to perform the DHT \nrequest delegated by the initiator (i.e. the initial node which created the \nonion packet). The primitives for relays to process onion packets are also\nimplemented by [p3lib-sphinx](https://github.com/hashmatter/p3lib).\n\nThis *delegation pattern* in combination with provably secure\nonion encryption is similar to what is used by other anonymous P2P networks,\nsuch as [Tor](https://torproject.org).\n\n### Open problems\n\n- [ ] Implementation of SURBs in [p3lib-sphinx](https://github.com/hashmatter/p3lib)\n\nSURBs (Single Use Reply Blocks) are used to allow the exit node to send a\nresponse to the initiator through the established secure path with expected\nsecurity properties. The initiator prepares an onion packet for the exit relay\nto fill with the results and send back. \nIf you'd like to help with the SURB implementation in p3lib-sphinx, check\n[p3lib-sphinx](https://github.com/hashmatter/p3lib).\n\n- [ ] Scalable and anonymous relay selection with partial network view\n\n- [ ] Measure and understand entropy requirements for security\n\nThere are many more open problems to achieve practical metadata resistance in\ndistributed hash tables and P2P networks. If you are interested in discussing\nand working on these problems, check what [hashmatter](https://hashmatter.com)\nhas been working on and reach out!\n\n### Why?\n\nBecause we all want security, privacy and decentralized networks to go \nmainstream! Also check [In Pursuit of Private DHTs](https://www.gpestana.com/blog/in-pursuit-of-private-dhts/)!\n\n### Please note!\n\nThe code in this repository is part of an experimental research project to \nimplement practical privacy preserving network protocols and primitives. The\ncode in this repo is **highly experimental** and for demo purposes only, do not\nuse it in production.\n\nPlease bear in mind that the relay discovery protocol used in this repo will \ndefeat the purposes of onion routing security by the identity of the initiator\nto all the relays in the circuit. This is not safe and should not be used in\nproduction.\n\n## Further reading\n\n[0] [Privacy preserving DHTs](https://github.com/gpestana/notes/issues/8)\n\n[1] [Privacy preserving lookups with In-DHT Onion Routing](https://github.com/gpestana/notes/blob/master/research/metadata_resistant_dht/onion_routing_paper/onion_routing_dht.pdf/)\n\n[2] [Sphinx: A Compact and Provably Secure Mix Format](https://cypherpunks.ca/~iang/pubs/Sphinx_Oakland09.pdf)\n\n[3] [Using Sphinx to Improve Onion Routing Circuit Construction](https://eprint.iacr.org/2009/628.pdf)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhashmatter%2Flibp2p-onion-routing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhashmatter%2Flibp2p-onion-routing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhashmatter%2Flibp2p-onion-routing/lists"}