summaryrefslogtreecommitdiffstats
path: root/vendor/go.mau.fi/libsignal/groups/ratchet
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.mau.fi/libsignal/groups/ratchet')
-rw-r--r--vendor/go.mau.fi/libsignal/groups/ratchet/Doc.go3
-rw-r--r--vendor/go.mau.fi/libsignal/groups/ratchet/SenderChainKey.go68
-rw-r--r--vendor/go.mau.fi/libsignal/groups/ratchet/SenderMessageKey.go89
3 files changed, 160 insertions, 0 deletions
diff --git a/vendor/go.mau.fi/libsignal/groups/ratchet/Doc.go b/vendor/go.mau.fi/libsignal/groups/ratchet/Doc.go
new file mode 100644
index 00000000..6d374465
--- /dev/null
+++ b/vendor/go.mau.fi/libsignal/groups/ratchet/Doc.go
@@ -0,0 +1,3 @@
+// Package ratchet provides the methods necessary to establish a ratchet
+// session for group messaging.
+package ratchet
diff --git a/vendor/go.mau.fi/libsignal/groups/ratchet/SenderChainKey.go b/vendor/go.mau.fi/libsignal/groups/ratchet/SenderChainKey.go
new file mode 100644
index 00000000..a9530143
--- /dev/null
+++ b/vendor/go.mau.fi/libsignal/groups/ratchet/SenderChainKey.go
@@ -0,0 +1,68 @@
+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)
+}
diff --git a/vendor/go.mau.fi/libsignal/groups/ratchet/SenderMessageKey.go b/vendor/go.mau.fi/libsignal/groups/ratchet/SenderMessageKey.go
new file mode 100644
index 00000000..724059f2
--- /dev/null
+++ b/vendor/go.mau.fi/libsignal/groups/ratchet/SenderMessageKey.go
@@ -0,0 +1,89 @@
+package ratchet
+
+import (
+ "go.mau.fi/libsignal/kdf"
+ "go.mau.fi/libsignal/util/bytehelper"
+)
+
+// KdfInfo is optional bytes to include in deriving secrets with KDF.
+const KdfInfo string = "WhisperGroup"
+
+// NewSenderMessageKey will return a new sender message key using the given
+// iteration and seed.
+func NewSenderMessageKey(iteration uint32, seed []byte) (*SenderMessageKey, error) {
+ derivative, err := kdf.DeriveSecrets(seed, nil, []byte(KdfInfo), 48)
+ if err != nil {
+ return nil, err
+ }
+
+ // Split our derived secrets into 2 parts
+ parts := bytehelper.Split(derivative, 16, 32)
+
+ // Build the message key.
+ senderKeyMessage := &SenderMessageKey{
+ iteration: iteration,
+ seed: seed,
+ iv: parts[0],
+ cipherKey: parts[1],
+ }
+
+ return senderKeyMessage, nil
+}
+
+// NewSenderMessageKeyFromStruct will return a new message key object from the
+// given serializeable structure.
+func NewSenderMessageKeyFromStruct(structure *SenderMessageKeyStructure) *SenderMessageKey {
+ return &SenderMessageKey{
+ iteration: structure.Iteration,
+ iv: structure.IV,
+ cipherKey: structure.CipherKey,
+ seed: structure.Seed,
+ }
+}
+
+// NewStructFromSenderMessageKey returns a serializeable structure of message keys.
+func NewStructFromSenderMessageKey(key *SenderMessageKey) *SenderMessageKeyStructure {
+ return &SenderMessageKeyStructure{
+ CipherKey: key.cipherKey,
+ Iteration: key.iteration,
+ IV: key.iv,
+ Seed: key.seed,
+ }
+}
+
+// SenderMessageKeyStructure is a serializeable structure of SenderMessageKeys.
+type SenderMessageKeyStructure struct {
+ Iteration uint32
+ IV []byte
+ CipherKey []byte
+ Seed []byte
+}
+
+// SenderMessageKey is a structure for sender message keys used in group
+// messaging.
+type SenderMessageKey struct {
+ iteration uint32
+ iv []byte
+ cipherKey []byte
+ seed []byte
+}
+
+// Iteration will return the sender message key's iteration.
+func (k *SenderMessageKey) Iteration() uint32 {
+ return k.iteration
+}
+
+// Iv will return the sender message key's initialization vector.
+func (k *SenderMessageKey) Iv() []byte {
+ return k.iv
+}
+
+// CipherKey will return the key in bytes.
+func (k *SenderMessageKey) CipherKey() []byte {
+ return k.cipherKey
+}
+
+// Seed will return the sender message key's seed.
+func (k *SenderMessageKey) Seed() []byte {
+ return k.seed
+}