noise is an opinionated, easy-to-use P2P network stack for decentralized applications, and cryptographic protocols written in Go.
noise is made to be minimal, robust, developer-friendly, performant, secure, and cross-platform across multitudes of devices by making use of a small amount of well-tested, production-grade dependencies.
Features
- Listen for incoming peers, query peers, and ping peers.
- Request for/respond to messages, fire-and-forget messages, and optionally automatically serialize/deserialize messages across peers.
- Optionally cancel/timeout pinging peers, sending messages to peers, receiving messages from peers, or requesting messages from peers via
context
support. - Fine-grained control over a node and peers lifecycle and goroutines and resources (synchronously/asynchronously/gracefully start listening for new peers, stop listening for new peers, send messages to a peer, disconnect an existing peer, wait for a peer to be ready, wait for a peer to have disconnected).
- Limit resource consumption by pooling connections and specifying the max number of inbound/outbound connections allowed at any given time.
- Reclaim resources exhaustively by timing out idle peers with a configurable timeout.
- Establish a shared secret by performing an Elliptic-Curve Diffie-Hellman Handshake over Curve25519.
- Establish an encrypted session amongst a pair of peers via authenticated-encryption-with-associated-data (AEAD). Built-in support for AES 256-bit Galois Counter Mode (GCM).
- Peer-to-peer routing, discovery, identities, and handshake protocol via Kademlia overlay network protocol.
Setup
go get -u github.com/perlin-network/noise
Example
package main
import (
"context"
"fmt"
"github.com/perlin-network/noise"
)
func check(err error) {
if err != nil {
panic(err)
}
}
func main() {
alice, err := noise.NewNode()
check(err)
bob, err := noise.NewNode()
check(err)
defer alice.Close()
defer bob.Close()
bob.Handle(func(ctx noise.HandlerContext) error {
if !ctx.IsRequest() {
return nil
}
fmt.Printf("Got a message from Alice: '%s'\n", string(ctx.Data()))
return ctx.Send([]byte("Hi Alice!"))
})
check(alice.Listen())
check(bob.Listen())
res, err := alice.Request(context.TODO(), bob.Addr(), []byte("Hi Bob!"))
check(err)
fmt.Printf("Got a message from Bob: '%s'\n", string(res))
}