Skip to content
A decentralized P2P networking stack written in Go.
Go Assembly
Branch: master
Clone or download
iwasaki-kenta Merge pull request #213 from perlin-network/fix-peer-disconnect
Fix a bug that happens when peer's connection is closed by the dialler.
Latest commit f9c1f15 Mar 5, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
callbacks Fix race condition over the network for AEAD. (#209) Feb 17, 2019
cipher/aead aead: allow for custom AEAD cipher suites Feb 19, 2019
docs docs, eddsa: update documentation Feb 22, 2019
examples examples/chat: disable NAT traversal by default Feb 19, 2019
handshake/ecdh ecdh: allow for setting of handshake message contents Feb 19, 2019
identity identity, signature, eddsa: separate out sign/verify interfaces from … Feb 22, 2019
internal Fix logic for gracefully stopping nodes/peers. (#210) Feb 17, 2019
log aead: improve tests Feb 14, 2019
nat nat: add IPv4 loopback address to IsPrivateIP() Feb 19, 2019
payload peer, skademlia: removed need to specify opcode for sending/broadcast… Feb 13, 2019
protocol peer: fix a bug in case of peer's connection is closed by the dialler… Mar 5, 2019
signature eddsa: make test for 100% coverage Feb 22, 2019
skademlia identity, signature, eddsa: separate out sign/verify interfaces from … Feb 22, 2019
transport tcp: remove host constraint when listening Feb 19, 2019
.codecov.yml codecov: updated ignore list Feb 13, 2019
.gitignore docs, readme: add mdbook Feb 19, 2019
.travis.yml ci: fixed travis config Feb 19, 2019
LICENSE all: rebase on master Feb 10, 2019
README.md readme: updated contents Feb 19, 2019
callbacks.go all: rebase on master Feb 10, 2019
empty.go codecov: updated ignore list Feb 13, 2019
go.mod aead, ecdh, skademlia: replaced Schnorr signatures for assembly-optim… Feb 16, 2019
go.sum aead, ecdh, skademlia: replaced Schnorr signatures for assembly-optim… Feb 16, 2019
init.go
msg.go codecov: updated ignore list Feb 13, 2019
msg_test.go aead: use single proto block Feb 15, 2019
node.go node, peer: updated docs Feb 19, 2019
node_test.go node/test: add a sleep after closing the connection because it's not … Mar 5, 2019
opcode.go codecov: updated ignore list Feb 13, 2019
opcode_test.go opcode/test: add more tests Feb 15, 2019
params.go node, nat: support specifying an external port for NAT traversal purp… Feb 17, 2019
params_test.go Tests and fixes for noise.Node, and `protocol` package. (#206) Feb 14, 2019
peer.go peer: fix a bug in case of peer's connection is closed by the dialler… Mar 5, 2019
peer_test.go peer: fix a bug in case of peer's connection is closed by the dialler… Mar 5, 2019

README.md

Noise

GoDoc Discord MIT licensed Build Status Go Report Card Coverage Statusd

noise is an opinionated, easy-to-use P2P network stack for decentralized applications, and cryptographic protocols written in Go by the Perlin team.

noise is made to be robust, developer-friendly, performant, secure, and cross-platform across multitudes of devices by making use of well-tested, production-grade dependencies.


By itself, noise is a low-level, stateless, concurrent networking library that easily allows you to incorporate fundamental features any modern p2p application needs such as:

  1. cryptographic primitives (Ed25519, PoW, AES-256),
  2. message serialization/deserialization schemes (byte-order little endian, protobuf, msgpack),
  3. network timeout/error management (on dial, on receive message, on send buffer full),
  4. network-level atomic operations (receive-then-lock),
  5. and NAT traversal support (NAT-PMP, UPnP).

Out of its own low-level constructs, noise additionally comes bundled with a high-level protocol package comprised of a large number of production-ready, high-level protocol building blocks such as:

  1. handshake protocol implementations (Elliptic-Curve Diffie Hellman),
  2. peer routing/discovery protocol implementations (S/Kademlia),
  3. message broadcasting protocol implementations (S/Kademlia),
  4. overlay network protocol implementations (S/Kademlia),
  5. cryptographic identity schemes (Ed25519 w/ EdDSA signatures),
  6. and authenticated encryption schemes (AES-256 GCM AEAD).

Every single building block is easily configurable, and may be mixed and matched together to help you kickstart your journey on developing secure, debuggable, and highly-performant p2p applications.

package main

import (
    "fmt"
	
    "github.com/perlin-network/noise"
    "github.com/perlin-network/noise/cipher/aead"
    "github.com/perlin-network/noise/handshake/ecdh"
    "github.com/perlin-network/noise/identity/ed25519"
    "github.com/perlin-network/noise/protocol"
    "github.com/perlin-network/noise/rpc"
    "github.com/perlin-network/noise/skademlia"
)

type chatMessage struct {
	text string
}

func (chatMessage) Read(reader payload.Reader) (noise.Message, error) {
	text, err := reader.ReadString()
	if err != nil {
		return nil, errors.Wrap(err, "failed to read chat msg")
	}

	return chatMessage{text: text}, nil
}

func (m chatMessage) Write() []byte {
	return payload.NewWriter(nil).WriteString(m.text).Bytes()
}

func main() {
    // Register message type to Noise.
    opcodeChatMessage := noise.RegisterMessage(noise.NextAvailableOpcode(), (*chatMessage)(nil))
    
    params := noise.DefaultParams()
    params.Keys = ed25519.Random()
    params.Port = uint16(3000)
    
    node, err := noise.NewNode(params)
    if err != nil {
        panic(err)
    }
    
    protocol.New().
    	Register(ecdh.New()).
    	Register(aead.New()).
    	Register(skademlia.New()).
    	Enforce(node)
    
    fmt.Printf("Listening for peers on port %d.\n", node.ExternalPort())
    
    go node.Listen()
    
    // Dial peer via TCP located at address 127.0.0.1:3001.
    peer, err := node.Dial("127.0.0.1:3001")
    if err != nil {
        panic(err)
    }
    
    // Wait until the peer has finished all cryptographic handshake procedures.
    skademlia.WaitUntilAuthenticated(peer)
    
    // Send a single chat message over the peer knowing that it's encrypted over the wire.
    err = peer.SendMessage(chatMessage{text: "Hello peer!"})
    if err != nil {
        panic(err)
    }
    
    // Receive and print out a single chat message back from our peer.
    fmt.Println(<-peer.Receive(opcodeChatMessage))
}

Setup

Make sure to have at the bare minimum Go 1.11 installed before incorporating noise into your project.

After installing Go, you may choose to either:

  1. directly incorporate noise as a library dependency to your project,
# Be sure to have Go modules enabled: https://github.com/golang/go/wiki/Modules
export GO111MODULE=on

# Run this inside your projects directory.
go get github.com/perlin-network/noise
  1. or checkout the source code on Github and run any of the following commands below.
# Be sure to have Go modules enabled: https://github.com/golang/go/wiki/Modules
export GO111MODULE=on

# Run an example creating a cluster of 3 peers automatically
# discovering one another.
[terminal 1] go run examples/chat/main.go -p 3000
[terminal 2] go run examples/chat/main.go -p 3001 127.0.0.1:3000
[terminal 3] go run examples/chat/main.go -p 3002 127.0.0.1:3001

# Optionally run test cases.
go test -v -count=1 -race ./...

We're hiring!

Here at Perlin, we spend days and weeks debating, tinkering, and researching what is out there in academia to bring to industries truly resilient, open-source, secure, economic, and decentralized software to empower companies, startups, and users.

Our doors are open to academics that have a knack for distributed systems, engineers that want to explore unknown waters, frontend developers that want to make and evangelize the next generation of customer-facing applications, and graphics designers that yearn to instrument together greater user experiences for decentralized applications.

Contributions

First of all, thank you so much for taking part in our efforts for creating a p2p networking stack that can meet everyones needs without sacrificing developer productivity!

All code contributions to noise should comply with all idiomatic Go standards listed here.

All commit messages should be in the format:

module_name_1, module_name_2: description of the changes you made to the two
    modules here as a sentence

Be sure to use only imperative, present tense within your commit messages and optionally include motivation for your changes two lines breaks away from your commit message.

This allows other maintainers and contributors to know which modules you are modifying/creating within the code/docs repository.

Lastly, be sure to consider backwards compatibility.

New modules/methods are perfectly fine, but changing code living in noise.Node or noise.Peer radically for example would break a lot of existing projects utilizing noise.

Additionally, if you'd like to talk to us or any of the team in real-time, be sure to join our Discord server!

We are heavily active, ready to answer any questions/assist you with any code/doc contributions at almost any time.

License

noise, and all of its source code is released under the MIT License.

You can’t perform that action at this time.