forked from jshiffer/matterbridge
69 lines
1.7 KiB
Go
69 lines
1.7 KiB
Go
package ratchet
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
)
|
|
|
|
var messageKeySeed = []byte{0x01}
|
|
var chainKeySeed = []byte{0x02}
|
|
|
|
// NewSenderChainKey will return a new SenderChainKey.
|
|
func NewSenderChainKey(iteration uint32, chainKey []byte) *SenderChainKey {
|
|
return &SenderChainKey{
|
|
iteration: iteration,
|
|
chainKey: chainKey,
|
|
}
|
|
}
|
|
|
|
// NewSenderChainKeyFromStruct will return a new chain key object from the
|
|
// given serializeable structure.
|
|
func NewSenderChainKeyFromStruct(structure *SenderChainKeyStructure) *SenderChainKey {
|
|
return &SenderChainKey{
|
|
iteration: structure.Iteration,
|
|
chainKey: structure.ChainKey,
|
|
}
|
|
}
|
|
|
|
// NewStructFromSenderChainKeys returns a serializeable structure of chain keys.
|
|
func NewStructFromSenderChainKey(key *SenderChainKey) *SenderChainKeyStructure {
|
|
return &SenderChainKeyStructure{
|
|
Iteration: key.iteration,
|
|
ChainKey: key.chainKey,
|
|
}
|
|
}
|
|
|
|
// SenderChainKeyStructure is a serializeable structure of SenderChainKeys.
|
|
type SenderChainKeyStructure struct {
|
|
Iteration uint32
|
|
ChainKey []byte
|
|
}
|
|
|
|
type SenderChainKey struct {
|
|
iteration uint32
|
|
chainKey []byte
|
|
}
|
|
|
|
func (k *SenderChainKey) Iteration() uint32 {
|
|
return k.iteration
|
|
}
|
|
|
|
func (k *SenderChainKey) SenderMessageKey() (*SenderMessageKey, error) {
|
|
return NewSenderMessageKey(k.iteration, k.getDerivative(messageKeySeed, k.chainKey))
|
|
}
|
|
|
|
func (k *SenderChainKey) Next() *SenderChainKey {
|
|
return NewSenderChainKey(k.iteration+1, k.getDerivative(chainKeySeed, k.chainKey))
|
|
}
|
|
|
|
func (k *SenderChainKey) Seed() []byte {
|
|
return k.chainKey
|
|
}
|
|
|
|
func (k *SenderChainKey) getDerivative(seed []byte, key []byte) []byte {
|
|
mac := hmac.New(sha256.New, key[:])
|
|
mac.Write(seed)
|
|
|
|
return mac.Sum(nil)
|
|
}
|