doubleratchet/message.go

57 lines
1.5 KiB
Go
Raw Permalink Normal View History

package doubleratchet
import (
"encoding/binary"
2017-06-19 04:02:10 +00:00
"fmt"
)
// MessageHE contains ciphertext and an encrypted header.
type MessageHE struct {
Header []byte `json:"header"`
Ciphertext []byte `json:"ciphertext"`
}
// Message is a single message exchanged by the parties.
type Message struct {
Header MessageHeader `json:"header"`
Ciphertext []byte `json:"ciphertext"`
}
// MessageHeader that is prepended to every message.
type MessageHeader struct {
// DHr is the sender's current ratchet public key.
DH Key `json:"dh"`
// N is the number of the message in the sending chain.
N uint32 `json:"n"`
2017-06-11 03:16:32 +00:00
// PN is the length of the previous sending chain.
PN uint32 `json:"pn"`
}
2017-06-11 03:16:32 +00:00
// Encode the header in the binary format.
func (mh MessageHeader) Encode() MessageEncHeader {
2017-06-19 04:02:10 +00:00
buf := make([]byte, 8)
binary.LittleEndian.PutUint32(buf[0:4], mh.N)
2017-06-19 04:02:10 +00:00
binary.LittleEndian.PutUint32(buf[4:8], mh.PN)
return append(buf, mh.DH[:]...)
2017-06-11 03:16:32 +00:00
}
// MessageEncHeader is a binary-encoded representation of a message header.
type MessageEncHeader []byte
// Decode message header out of the binary-encoded representation.
func (mh MessageEncHeader) Decode() (MessageHeader, error) {
// n (4 bytes) + pn (4 bytes) + dh (32 bytes)
if len(mh) != 40 {
return MessageHeader{}, fmt.Errorf("encoded message header must be 40 bytes, %d given", len(mh))
}
var dh Key = make(Key, 32)
copy(dh[:], mh[8:40])
return MessageHeader{
DH: dh,
N: binary.LittleEndian.Uint32(mh[0:4]),
PN: binary.LittleEndian.Uint32(mh[4:8]),
}, nil
}