github.com/geph-official/geph2@v0.22.6-0.20210211030601-f527cb59b0df/libs/cryptrr/structs.go (about)

     1  package cryptrr
     2  
     3  import (
     4  	"crypto/rand"
     5  	"crypto/sha256"
     6  	"fmt"
     7  
     8  	"github.com/ethereum/go-ethereum/rlp"
     9  	"golang.org/x/crypto/chacha20poly1305"
    10  	"golang.org/x/crypto/curve25519"
    11  )
    12  
    13  // PlainMsg is a plaintext message.
    14  type PlainMsg struct {
    15  	Cmd  string
    16  	Args rlp.RawValue
    17  }
    18  
    19  // NewPlainMsg constructs a plain message.
    20  func NewPlainMsg(cmd string, args ...interface{}) PlainMsg {
    21  	aa, err := rlp.EncodeToBytes(args)
    22  	if err != nil {
    23  		panic(err)
    24  	}
    25  	return PlainMsg{
    26  		Cmd:  cmd,
    27  		Args: rlp.RawValue(aa),
    28  	}
    29  }
    30  
    31  // CiphMsg is an enciphered message.
    32  type CiphMsg struct {
    33  	LocalPK [32]byte
    34  	Nonce   [32]byte
    35  	Ctext   []byte
    36  }
    37  
    38  // Encrypt encrypts a PlainMsg to be decoded by someone holding the secret key to remotePK.
    39  func (pmsg PlainMsg) Encrypt(localSK [32]byte, remotePK [32]byte, isServer bool) CiphMsg {
    40  	payload, err := rlp.EncodeToBytes(pmsg)
    41  	if err != nil {
    42  		panic(err)
    43  	}
    44  	ss, err := curve25519.X25519(localSK[:], remotePK[:])
    45  	if err != nil {
    46  		panic(err)
    47  	}
    48  	var nonce [32]byte
    49  	rand.Read(nonce[:])
    50  	key := sha256.Sum256(append(nonce[:], append([]byte(fmt.Sprint(isServer)), ss...)...))
    51  	aead, err := chacha20poly1305.New(key[:])
    52  	if err != nil {
    53  		panic(err)
    54  	}
    55  	ctext := aead.Seal(nil, make([]byte, 12), payload, nil)
    56  	var localPK [32]byte
    57  	curve25519.ScalarBaseMult(&localPK, &localSK)
    58  	return CiphMsg{
    59  		LocalPK: localPK,
    60  		Nonce:   nonce,
    61  		Ctext:   ctext,
    62  	}
    63  }