mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-07-04 04:17:45 +00:00
Add dependencies/vendor (whatsapp)
This commit is contained in:
127
vendor/go.mau.fi/libsignal/keys/chain/ChainKey.go
vendored
Normal file
127
vendor/go.mau.fi/libsignal/keys/chain/ChainKey.go
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
// Package chain provides chain keys used in double ratchet sessions.
|
||||
package chain
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"go.mau.fi/libsignal/kdf"
|
||||
"go.mau.fi/libsignal/keys/message"
|
||||
)
|
||||
|
||||
var messageKeySeed = []byte{0x01}
|
||||
var chainKeySeed = []byte{0x02}
|
||||
|
||||
// NewKey returns a new chain key with the given kdf, key, and index
|
||||
func NewKey(kdf kdf.HKDF, key []byte, index uint32) *Key {
|
||||
chainKey := Key{
|
||||
kdf: kdf,
|
||||
key: key,
|
||||
index: index,
|
||||
}
|
||||
|
||||
return &chainKey
|
||||
}
|
||||
|
||||
// NewKeyFromStruct will return a chain key built from the given structure.
|
||||
func NewKeyFromStruct(structure *KeyStructure, kdf kdf.HKDF) *Key {
|
||||
return NewKey(
|
||||
kdf,
|
||||
structure.Key,
|
||||
structure.Index,
|
||||
)
|
||||
}
|
||||
|
||||
// NewStructFromKey will return a chain key structure for serialization.
|
||||
func NewStructFromKey(key *Key) *KeyStructure {
|
||||
return &KeyStructure{
|
||||
Key: key.key,
|
||||
Index: key.index,
|
||||
}
|
||||
}
|
||||
|
||||
// KeyStructure is a serializeable structure for chain keys.
|
||||
type KeyStructure struct {
|
||||
Key []byte
|
||||
Index uint32
|
||||
}
|
||||
|
||||
// Key is used for generating message keys. This key "ratchets" every time a
|
||||
// message key is generated. Every time the chain key ratchets forward, its index
|
||||
// increases by one.
|
||||
type Key struct {
|
||||
kdf kdf.HKDF
|
||||
key []byte
|
||||
index uint32 // Index's maximum size: 4,294,967,295
|
||||
}
|
||||
|
||||
// Current returns the current ChainKey struct.
|
||||
func (c *Key) Current() *Key {
|
||||
return c
|
||||
}
|
||||
|
||||
// Key returns the ChainKey's key material.
|
||||
func (c *Key) Key() []byte {
|
||||
return c.key
|
||||
}
|
||||
|
||||
// SetKey will set the ChainKey's key material.
|
||||
func (c *Key) SetKey(key []byte) {
|
||||
c.key = key
|
||||
}
|
||||
|
||||
// Index returns how many times the ChainKey has been "ratcheted" forward.
|
||||
func (c *Key) Index() uint32 {
|
||||
return c.index
|
||||
}
|
||||
|
||||
// SetIndex sets how many times the ChainKey has been "ratcheted" forward.
|
||||
func (c *Key) SetIndex(index uint32) {
|
||||
c.index = index
|
||||
}
|
||||
|
||||
// NextKey uses the key derivation function to generate a new ChainKey.
|
||||
func (c *Key) NextKey() *Key {
|
||||
nextKey := c.BaseMaterial(chainKeySeed)
|
||||
return NewKey(c.kdf, nextKey, c.index+1)
|
||||
}
|
||||
|
||||
// MessageKeys returns message keys, which includes the cipherkey, mac, iv, and index.
|
||||
func (c *Key) MessageKeys() *message.Keys {
|
||||
inputKeyMaterial := c.BaseMaterial(messageKeySeed)
|
||||
keyMaterialBytes, _ := c.kdf(inputKeyMaterial, nil, []byte(message.KdfSalt), message.DerivedSecretsSize)
|
||||
keyMaterial := newKeyMaterial(keyMaterialBytes)
|
||||
|
||||
// Use the key material returned from the key derivation function for our cipherkey, mac, and iv.
|
||||
messageKeys := message.NewKeys(
|
||||
keyMaterial.CipherKey, // Use the first 32 bytes of the key material for the CipherKey
|
||||
keyMaterial.MacKey, // Use bytes 32-64 of the key material for the MacKey
|
||||
keyMaterial.IV, // Use the last 16 bytes for the IV.
|
||||
c.Index(), // Attach the chain key's index to the message keys.
|
||||
)
|
||||
|
||||
return messageKeys
|
||||
}
|
||||
|
||||
// BaseMaterial uses hmac to derive the base material used in the key derivation function for a new key.
|
||||
func (c *Key) BaseMaterial(seed []byte) []byte {
|
||||
mac := hmac.New(sha256.New, c.key[:])
|
||||
mac.Write(seed)
|
||||
|
||||
return mac.Sum(nil)
|
||||
}
|
||||
|
||||
// NewKeyMaterial takes an 80-byte slice derived from a key derivation function and splits
|
||||
// it into the cipherkey, mac, and iv.
|
||||
func newKeyMaterial(keyMaterialBytes []byte) *kdf.KeyMaterial {
|
||||
cipherKey := keyMaterialBytes[:32] // Use the first 32 bytes of the key material for the CipherKey
|
||||
macKey := keyMaterialBytes[32:64] // Use bytes 32-64 of the key material for the MacKey
|
||||
iv := keyMaterialBytes[64:80] // Use the last 16 bytes for the IV.
|
||||
|
||||
keyMaterial := kdf.KeyMaterial{
|
||||
CipherKey: cipherKey,
|
||||
MacKey: macKey,
|
||||
IV: iv,
|
||||
}
|
||||
|
||||
return &keyMaterial
|
||||
}
|
47
vendor/go.mau.fi/libsignal/keys/identity/IdentityKey.go
vendored
Normal file
47
vendor/go.mau.fi/libsignal/keys/identity/IdentityKey.go
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
// Package identity provides identity keys used for verifying the identity
|
||||
// of a signal user.
|
||||
package identity
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"go.mau.fi/libsignal/ecc"
|
||||
)
|
||||
|
||||
// NewKey generates a new IdentityKey from an ECPublicKey
|
||||
func NewKey(publicKey ecc.ECPublicKeyable) *Key {
|
||||
identityKey := Key{
|
||||
publicKey: publicKey,
|
||||
}
|
||||
|
||||
return &identityKey
|
||||
}
|
||||
|
||||
// NewKeyFromBytes generates a new IdentityKey from public key bytes
|
||||
func NewKeyFromBytes(publicKey [32]byte, offset int) Key {
|
||||
identityKey := Key{
|
||||
publicKey: ecc.NewDjbECPublicKey(publicKey),
|
||||
}
|
||||
|
||||
return identityKey
|
||||
}
|
||||
|
||||
// Key is a structure for representing an identity key. This same structure can
|
||||
// be used for verifying recipient's identity key or storing our own identity key.
|
||||
type Key struct {
|
||||
publicKey ecc.ECPublicKeyable
|
||||
}
|
||||
|
||||
// Fingerprint gets the string fingerprint representation of the public key.
|
||||
func (k *Key) Fingerprint() string {
|
||||
return hex.EncodeToString(k.publicKey.Serialize())
|
||||
}
|
||||
|
||||
// PublicKey returns the EC Public key of the identity key
|
||||
func (k *Key) PublicKey() ecc.ECPublicKeyable {
|
||||
return k.publicKey
|
||||
}
|
||||
|
||||
// Serialize returns the serialized version of the key
|
||||
func (k *Key) Serialize() []byte {
|
||||
return k.publicKey.Serialize()
|
||||
}
|
39
vendor/go.mau.fi/libsignal/keys/identity/IdentityKeyPair.go
vendored
Normal file
39
vendor/go.mau.fi/libsignal/keys/identity/IdentityKeyPair.go
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
package identity
|
||||
|
||||
import (
|
||||
"go.mau.fi/libsignal/ecc"
|
||||
)
|
||||
|
||||
// NewKeyPair returns a new identity key with the given public and private keys.
|
||||
func NewKeyPair(publicKey *Key, privateKey ecc.ECPrivateKeyable) *KeyPair {
|
||||
keyPair := KeyPair{
|
||||
publicKey: publicKey,
|
||||
privateKey: privateKey,
|
||||
}
|
||||
|
||||
return &keyPair
|
||||
}
|
||||
|
||||
// NewKeyPairFromBytes returns a new identity key from the given serialized bytes.
|
||||
//func NewKeyPairFromBytes(serialized []byte) KeyPair {
|
||||
//}
|
||||
|
||||
// KeyPair is a holder for public and private identity key pair.
|
||||
type KeyPair struct {
|
||||
publicKey *Key
|
||||
privateKey ecc.ECPrivateKeyable
|
||||
}
|
||||
|
||||
// PublicKey returns the identity key's public key.
|
||||
func (k *KeyPair) PublicKey() *Key {
|
||||
return k.publicKey
|
||||
}
|
||||
|
||||
// PrivateKey returns the identity key's private key.
|
||||
func (k *KeyPair) PrivateKey() ecc.ECPrivateKeyable {
|
||||
return k.privateKey
|
||||
}
|
||||
|
||||
// Serialize returns a byte array that represents the keypair.
|
||||
//func (k *KeyPair) Serialize() []byte {
|
||||
//}
|
91
vendor/go.mau.fi/libsignal/keys/message/MessageKey.go
vendored
Normal file
91
vendor/go.mau.fi/libsignal/keys/message/MessageKey.go
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
// Package message provides a structure for message keys, which are symmetric
|
||||
// keys used for the encryption/decryption of Signal messages.
|
||||
package message
|
||||
|
||||
// DerivedSecretsSize is the size of the derived secrets for message keys.
|
||||
const DerivedSecretsSize = 80
|
||||
|
||||
// CipherKeyLength is the length of the actual cipher key used for messages.
|
||||
const CipherKeyLength = 32
|
||||
|
||||
// MacKeyLength is the length of the message authentication code in bytes.
|
||||
const MacKeyLength = 32
|
||||
|
||||
// IVLength is the length of the initialization vector in bytes.
|
||||
const IVLength = 16
|
||||
|
||||
// KdfSalt is used as the Salt for message keys to derive secrets using a Key Derivation Function
|
||||
const KdfSalt string = "WhisperMessageKeys"
|
||||
|
||||
// NewKeys returns a new message keys structure with the given cipherKey, mac, iv, and index.
|
||||
func NewKeys(cipherKey, macKey, iv []byte, index uint32) *Keys {
|
||||
messageKeys := Keys{
|
||||
cipherKey: cipherKey,
|
||||
macKey: macKey,
|
||||
iv: iv,
|
||||
index: index,
|
||||
}
|
||||
|
||||
return &messageKeys
|
||||
}
|
||||
|
||||
// NewKeysFromStruct will return a new message keys object from the
|
||||
// given serializeable structure.
|
||||
func NewKeysFromStruct(structure *KeysStructure) *Keys {
|
||||
return NewKeys(
|
||||
structure.CipherKey,
|
||||
structure.MacKey,
|
||||
structure.IV,
|
||||
structure.Index,
|
||||
)
|
||||
}
|
||||
|
||||
// NewStructFromKeys returns a serializeable structure of message keys.
|
||||
func NewStructFromKeys(keys *Keys) *KeysStructure {
|
||||
return &KeysStructure{
|
||||
CipherKey: keys.cipherKey,
|
||||
MacKey: keys.macKey,
|
||||
IV: keys.iv,
|
||||
Index: keys.index,
|
||||
}
|
||||
}
|
||||
|
||||
// KeysStructure is a serializeable structure of message keys.
|
||||
type KeysStructure struct {
|
||||
CipherKey []byte
|
||||
MacKey []byte
|
||||
IV []byte
|
||||
Index uint32
|
||||
}
|
||||
|
||||
// Keys is a structure to hold all the keys for a single MessageKey, including the
|
||||
// cipherKey, mac, iv, and index of the chain key. MessageKeys are used to
|
||||
// encrypt individual messages.
|
||||
type Keys struct {
|
||||
cipherKey []byte
|
||||
macKey []byte
|
||||
iv []byte
|
||||
index uint32
|
||||
}
|
||||
|
||||
// CipherKey is the key used to produce ciphertext.
|
||||
func (k *Keys) CipherKey() []byte {
|
||||
return k.cipherKey
|
||||
}
|
||||
|
||||
// MacKey returns the message's message authentication code.
|
||||
func (k *Keys) MacKey() []byte {
|
||||
return k.macKey
|
||||
}
|
||||
|
||||
// Iv returns the message keys' initialization vector. The IV is a fixed-size input
|
||||
// to a cryptographic primitive.
|
||||
func (k *Keys) Iv() []byte {
|
||||
return k.iv
|
||||
}
|
||||
|
||||
// Index returns the number of times the chain key has been put through a key derivation
|
||||
// function to generate this message key.
|
||||
func (k *Keys) Index() uint32 {
|
||||
return k.index
|
||||
}
|
86
vendor/go.mau.fi/libsignal/keys/prekey/PreKeyBundle.go
vendored
Normal file
86
vendor/go.mau.fi/libsignal/keys/prekey/PreKeyBundle.go
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
// Package prekey provides prekey bundle structures for calculating
|
||||
// a new Signal session with a user asyncronously.
|
||||
package prekey
|
||||
|
||||
import (
|
||||
"go.mau.fi/libsignal/ecc"
|
||||
"go.mau.fi/libsignal/keys/identity"
|
||||
"go.mau.fi/libsignal/util/optional"
|
||||
)
|
||||
|
||||
// NewBundle returns a Bundle structure that contains a remote PreKey
|
||||
// and collection of associated items.
|
||||
func NewBundle(registrationID, deviceID uint32, preKeyID *optional.Uint32, signedPreKeyID uint32,
|
||||
preKeyPublic, signedPreKeyPublic ecc.ECPublicKeyable, signedPreKeySig [64]byte,
|
||||
identityKey *identity.Key) *Bundle {
|
||||
|
||||
bundle := Bundle{
|
||||
registrationID: registrationID,
|
||||
deviceID: deviceID,
|
||||
preKeyID: preKeyID,
|
||||
preKeyPublic: preKeyPublic,
|
||||
signedPreKeyID: signedPreKeyID,
|
||||
signedPreKeyPublic: signedPreKeyPublic,
|
||||
signedPreKeySignature: signedPreKeySig,
|
||||
identityKey: identityKey,
|
||||
}
|
||||
|
||||
return &bundle
|
||||
}
|
||||
|
||||
// Bundle is a structure that contains a remote PreKey and collection
|
||||
// of associated items.
|
||||
type Bundle struct {
|
||||
registrationID uint32
|
||||
deviceID uint32
|
||||
preKeyID *optional.Uint32
|
||||
preKeyPublic ecc.ECPublicKeyable
|
||||
signedPreKeyID uint32
|
||||
signedPreKeyPublic ecc.ECPublicKeyable
|
||||
signedPreKeySignature [64]byte
|
||||
identityKey *identity.Key
|
||||
}
|
||||
|
||||
// DeviceID returns the device ID this PreKey belongs to.
|
||||
func (b *Bundle) DeviceID() uint32 {
|
||||
return b.deviceID
|
||||
}
|
||||
|
||||
// PreKeyID returns the unique key ID for this PreKey.
|
||||
func (b *Bundle) PreKeyID() *optional.Uint32 {
|
||||
return b.preKeyID
|
||||
}
|
||||
|
||||
// PreKey returns the public key for this PreKey.
|
||||
func (b *Bundle) PreKey() ecc.ECPublicKeyable {
|
||||
return b.preKeyPublic
|
||||
}
|
||||
|
||||
// SignedPreKeyID returns the unique key ID for this
|
||||
// signed PreKey.
|
||||
func (b *Bundle) SignedPreKeyID() uint32 {
|
||||
return b.signedPreKeyID
|
||||
}
|
||||
|
||||
// SignedPreKey returns the signed PreKey for this
|
||||
// PreKeyBundle.
|
||||
func (b *Bundle) SignedPreKey() ecc.ECPublicKeyable {
|
||||
return b.signedPreKeyPublic
|
||||
}
|
||||
|
||||
// SignedPreKeySignature returns the signature over the
|
||||
// signed PreKey.
|
||||
func (b *Bundle) SignedPreKeySignature() [64]byte {
|
||||
return b.signedPreKeySignature
|
||||
}
|
||||
|
||||
// IdentityKey returns the Identity Key of this PreKey's owner.
|
||||
func (b *Bundle) IdentityKey() *identity.Key {
|
||||
return b.identityKey
|
||||
}
|
||||
|
||||
// RegistrationID returns the registration ID associated with
|
||||
// this PreKey.
|
||||
func (b *Bundle) RegistrationID() uint32 {
|
||||
return b.registrationID
|
||||
}
|
66
vendor/go.mau.fi/libsignal/keys/root/RootKey.go
vendored
Normal file
66
vendor/go.mau.fi/libsignal/keys/root/RootKey.go
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
// Package root provides root keys which are used to derive new chain and
|
||||
// root keys in a ratcheting session.
|
||||
package root
|
||||
|
||||
import (
|
||||
"go.mau.fi/libsignal/ecc"
|
||||
"go.mau.fi/libsignal/kdf"
|
||||
"go.mau.fi/libsignal/keys/chain"
|
||||
"go.mau.fi/libsignal/keys/session"
|
||||
)
|
||||
|
||||
// DerivedSecretsSize is the size of the derived secrets for root keys.
|
||||
const DerivedSecretsSize = 64
|
||||
|
||||
// KdfInfo is used as the info for message keys to derive secrets using a Key Derivation Function
|
||||
const KdfInfo string = "WhisperRatchet"
|
||||
|
||||
// NewKey returns a new RootKey given the key derivation function and bytes.
|
||||
func NewKey(kdf kdf.HKDF, key []byte) *Key {
|
||||
rootKey := Key{
|
||||
kdf: kdf,
|
||||
key: key,
|
||||
}
|
||||
|
||||
return &rootKey
|
||||
}
|
||||
|
||||
// Key is a structure for RootKeys, which are used to derive a new set of chain and root
|
||||
// keys for every round trip of messages.
|
||||
type Key struct {
|
||||
kdf kdf.HKDF
|
||||
key []byte
|
||||
}
|
||||
|
||||
// Bytes returns the RootKey in bytes.
|
||||
func (k *Key) Bytes() []byte {
|
||||
return k.key
|
||||
}
|
||||
|
||||
// CreateChain creates a new RootKey and ChainKey from the recipient's ratchet key and our private key.
|
||||
func (k *Key) CreateChain(theirRatchetKey ecc.ECPublicKeyable, ourRatchetKey *ecc.ECKeyPair) (*session.KeyPair, error) {
|
||||
theirPublicKey := theirRatchetKey.PublicKey()
|
||||
ourPrivateKey := ourRatchetKey.PrivateKey().Serialize()
|
||||
|
||||
// Use our key derivation function to calculate a shared secret.
|
||||
sharedSecret := kdf.CalculateSharedSecret(theirPublicKey, ourPrivateKey)
|
||||
derivedSecretBytes, err := kdf.DeriveSecrets(sharedSecret[:], k.key, []byte(KdfInfo), DerivedSecretsSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Split the derived secret bytes in half, using one half for the root key and the second for the chain key.
|
||||
derivedSecrets := session.NewDerivedSecrets(derivedSecretBytes)
|
||||
|
||||
// Create new root and chain key structures from the derived secrets.
|
||||
rootKey := NewKey(k.kdf, derivedSecrets.RootKey())
|
||||
chainKey := chain.NewKey(k.kdf, derivedSecrets.ChainKey(), 0)
|
||||
|
||||
// Create a session keypair with the generated root and chain keys.
|
||||
keyPair := session.NewKeyPair(
|
||||
rootKey,
|
||||
chainKey,
|
||||
)
|
||||
|
||||
return keyPair, nil
|
||||
}
|
29
vendor/go.mau.fi/libsignal/keys/session/DerivedSecrets.go
vendored
Normal file
29
vendor/go.mau.fi/libsignal/keys/session/DerivedSecrets.go
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
package session
|
||||
|
||||
// NewDerivedSecrets returns a new RootKey/ChainKey pair from 64 bytes of key material
|
||||
// generated by the key derivation function.
|
||||
func NewDerivedSecrets(keyMaterial []byte) *DerivedSecrets {
|
||||
secrets := DerivedSecrets{
|
||||
keyMaterial[:32],
|
||||
keyMaterial[32:],
|
||||
}
|
||||
|
||||
return &secrets
|
||||
}
|
||||
|
||||
// DerivedSecrets is a structure for holding the derived secrets for the
|
||||
// Root and Chain keys for a session.
|
||||
type DerivedSecrets struct {
|
||||
rootKey []byte
|
||||
chainKey []byte
|
||||
}
|
||||
|
||||
// RootKey returns the RootKey bytes.
|
||||
func (d *DerivedSecrets) RootKey() []byte {
|
||||
return d.rootKey
|
||||
}
|
||||
|
||||
// ChainKey returns the ChainKey bytes.
|
||||
func (d *DerivedSecrets) ChainKey() []byte {
|
||||
return d.chainKey
|
||||
}
|
43
vendor/go.mau.fi/libsignal/keys/session/Pair.go
vendored
Normal file
43
vendor/go.mau.fi/libsignal/keys/session/Pair.go
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
// Package session provides a simple structure for session keys, which is
|
||||
// a pair of root and chain keys for a session.
|
||||
package session
|
||||
|
||||
import (
|
||||
"go.mau.fi/libsignal/ecc"
|
||||
"go.mau.fi/libsignal/keys/chain"
|
||||
"go.mau.fi/libsignal/keys/message"
|
||||
)
|
||||
|
||||
// RootKeyable is an interface for all root key implementations that are part of
|
||||
// a session keypair.
|
||||
type RootKeyable interface {
|
||||
Bytes() []byte
|
||||
CreateChain(theirRatchetKey ecc.ECPublicKeyable, ourRatchetKey *ecc.ECKeyPair) (*KeyPair, error)
|
||||
}
|
||||
|
||||
// ChainKeyable is an interface for all chain key implementations that are part of
|
||||
// a session keypair.
|
||||
type ChainKeyable interface {
|
||||
Key() []byte
|
||||
Index() uint32
|
||||
NextKey() *chain.Key
|
||||
MessageKeys() *message.Keys
|
||||
Current() *chain.Key
|
||||
}
|
||||
|
||||
// NewKeyPair returns a new session key pair that holds a root and chain key.
|
||||
func NewKeyPair(rootKey RootKeyable, chainKey ChainKeyable) *KeyPair {
|
||||
keyPair := KeyPair{
|
||||
RootKey: rootKey,
|
||||
ChainKey: chainKey,
|
||||
}
|
||||
|
||||
return &keyPair
|
||||
}
|
||||
|
||||
// KeyPair is a session key pair that holds a single root and chain key pair. These
|
||||
// keys are ratcheted after every message sent and every message round trip.
|
||||
type KeyPair struct {
|
||||
RootKey RootKeyable
|
||||
ChainKey ChainKeyable
|
||||
}
|
Reference in New Issue
Block a user