Documentation
¶
Index ¶
- func GenerateKey() ([]byte, error)
- func SerializeRatchetMessage(msg *RatchetMessage) []byte
- func VerifySignature(publicKey, signature, publicKeyToVerify []byte) bool
- func X3DHInitiator(myIdentityPriv, theirBundle *PreKeyBundle) (sharedSecret []byte, ephemeralPub []byte, err error)
- func X3DHResponderKeys(mySignedPreKeyPriv []byte, myOneTimePreKeyPriv []byte, ...) ([]byte, error)
- type ClientEncryptor
- type Encryptor
- type HandshakeManager
- type IdentityKey
- type KeyPair
- type OneTimePreKey
- type PreKeyBundle
- type RatchetMessage
- type RatchetState
- type SignedPreKey
- type SimpleKeyExchange
- type X3DHIdentity
- type X25519KeyExchange
- func (kx *X25519KeyExchange) DeriveSharedSecret(peerID string, remotePublicKey []byte) ([]byte, error)
- func (kx *X25519KeyExchange) GenerateKeyPair(peerID string) (*KeyPair, error)
- func (kx *X25519KeyExchange) GetPublicKey(peerID string) ([]byte, error)
- func (kx *X25519KeyExchange) RemovePeer(peerID string)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GenerateKey ¶
GenerateKey generates a random 32-byte key suitable for XChaCha20-Poly1305.
func SerializeRatchetMessage ¶
func SerializeRatchetMessage(msg *RatchetMessage) []byte
SerializeRatchetMessage encodes a RatchetMessage to bytes. Format: [DH_len:2][DH][N:4][PN:4][CT_len:4][CT]
func VerifySignature ¶
VerifySignature verifies an HMAC-SHA256 signature of a public key.
func X3DHInitiator ¶
func X3DHInitiator(myIdentityPriv, theirBundle *PreKeyBundle) (sharedSecret []byte, ephemeralPub []byte, err error)
X3DH performs the initiator side of the X3DH key agreement. Returns the shared secret and the ephemeral key pair (for inclusion in the X3DH message).
The shared secret is computed as:
DH1 = DH(IKa, SPKb) DH2 = DH(EKa, IKb) DH3 = DH(EKa, SPKb) DH4 = DH(EKa, OPKb)
SK = KDF(DH1 || DH2 || DH3 || DH4)
func X3DHResponderKeys ¶
func X3DHResponderKeys( mySignedPreKeyPriv []byte, myOneTimePreKeyPriv []byte, senderIdentityPub []byte, senderEphemeralPub []byte, myIdentityPriv []byte, ) ([]byte, error)
X3DHResponderKeys performs the responder-side X3DH. The responder uses their private keys to compute the same shared secret.
Types ¶
type ClientEncryptor ¶
type ClientEncryptor struct {
// contains filtered or unexported fields
}
ClientEncryptor is a utility for client-side encryption/decryption using XChaCha20-Poly1305.
func NewEncryptor ¶
func NewEncryptor(sharedSecret []byte) (*ClientEncryptor, error)
NewEncryptor creates a new encryptor using a 32-byte shared secret.
func (*ClientEncryptor) Decrypt ¶
func (e *ClientEncryptor) Decrypt(ciphertext []byte) ([]byte, error)
Decrypt decrypts ciphertext with leading nonce.
func (*ClientEncryptor) Encrypt ¶
func (e *ClientEncryptor) Encrypt(plaintext []byte) ([]byte, error)
Encrypt encrypts plaintext and prepends a random 24-byte nonce.
func (*ClientEncryptor) RotateKey ¶
func (e *ClientEncryptor) RotateKey(newKey []byte) error
RotateKey rotates the encryption key. Old ciphertexts cannot be decrypted with the new key.
type Encryptor ¶
type Encryptor = ClientEncryptor
Encryptor is a utility for encryption/decryption using XChaCha20-Poly1305.
type HandshakeManager ¶
type HandshakeManager struct {
// contains filtered or unexported fields
}
HandshakeManager facilitates public key exchange between peers. It stores ONLY public keys temporarily during the handshake process.
func NewHandshakeManager ¶
func NewHandshakeManager() *HandshakeManager
NewHandshakeManager creates a new server-side handshake facilitator.
func (*HandshakeManager) GetPublicKey ¶
func (hm *HandshakeManager) GetPublicKey(peerID string) ([]byte, bool)
GetPublicKey retrieves a peer's public key.
func (*HandshakeManager) RemovePeer ¶
func (hm *HandshakeManager) RemovePeer(peerID string)
RemovePeer cleans up public key material for a peer.
func (*HandshakeManager) StorePublicKey ¶
func (hm *HandshakeManager) StorePublicKey(peerID string, pubKey []byte)
StorePublicKey stores a peer's public key (received from the client).
type IdentityKey ¶
type IdentityKey = KeyPair
IdentityKey is a long-lived key pair identifying a user.
type KeyPair ¶
KeyPair holds an X25519 public/private key pair.
func X3DHInitiatorKeys ¶
func X3DHInitiatorKeys( identityPriv []byte, identityPub []byte, recipientIdentityPub []byte, recipientSignedPreKeyPub []byte, recipientOneTimePreKeyPub []byte, ) (sharedSecret []byte, ephemeral *KeyPair, err error)
X3DHInitiatorKeys performs the initiator-side X3DH with raw key material. Returns the shared secret and the ephemeral key pair (for reuse as the ratchet DH key).
type OneTimePreKey ¶
OneTimePreKey is a single-use key pair used in X3DH for forward secrecy.
type PreKeyBundle ¶
type PreKeyBundle struct {
IdentityKey []byte // public key
SignedPreKey []byte // public key
SignedPreKeyID uint32
Signature []byte // signature of SignedPreKey by IdentityKey
OneTimePreKey []byte // public key (optional, nil if consumed)
OneTimePreKeyID uint32 // 0 if no one-time pre-key
}
PreKeyBundle contains the public keys a user publishes to the server for asynchronous X3DH key agreement.
type RatchetMessage ¶
type RatchetMessage struct {
DH []byte `json:"dh"` // sender's current DH public key
N uint32 `json:"n"` // message number in the sending chain
PN uint32 `json:"pn"` // previous chain length
Ciphertext []byte `json:"ct"` // encrypted message (with AEAD nonce prepended)
}
RatchetMessage is the wire format for a Double Ratchet encrypted message.
func DeserializeRatchetMessage ¶
func DeserializeRatchetMessage(data []byte) (*RatchetMessage, error)
DeserializeRatchetMessage decodes bytes to a RatchetMessage.
type RatchetState ¶
type RatchetState struct {
// DH keys
DHs *KeyPair // sending ratchet key pair
// Remote peer's current DH public key
DHr []byte
// Root key (32 bytes) — updated on every DH ratchet step
RootKey []byte
// Sending chain key — KDF'd on each message sent
CKs []byte
// Receiving chain key — KDF'd on each message received
CKr []byte
// Message counters
Ns uint32 // sending
Nr uint32 // receiving
PN uint32 // number of messages in previous sending chain
// Skipped message keys: map of (DH public key, counter) -> message key
// For handling out-of-order messages
SkippedKeys map[string]map[uint32][]byte
// Max skipped keys to prevent DoS
MaxSkipped uint32
// contains filtered or unexported fields
}
RatchetState holds the complete state of a Double Ratchet session. This implements the Signal Double Ratchet Algorithm.
func NewRatchetSession ¶
func NewRatchetSession(sharedSecret, identityPriv, remoteSignedPreKeyPub []byte, dhKeyPair *KeyPair) *RatchetState
NewRatchetSession creates a new Double Ratchet session for the INITIATOR (Alice).
After X3DH, Alice has the shared secret (SK). She uses her X3DH ephemeral key pair as her initial ratchet DH key pair (DHs).
Chain key derivation follows Signal spec:
CKs = KDF(SK, DH(Alice.IK_priv, Bob.SPK_pub)) — matches Bob's CKr CKr = nil (will be set on first DH ratchet step when receiving a reply)
func NewRatchetSessionFromReceived ¶
func NewRatchetSessionFromReceived(sharedSecret, signedPreKeyPriv, remoteIdentityPub, senderEphemeralPub []byte, myDHKeyPair *KeyPair) *RatchetState
NewRatchetSessionFromReceived creates the RESPONDER's (Bob's) session.
Bob receives Alice's initial message containing Alice's ephemeral DH public key. Bob generates his own ratchet DH key pair but does NOT send yet.
Chain key derivation:
CKr = KDF(SK, DH(SPK_b_priv, IK_a_pub)) — matches Alice's CKs CKs = nil (will be set on first DH ratchet step when Bob first sends)
func (*RatchetState) Decrypt ¶
func (rs *RatchetState) Decrypt(msg *RatchetMessage) ([]byte, error)
Decrypt decrypts an incoming RatchetMessage.
func (*RatchetState) Encrypt ¶
func (rs *RatchetState) Encrypt(plaintext []byte) (*RatchetMessage, error)
Encrypt encrypts a plaintext message using the Double Ratchet.
type SignedPreKey ¶
type SignedPreKey struct {
KeyPair
KeyID uint32
Signature []byte // Ed25519 signature of PublicKey by IdentityKey
}
SignedPreKey is a medium-lived key pair signed by the identity key.
type SimpleKeyExchange ¶
type SimpleKeyExchange struct {
// contains filtered or unexported fields
}
SimpleKeyExchange is a legacy key exchange that just returns the remote key directly. Kept for backwards compatibility with tests.
func NewSimpleKeyExchange ¶
func NewSimpleKeyExchange() *SimpleKeyExchange
NewSimpleKeyExchange creates a new simple key exchange manager.
func (*SimpleKeyExchange) ExchangeKey ¶
func (kx *SimpleKeyExchange) ExchangeKey(peerID string, remoteKey []byte) ([]byte, error)
ExchangeKey performs a simple key exchange by returning the remote key.
func (*SimpleKeyExchange) GenerateKeyPair ¶
func (kx *SimpleKeyExchange) GenerateKeyPair(peerID string) (*KeyPair, error)
GenerateKeyPair generates a random key pair for a peer.
type X3DHIdentity ¶
type X3DHIdentity struct {
IdentityKey *IdentityKey
SignedPreKey *SignedPreKey
OneTimePreKeys map[uint32]*OneTimePreKey // keyID -> key
// contains filtered or unexported fields
}
X3DHIdentity holds a user's X3DH key material.
func NewX3DHIdentity ¶
func NewX3DHIdentity() (*X3DHIdentity, error)
NewX3DHIdentity generates a complete X3DH identity set.
func (*X3DHIdentity) ConsumeOneTimePreKey ¶
func (id *X3DHIdentity) ConsumeOneTimePreKey(keyID uint32)
ConsumeOneTimePreKey removes a one-time pre-key after use.
func (*X3DHIdentity) GenerateOneTimePreKeys ¶
func (id *X3DHIdentity) GenerateOneTimePreKeys(n int) error
GenerateOneTimePreKeys generates N one-time pre-keys.
func (*X3DHIdentity) GetBundle ¶
func (id *X3DHIdentity) GetBundle() *PreKeyBundle
GetBundle returns the public PreKeyBundle for publishing to the server.
type X25519KeyExchange ¶
type X25519KeyExchange struct {
// contains filtered or unexported fields
}
X25519KeyExchange implements Diffie-Hellman key exchange using Curve25519.
func NewX25519KeyExchange ¶
func NewX25519KeyExchange() *X25519KeyExchange
NewX25519KeyExchange creates a new X25519 key exchange manager.
func (*X25519KeyExchange) DeriveSharedSecret ¶
func (kx *X25519KeyExchange) DeriveSharedSecret(peerID string, remotePublicKey []byte) ([]byte, error)
DeriveSharedSecret computes the shared secret using ECDH (Curve25519). The caller must supply the remote peer's public key.
func (*X25519KeyExchange) GenerateKeyPair ¶
func (kx *X25519KeyExchange) GenerateKeyPair(peerID string) (*KeyPair, error)
GenerateKeyPair generates a new X25519 key pair for a peer.
func (*X25519KeyExchange) GetPublicKey ¶
func (kx *X25519KeyExchange) GetPublicKey(peerID string) ([]byte, error)
GetPublicKey returns the public key for a peer.
func (*X25519KeyExchange) RemovePeer ¶
func (kx *X25519KeyExchange) RemovePeer(peerID string)
RemovePeer zeroes out the private key and removes the key pair.