1 // Package noise provides a net.Conn-like interface for a
2 // Noise_NK_25519_ChaChaPoly_BLAKE2s. It encodes Noise messages onto a reliable
3 // stream using 16-bit length prefixes.
5 // https://noiseprotocol.org/noise.html
17 "github.com/flynn/noise"
18 "golang.org/x/crypto/curve25519"
21 // The length of public and private keys as returned by GeneratePrivkey.
25 MsgTypeHandshakeInit
= 1
26 MsgTypeHandshakeResp
= 2
30 // cipherSuite represents 25519_ChaChaPoly_BLAKE2s.
31 var cipherSuite
= noise
.NewCipherSuite(noise
.DH25519
, noise
.CipherChaChaPoly
, noise
.HashBLAKE2s
)
33 func ReadMessageFrom(conn net
.PacketConn
) (byte, []byte, net
.Addr
, error
) {
36 n
, addr
, err
:= conn
.ReadFrom(buf
[:])
38 return 0, nil, nil, err
41 return buf
[0], buf
[1:n
], addr
, nil
46 // newConfig instantiates configuration settings that are common to clients and
48 func newConfig() noise
.Config
{
50 CipherSuite
: cipherSuite
,
51 Pattern
: noise
.HandshakeNK
,
52 Prologue
: []byte("Champa 2021-06-17"),
56 // GeneratePrivkey generates a private key. The corresponding private key can be
57 // generated using PubkeyFromPrivkey.
58 func GeneratePrivkey() ([]byte, error
) {
59 pair
, err
:= noise
.DH25519
.GenerateKeypair(rand
.Reader
)
60 return pair
.Private
, err
63 // PubkeyFromPrivkey returns the public key that corresponds to privkey.
64 func PubkeyFromPrivkey(privkey
[]byte) []byte {
65 pubkey
, err
:= curve25519
.X25519(privkey
, curve25519
.Basepoint
)
72 // ReadKey reads a hex-encoded key from r. r must consist of a single line, with
73 // or without a '\n' line terminator. The line must consist of KeyLen
75 func ReadKey(r io
.Reader
) ([]byte, error
) {
76 br
:= bufio
.NewReader(io
.LimitReader(r
, 100))
77 line
, err
:= br
.ReadString('\n')
82 // Check that we're at EOF.
83 _
, err
= br
.ReadByte()
86 } else if err
== nil {
87 err
= fmt
.Errorf("file contains more than one line")
93 line
= strings
.TrimSuffix(line
, "\n")
94 return DecodeKey(line
)
97 // WriteKey writes the hex-encoded key in a single line to w.
98 func WriteKey(w io
.Writer
, key
[]byte) error
{
99 _
, err
:= fmt
.Fprintf(w
, "%x\n", key
)
103 // DecodeKey decodes a hex-encoded private or public key.
104 func DecodeKey(s
string) ([]byte, error
) {
105 key
, err
:= hex
.DecodeString(s
)
106 if err
== nil && len(key
) != KeyLen
{
107 err
= fmt
.Errorf("length is %d, expected %d", len(key
), KeyLen
)
112 // EncodeKey encodes a hex-encoded private or public key.
113 func EncodeKey(key
[]byte) string {
114 return hex
.EncodeToString(key
)