2017-06-10 14:41:54 +00:00
|
|
|
package doubleratchet
|
|
|
|
|
2017-06-16 13:37:46 +00:00
|
|
|
import (
|
|
|
|
"encoding/binary"
|
2017-06-19 04:02:10 +00:00
|
|
|
"fmt"
|
2017-06-16 13:37:46 +00:00
|
|
|
)
|
|
|
|
|
2017-06-19 05:13:14 +00:00
|
|
|
// MessageHE contains ciphertext and an encrypted header.
|
2017-06-16 13:37:46 +00:00
|
|
|
type MessageHE struct {
|
2017-06-16 17:09:18 +00:00
|
|
|
Header []byte `json:"header"`
|
|
|
|
Ciphertext []byte `json:"ciphertext"`
|
2017-06-16 13:37:46 +00:00
|
|
|
}
|
|
|
|
|
2017-06-10 14:41:54 +00:00
|
|
|
// Message is a single message exchanged by the parties.
|
|
|
|
type Message struct {
|
2017-06-14 12:16:03 +00:00
|
|
|
Header MessageHeader `json:"header"`
|
|
|
|
Ciphertext []byte `json:"ciphertext"`
|
2017-06-10 14:41:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// MessageHeader that is prepended to every message.
|
|
|
|
type MessageHeader struct {
|
|
|
|
// DHr is the sender's current ratchet public key.
|
2017-06-14 12:16:03 +00:00
|
|
|
DH Key `json:"dh"`
|
2017-06-10 14:41:54 +00:00
|
|
|
|
|
|
|
// N is the number of the message in the sending chain.
|
2017-06-16 13:37:46 +00:00
|
|
|
N uint32 `json:"n"`
|
2017-06-10 14:41:54 +00:00
|
|
|
|
2017-06-11 03:16:32 +00:00
|
|
|
// PN is the length of the previous sending chain.
|
2017-06-16 13:37:46 +00:00
|
|
|
PN uint32 `json:"pn"`
|
2017-06-10 14:41:54 +00:00
|
|
|
}
|
2017-06-11 03:16:32 +00:00
|
|
|
|
2017-06-16 13:37:46 +00:00
|
|
|
// Encode the header in the binary format.
|
2017-06-19 05:13:14 +00:00
|
|
|
func (mh MessageHeader) Encode() MessageEncHeader {
|
2017-06-19 04:02:10 +00:00
|
|
|
buf := make([]byte, 8)
|
2017-06-16 13:37:46 +00:00
|
|
|
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
|
|
|
}
|
2017-06-19 05:13:14 +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))
|
|
|
|
}
|
2019-10-31 15:13:07 +00:00
|
|
|
var dh Key = make(Key, 32)
|
2017-06-19 05:13:14 +00:00
|
|
|
copy(dh[:], mh[8:40])
|
|
|
|
return MessageHeader{
|
|
|
|
DH: dh,
|
|
|
|
N: binary.LittleEndian.Uint32(mh[0:4]),
|
|
|
|
PN: binary.LittleEndian.Uint32(mh[4:8]),
|
|
|
|
}, nil
|
|
|
|
}
|