// Writes encrypted frames of `sealedFrameSize` // CONTRACT: data smaller than dataMaxSize is read atomically. func (sc *SecretConnection) Write(data []byte) (n int, err error) { for 0 < len(data) { var frame []byte = make([]byte, totalFrameSize) var chunk []byte if dataMaxSize < len(data) { chunk = data[:dataMaxSize] data = data[dataMaxSize:] } else { chunk = data data = nil } chunkLength := len(chunk) binary.BigEndian.PutUint16(frame, uint16(chunkLength)) copy(frame[dataLenSize:], chunk) // encrypt the frame var sealedFrame = make([]byte, sealedFrameSize) secretbox.Seal(sealedFrame[:0], frame, sc.sendNonce, sc.shrSecret) // fmt.Printf("secretbox.Seal(sealed:%X,sendNonce:%X,shrSecret:%X\n", sealedFrame, sc.sendNonce, sc.shrSecret) incr2Nonce(sc.sendNonce) // end encryption _, err := sc.conn.Write(sealedFrame) if err != nil { return n, err } else { n += len(chunk) } } return }
// SealAfterPrecomputation performs the same actions as Seal, but takes a // shared key as generated by Precompute. func SealAfterPrecomputation(out, message []byte, nonce *[24]byte, sharedKey *[32]byte) []byte { return secretbox.Seal(out, message, nonce, sharedKey) }
// Seal appends an encrypted and authenticated copy of message to out, which // will be Overhead bytes longer than the original and must not overlap. The // nonce must be unique for each distinct message for a given pair of keys. func Seal(out, message []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) []byte { var sharedKey [32]byte Precompute(&sharedKey, peersPublicKey, privateKey) return secretbox.Seal(out, message, nonce, &sharedKey) }