keychain

package module
v0.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2026 License: MIT Imports: 25 Imported by: 0

README

keychain

keychain is a port and extension of Operator's Keychain library for Swift (specifically, KeychainLinux)

Documentation

Overview

Package keychain provides secure local secret storage with minimal memory exposure.

Design principles:

  • Each secret stored separately (not one big blob)
  • Keys loaded into memory only when needed
  • Age encryption for at-rest storage
  • Symmetric keys derived via ECDH + HKDF
  • Protected memory via memguard for sensitive material

Index

Constants

View Source
const (
	NaClBoxNonceSize = 24
	NaClBoxKeySize   = 32
	NaClBoxOverhead  = box.Overhead // 16 bytes (Poly1305 tag)
)

NaCl box constants

View Source
const (
	P256KeychainTypeByte   = 0x02
	P256KeychainFormatByte = 0x04
	P256KeychainSize       = 66 // type + format + X + Y
)

P-256 Keychain format constants. The Keychain format is a JSON string containing base64-encoded data. For P-256 public keys, the encoded data is 66 bytes:

  • 1 byte: type (0x02 for P-256)
  • 1 byte: format (0x04 for uncompressed)
  • 32 bytes: X coordinate
  • 32 bytes: Y coordinate
View Source
const DefaultIdentityID = "default"

DefaultIdentityID is the ID used for the default/primary identity.

Variables

This section is empty.

Functions

func DecryptWith

func DecryptWith(key *memguard.LockedBuffer, ciphertext, nonce []byte, cs CipherSuite) ([]byte, error)

DecryptWith decrypts data using a provided symmetric key. Not applicable for CipherNaClBox - use NaClBoxDecrypt instead.

func EcdhPublicKeyToKeychain added in v0.0.6

func EcdhPublicKeyToKeychain(pubKey *ecdh.PublicKey) (string, error)

EcdhPublicKeyToKeychain converts a P-256 *ecdh.PublicKey to Keychain format. Output: JSON string containing base64-encoded 66-byte Keychain format

func Ed25519PrivateKeyToX25519 added in v0.0.4

func Ed25519PrivateKeyToX25519(ed25519Seed []byte) ([]byte, error)

Ed25519PrivateKeyToX25519 converts an Ed25519 private key seed to an X25519 private key. The Ed25519 private key seed is the 32-byte value returned by ed25519.PrivateKey.Seed(). This is compatible with libsodium's crypto_sign_ed25519_sk_to_curve25519.

func Ed25519PublicKeyToX25519 added in v0.0.4

func Ed25519PublicKeyToX25519(publicKey ed25519.PublicKey) (*ecdh.PublicKey, error)

Ed25519PublicKeyToX25519 converts an Ed25519 public key to an X25519 public key. This allows using the same key for both signing (Ed25519) and encryption (X25519). Returns the X25519 public key as *ecdh.PublicKey.

func EncryptWith

func EncryptWith(key *memguard.LockedBuffer, plaintext []byte, cs CipherSuite) (ciphertext, nonce []byte, err error)

EncryptWith encrypts data using a provided symmetric key. Not applicable for CipherNaClBox - use NaClBoxEncrypt instead.

func NaClBoxDecrypt added in v0.0.2

func NaClBoxDecrypt(message, peerPublicKey, privateKey []byte) ([]byte, error)

NaClBoxDecrypt decrypts a message using NaCl box (X25519 + XSalsa20-Poly1305). This is compatible with libsodium's crypto_box_open_easy. Expects: nonce (24 bytes) || ciphertext (MAC + encrypted message)

func NaClBoxEncrypt added in v0.0.2

func NaClBoxEncrypt(plaintext, peerPublicKey, privateKey []byte) ([]byte, error)

NaClBoxEncrypt encrypts a message using NaCl box (X25519 + XSalsa20-Poly1305). This is compatible with libsodium's crypto_box_easy. Returns: nonce (24 bytes) || ciphertext (MAC + encrypted message)

func P256KeychainToPublicKey added in v0.0.5

func P256KeychainToPublicKey(keychainFormat string) (*ecdh.PublicKey, error)

P256KeychainToPublicKey converts a Keychain format string to a P-256 public key. Input: JSON string containing base64-encoded 66-byte Keychain format Output: *ecdh.PublicKey for use with P-256 ECDH

func P256PublicKeyToKeychain added in v0.0.5

func P256PublicKeyToKeychain(pubKey []byte) (string, error)

P256PublicKeyToKeychain converts a P-256 public key to Keychain format. This version accepts raw bytes. For *ecdh.PublicKey, use EcdhPublicKeyToKeychain. Input: 65-byte uncompressed X9.62 public key (0x04 || X || Y) Output: JSON string containing base64-encoded 66-byte Keychain format

func VerifySignature added in v0.0.4

func VerifySignature(publicKey ed25519.PublicKey, signature []byte, data []byte) bool

VerifySignature verifies an Ed25519 signature. publicKey should be an Ed25519 public key. signature should be a 64-byte Ed25519 signature. data is the original data that was signed.

Types

type AddressBook

type AddressBook struct {
	// contains filtered or unexported fields
}

AddressBook manages contacts stored individually for minimal exposure.

func NewAddressBook

func NewAddressBook(store *Store) *AddressBook

NewAddressBook creates an address book backed by the secret store.

func (*AddressBook) AddContact

func (ab *AddressBook) AddContact(contact *Contact) error

AddContact stores a new contact with StatusDefault.

func (*AddressBook) AssociateOTPPad

func (ab *AddressBook) AssociateOTPPad(contactID string, otpID SecretID) error

AssociateOTPPad links a one-time pad to a contact (replaces any existing pad).

func (*AddressBook) AssociateP256Key

func (ab *AddressBook) AssociateP256Key(contactID string, keyID SecretID) error

AssociateP256Key links a P-256 public key to a contact.

func (*AddressBook) AssociateX25519Key

func (ab *AddressBook) AssociateX25519Key(contactID string, keyID SecretID) error

AssociateX25519Key links an X25519 public key to a contact.

func (*AddressBook) CanDecryptWith

func (ab *AddressBook) CanDecryptWith(contactID string, keyType KeyExchangeType) (bool, error)

CanDecryptWith returns true if decryption is possible with the specified key type. Requires the contact's public key and status >= StatusInvited.

func (*AddressBook) CanEncryptWith

func (ab *AddressBook) CanEncryptWith(contactID string, keyType KeyExchangeType) (bool, error)

CanEncryptWith returns true if encryption is possible with the specified key type. Requires the contact's public key and status >= StatusRequested.

func (*AddressBook) DecryptFromContact

func (ab *AddressBook) DecryptFromContact(
	myPrivKeyID SecretID,
	contactID string,
	ciphertext, nonce []byte,
	keyType KeyType,
	cs CipherSuite,
) ([]byte, error)

DecryptFromContact derives a shared key with a contact and decrypts data.

func (*AddressBook) DecryptFromContactWithIdentity

func (ab *AddressBook) DecryptFromContactWithIdentity(
	store *Store,
	identityID string,
	contactID string,
	ciphertext, nonce []byte,
	keyType KeyType,
	cs CipherSuite,
) ([]byte, error)

DecryptFromContactWithIdentity decrypts data from a contact using the identity's key.

func (*AddressBook) DeleteContact

func (ab *AddressBook) DeleteContact(id string) error

DeleteContact removes a contact (does not delete associated keys).

func (*AddressBook) DeleteContactWithKeys

func (ab *AddressBook) DeleteContactWithKeys(id string) error

DeleteContactWithKeys removes a contact and all associated keys.

func (*AddressBook) DisassociateOTPPad

func (ab *AddressBook) DisassociateOTPPad(contactID string) error

DisassociateOTPPad removes the OTP pad association from a contact (does not delete the pad).

func (*AddressBook) EncryptForContact

func (ab *AddressBook) EncryptForContact(
	myPrivKeyID SecretID,
	contactID string,
	plaintext []byte,
	keyType KeyType,
	cs CipherSuite,
) (ciphertext, nonce []byte, err error)

EncryptForContact derives a shared key with a contact and encrypts data. keyType specifies which key type to use (KeyTypeP256 or KeyTypeX25519).

func (*AddressBook) EncryptForContactWithIdentity

func (ab *AddressBook) EncryptForContactWithIdentity(
	store *Store,
	identityID string,
	contactID string,
	plaintext []byte,
	keyType KeyType,
	cs CipherSuite,
) (ciphertext, nonce []byte, err error)

EncryptForContactWithIdentity encrypts data for a contact using the identity's key.

func (*AddressBook) GetContact

func (ab *AddressBook) GetContact(id string) (*Contact, error)

GetContact retrieves a contact (without loading any key material).

func (*AddressBook) GetContactPublicKeys

func (ab *AddressBook) GetContactPublicKeys(id string) (*ContactPublicKeys, error)

GetContactPublicKeys loads the actual public key bytes for a contact. For contacts, we store the public key directly as the secret (not a private key).

func (*AddressBook) GetKeyStatus

func (ab *AddressBook) GetKeyStatus(contactID string, keyType KeyExchangeType) (FriendStatus, error)

GetKeyStatus returns the friend status for a specific key type.

func (*AddressBook) IsKeyVerified

func (ab *AddressBook) IsKeyVerified(contactID string, keyType KeyExchangeType) (bool, error)

IsKeyVerified returns true if the specified key type has been verified.

func (*AddressBook) ListContacts

func (ab *AddressBook) ListContacts() ([]*Contact, error)

ListContacts returns all contacts (without loading any key material).

func (*AddressBook) MarkInvited

func (ab *AddressBook) MarkInvited(contactID string, keyType KeyExchangeType) error

MarkInvited transitions a key's status from Default to Invited. Call this after sending your public key/pad to the contact.

func (*AddressBook) MarkRequested

func (ab *AddressBook) MarkRequested(contactID string, keyType KeyExchangeType) error

MarkRequested transitions a key's status from Default to Requested. Call this after receiving the contact's public key/pad.

func (*AddressBook) MarkVerified

func (ab *AddressBook) MarkVerified(contactID string, keyType KeyExchangeType) error

MarkVerified transitions a key's status to Verified. Call this after out-of-band key verification.

func (*AddressBook) NaClBoxDecryptFromContact added in v0.0.2

func (ab *AddressBook) NaClBoxDecryptFromContact(
	myPrivKeyID SecretID,
	contactID string,
	message []byte,
) ([]byte, error)

NaClBoxDecryptFromContact decrypts a message from a contact using NaCl box. This is compatible with Nahoft's encryption format. Expects: nonce (24 bytes) || ciphertext (MAC + encrypted message)

func (*AddressBook) NaClBoxDecryptFromContactWithIdentity added in v0.0.2

func (ab *AddressBook) NaClBoxDecryptFromContactWithIdentity(
	store *Store,
	identityID string,
	contactID string,
	message []byte,
) ([]byte, error)

NaClBoxDecryptFromContactWithIdentity decrypts from a contact using Nahoft-compatible NaCl box. Uses the default identity's X25519 key. Expects: nonce (24 bytes) || ciphertext (MAC + encrypted message)

func (*AddressBook) NaClBoxDecryptWithDefaultIdentity added in v0.0.2

func (ab *AddressBook) NaClBoxDecryptWithDefaultIdentity(
	store *Store,
	contactID string,
	message []byte,
) ([]byte, error)

NaClBoxDecryptWithDefaultIdentity is a convenience function for Nahoft decryption. Decrypts from a contact using the default identity.

func (*AddressBook) NaClBoxEncryptForContact added in v0.0.2

func (ab *AddressBook) NaClBoxEncryptForContact(
	myPrivKeyID SecretID,
	contactID string,
	plaintext []byte,
) ([]byte, error)

NaClBoxEncryptForContact encrypts a message for a contact using NaCl box. This is compatible with Nahoft's encryption format. Returns: nonce (24 bytes) || ciphertext (MAC + encrypted message)

func (*AddressBook) NaClBoxEncryptForContactWithIdentity added in v0.0.2

func (ab *AddressBook) NaClBoxEncryptForContactWithIdentity(
	store *Store,
	identityID string,
	contactID string,
	plaintext []byte,
) ([]byte, error)

NaClBoxEncryptForContactWithIdentity encrypts for a contact using Nahoft-compatible NaCl box. Uses the default identity's X25519 key. Returns: nonce (24 bytes) || ciphertext (MAC + encrypted message)

func (*AddressBook) NaClBoxEncryptWithDefaultIdentity added in v0.0.2

func (ab *AddressBook) NaClBoxEncryptWithDefaultIdentity(
	store *Store,
	contactID string,
	plaintext []byte,
) ([]byte, error)

NaClBoxEncryptWithDefaultIdentity is a convenience function for Nahoft encryption. Encrypts for a contact using the default identity.

func (*AddressBook) SetKeyStatus

func (ab *AddressBook) SetKeyStatus(contactID string, keyType KeyExchangeType, status FriendStatus) error

SetKeyStatus directly sets the friend status for a key type (use with caution).

func (*AddressBook) UpdateContact

func (ab *AddressBook) UpdateContact(contact *Contact) error

UpdateContact updates an existing contact.

type CipherSuite

type CipherSuite string

CipherSuite identifies the symmetric cipher used for encryption.

const (
	CipherAES256GCM        CipherSuite = "aes-256-gcm"
	CipherChaCha20Poly1305 CipherSuite = "chacha20-poly1305"
	// CipherNaClBox uses X25519 + XSalsa20-Poly1305 (libsodium crypto_box compatible)
	CipherNaClBox CipherSuite = "nacl-box"
)

func (CipherSuite) KeyLength

func (cs CipherSuite) KeyLength() int

KeyLength returns the required key length in bytes for the cipher suite.

func (CipherSuite) NonceLength added in v0.0.2

func (cs CipherSuite) NonceLength() int

NonceLength returns the nonce length in bytes for the cipher suite.

type Contact

type Contact struct {
	ID        string `json:"id"`
	Name      string `json:"name"`
	Notes     string `json:"notes,omitempty"`
	CreatedAt int64  `json:"created_at"`
	UpdatedAt int64  `json:"updated_at"`

	// P-256 key reference and exchange status
	P256KeyID  SecretID     `json:"p256_key_id,omitempty"`
	P256Status FriendStatus `json:"p256_status"`

	// X25519 key reference and exchange status
	X25519KeyID  SecretID     `json:"x25519_key_id,omitempty"`
	X25519Status FriendStatus `json:"x25519_status"`

	// OTP pad reference and exchange status (at most one pad per contact)
	OTPPadID  SecretID     `json:"otp_pad_id,omitempty"`
	OTPStatus FriendStatus `json:"otp_status"`
}

Contact represents an entry in the address book. Keys are stored separately in the keychain; contacts only hold references. Each key type has its own exchange status since key exchange is per-key-type.

type ContactPublicKeys

type ContactPublicKeys struct {
	P256PublicKey   []byte
	X25519PublicKey []byte
}

ContactPublicKeys holds the actual public key bytes for a contact. This is returned only when explicitly requested.

type FriendStatus

type FriendStatus int

FriendStatus tracks the key exchange state with a contact.

const (
	// StatusDefault - Contact added, no key exchange yet
	StatusDefault FriendStatus = iota
	// StatusInvited - User sent their public key to this contact
	StatusInvited
	// StatusRequested - Contact sent their public key to user
	StatusRequested
	// StatusApproved - Bidirectional key exchange complete, unverified
	StatusApproved
	// StatusVerified - Keys verified out-of-band (e.g., in person)
	StatusVerified
)

func (FriendStatus) String

func (s FriendStatus) String() string

String returns a human-readable status name.

type Identity

type Identity struct {
	ID           string   `json:"id"`
	Name         string   `json:"name"`
	CreatedAt    int64    `json:"created_at"`
	UpdatedAt    int64    `json:"updated_at"`
	P256KeyID    SecretID `json:"p256_key_id,omitempty"`
	X25519KeyID  SecretID `json:"x25519_key_id,omitempty"`
	Ed25519KeyID SecretID `json:"ed25519_key_id,omitempty"` // Ed25519 signing key
}

Identity represents the local user's identity with their private keys.

type IdentityPublicKeys

type IdentityPublicKeys struct {
	P256PublicKey    []byte
	X25519PublicKey  []byte
	Ed25519PublicKey []byte
}

IdentityPublicKeys holds the public keys for an identity.

func (*IdentityPublicKeys) Ed25519PublicKeyTyped added in v0.0.6

func (k *IdentityPublicKeys) Ed25519PublicKeyTyped() (ed25519.PublicKey, error)

Ed25519PublicKeyTyped returns the Ed25519 public key as ed25519.PublicKey.

func (*IdentityPublicKeys) P256EcdhPublicKey added in v0.0.6

func (k *IdentityPublicKeys) P256EcdhPublicKey() (*ecdh.PublicKey, error)

P256EcdhPublicKey returns the P-256 public key as *ecdh.PublicKey.

func (*IdentityPublicKeys) X25519EcdhPublicKey added in v0.0.6

func (k *IdentityPublicKeys) X25519EcdhPublicKey() (*ecdh.PublicKey, error)

X25519EcdhPublicKey returns the X25519 public key as *ecdh.PublicKey.

type KeyExchangeType

type KeyExchangeType int

KeyExchangeType specifies which key type a status operation applies to.

const (
	KeyExchangeP256 KeyExchangeType = iota
	KeyExchangeX25519
	KeyExchangeOTP
)

type KeyType

type KeyType string

KeyType identifies the type of key stored.

const (
	KeyTypeP256          KeyType = "p256"
	KeyTypeX25519        KeyType = "x25519"
	KeyTypeP256Public    KeyType = "p256-public"
	KeyTypeX25519Public  KeyType = "x25519-public"
	KeyTypeAES256        KeyType = "aes256"
	KeyTypeChaCha20      KeyType = "chacha20"
	KeyTypeContact       KeyType = "contact"
	KeyTypeEd25519       KeyType = "ed25519"        // Ed25519 signing key (private)
	KeyTypeEd25519Public KeyType = "ed25519-public" // Ed25519 public key (for contacts)
)
const KeyTypeIdentity KeyType = "identity"

KeyTypeIdentity is the key type for identity metadata.

const KeyTypeOTP KeyType = "otp"

KeyTypeOTP is the key type for one-time pad secrets.

const KeyTypeOTPMeta KeyType = "otp-meta"

KeyTypeOTPMeta is the key type for one-time pad metadata.

type OTPPad

type OTPPad struct {
	ID        SecretID `json:"id"`
	Label     string   `json:"label,omitempty"`
	Length    int      `json:"length"` // Total length of the pad in bytes
	Offset    int      `json:"offset"` // Current offset - bytes before this are consumed
	CreatedAt int64    `json:"created_at"`
}

OTPPad represents a one-time pad for XOR-based encryption. The pad is consumed sequentially and bytes are never reused.

type OTPResult

type OTPResult struct {
	Data        []byte // The XOR'd output
	BytesUsed   int    // Number of pad bytes consumed
	BytesLeft   int    // Remaining bytes in the pad
	StartOffset int    // Offset where this operation started
}

OTPResult contains the result of an OTP encryption/decryption operation.

type SecretID

type SecretID string

SecretID uniquely identifies a secret in the store.

type SecretMetadata

type SecretMetadata struct {
	ID        SecretID `json:"id"`
	KeyType   KeyType  `json:"key_type"`
	Label     string   `json:"label,omitempty"`
	CreatedAt int64    `json:"created_at"`
	PublicKey []byte   `json:"public_key,omitempty"`
}

SecretMetadata is stored inside the encrypted envelope.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store manages secrets on disk using age encryption.

func OpenStore

func OpenStore(path string, password []byte) (*Store, error)

OpenStore opens or creates a secret store at the given path. The password is used with age's scrypt-based encryption.

func (*Store) AddEd25519KeyToIdentity added in v0.0.4

func (s *Store) AddEd25519KeyToIdentity(id string) (ed25519.PublicKey, error)

AddEd25519KeyToIdentity generates and adds an Ed25519 key to an existing identity.

func (*Store) AddP256KeyToIdentity

func (s *Store) AddP256KeyToIdentity(id string) (*ecdh.PublicKey, error)

AddP256KeyToIdentity generates and adds a P-256 key to an existing identity.

func (*Store) AddX25519KeyToIdentity

func (s *Store) AddX25519KeyToIdentity(id string) (*ecdh.PublicKey, error)

AddX25519KeyToIdentity generates and adds an X25519 key to an existing identity.

func (*Store) Close

func (s *Store) Close()

Close securely destroys the password from memory.

func (*Store) CreateDefaultIdentity

func (s *Store) CreateDefaultIdentity(name string) (*Identity, error)

CreateDefaultIdentity creates the default identity with all key types.

func (*Store) CreateFullIdentity added in v0.0.4

func (s *Store) CreateFullIdentity(name string) (*Identity, error)

CreateFullIdentity creates an identity with all key types (P-256, X25519, Ed25519).

func (*Store) CreateIdentity

func (s *Store) CreateIdentity(id string, name string, generateP256, generateX25519, generateEd25519 bool) (*Identity, error)

CreateIdentity creates a new identity with the specified key types. If generateP256 is true, a P-256 keypair is generated. If generateX25519 is true, an X25519 keypair is generated. If generateEd25519 is true, an Ed25519 keypair is generated.

func (*Store) CreateNahoftIdentity added in v0.0.2

func (s *Store) CreateNahoftIdentity(name string) (*Identity, error)

CreateNahoftIdentity creates an identity with only X25519 key (Nahoft-compatible).

func (*Store) CreateSigningIdentity added in v0.0.4

func (s *Store) CreateSigningIdentity(id string, name string) (*Identity, error)

CreateSigningIdentity creates an identity with Ed25519 key for signing.

func (*Store) DecryptWithDerivedKey

func (s *Store) DecryptWithDerivedKey(
	privateKeyID SecretID,
	peerPublicKey []byte,
	info []byte,
	ciphertext, nonce []byte,
	cs CipherSuite,
) ([]byte, error)

DecryptWithDerivedKey derives a shared key via ECDH and decrypts data. This is a convenience function that combines DeriveSharedKey and DecryptWith. Not applicable for CipherNaClBox - use NaClBoxDecryptWithStore instead.

func (*Store) DefaultIdentityExists

func (s *Store) DefaultIdentityExists() bool

DefaultIdentityExists checks if the default identity exists.

func (*Store) DeleteIdentity

func (s *Store) DeleteIdentity(id string) error

DeleteIdentity removes an identity and its associated keys.

func (*Store) DeleteOTPPad

func (s *Store) DeleteOTPPad(id SecretID) error

DeleteOTPPad removes an OTP pad and its metadata.

func (*Store) DeleteSecret

func (s *Store) DeleteSecret(id SecretID) error

DeleteSecret securely removes a secret.

func (*Store) DeriveSharedKey

func (s *Store) DeriveSharedKey(
	privateKeyID SecretID,
	peerPublicKey []byte,
	info []byte,
	keyLen int,
) (*memguard.LockedBuffer, error)

DeriveSharedKey performs ECDH with a peer's public key and derives a symmetric key using HKDF. The private key is loaded only for this operation.

func (*Store) DeriveSharedKeyP256 added in v0.0.6

func (s *Store) DeriveSharedKeyP256(
	privateKeyID SecretID,
	peerPublicKey *ecdh.PublicKey,
	info []byte,
	keyLen int,
) (*memguard.LockedBuffer, error)

DeriveSharedKeyP256 performs ECDH with a peer's P-256 public key. This is a convenience wrapper that extracts bytes from *ecdh.PublicKey.

func (*Store) DeriveSharedKeyX25519 added in v0.0.6

func (s *Store) DeriveSharedKeyX25519(
	privateKeyID SecretID,
	peerPublicKey *ecdh.PublicKey,
	info []byte,
	keyLen int,
) (*memguard.LockedBuffer, error)

DeriveSharedKeyX25519 performs ECDH with a peer's X25519 public key. This is a convenience wrapper that extracts bytes from *ecdh.PublicKey.

func (*Store) Ed25519PublicToX25519 added in v0.0.4

func (s *Store) Ed25519PublicToX25519(id SecretID) (*ecdh.PublicKey, error)

Ed25519PublicToX25519 converts a stored Ed25519 public key to an X25519 public key. Returns the X25519 public key as *ecdh.PublicKey.

func (*Store) Ed25519ToX25519 added in v0.0.4

func (s *Store) Ed25519ToX25519(id SecretID) ([]byte, error)

Ed25519ToX25519 converts a stored Ed25519 private key to an X25519 private key. The returned key is suitable for X25519 key exchange and NaCl box encryption.

func (*Store) EncryptWithDerivedKey

func (s *Store) EncryptWithDerivedKey(
	privateKeyID SecretID,
	peerPublicKey []byte,
	info []byte,
	plaintext []byte,
	cs CipherSuite,
) (ciphertext, nonce []byte, err error)

EncryptWithDerivedKey derives a shared key via ECDH and encrypts data. This is a convenience function that combines DeriveSharedKey and EncryptWith. Not applicable for CipherNaClBox - use NaClBoxEncryptWithStore instead.

func (*Store) ExportP256PublicKey added in v0.0.5

func (s *Store) ExportP256PublicKey(keyID SecretID) (string, error)

ExportP256PublicKey exports a P-256 public key in Keychain format. The keychain format is a JSON string containing base64-encoded data:

"AgRLwusU2xH3whuHbLUPAKw/tgnqZkuu28c5hWQaD/VPgCJmn0C4g+7UUMNSqFHBw3ItFLj0dMdVYuA64kBCFtbE"

The encoded data is 66 bytes:

  • 1 byte: type (0x02 for P-256)
  • 1 byte: format (0x00)
  • 32 bytes: X coordinate
  • 32 bytes: Y coordinate

This format is compatible with DarkStar's NewDarkStarClient function.

keyID can be either a P-256 private key (KeyTypeP256) or a P-256 public key (KeyTypeP256Public). For private keys, the public key is extracted from metadata.

func (*Store) GenerateEd25519 added in v0.0.4

func (s *Store) GenerateEd25519(id SecretID, label string) (ed25519.PublicKey, error)

GenerateEd25519 creates a new Ed25519 keypair and stores the private key seed. Returns the public key as ed25519.PublicKey for use with signature verification.

func (*Store) GenerateP256

func (s *Store) GenerateP256(id SecretID, label string) (*ecdh.PublicKey, error)

GenerateP256 creates a new P-256 keypair and stores the private key. Returns the public key as *ecdh.PublicKey for use with ECDH key agreement.

func (*Store) GenerateSymmetricKey

func (s *Store) GenerateSymmetricKey(id SecretID, label string, keyLen int) error

GenerateSymmetricKey creates a random symmetric key of the specified length.

func (*Store) GenerateX25519

func (s *Store) GenerateX25519(id SecretID, label string) (*ecdh.PublicKey, error)

GenerateX25519 creates a new X25519 keypair and stores the private key. Returns the public key as *ecdh.PublicKey for use with ECDH key agreement.

func (*Store) GetDefaultIdentity

func (s *Store) GetDefaultIdentity() (*Identity, error)

GetDefaultIdentity retrieves the default identity.

func (*Store) GetDefaultIdentityPublicKeys

func (s *Store) GetDefaultIdentityPublicKeys() (*IdentityPublicKeys, error)

GetDefaultIdentityPublicKeys retrieves the public keys for the default identity.

func (*Store) GetIdentity

func (s *Store) GetIdentity(id string) (*Identity, error)

GetIdentity retrieves an identity by ID.

func (*Store) GetIdentityPublicKeys

func (s *Store) GetIdentityPublicKeys(id string) (*IdentityPublicKeys, error)

GetIdentityPublicKeys retrieves the public keys for an identity.

func (*Store) GetMetadata

func (s *Store) GetMetadata(id SecretID) (*SecretMetadata, error)

GetMetadata returns metadata for a secret without decrypting the secret itself. Note: This still requires decryption since metadata is inside the age envelope.

func (*Store) GetOTPPadInfo

func (s *Store) GetOTPPadInfo(id SecretID) (*OTPPad, error)

GetOTPPadInfo retrieves metadata about an OTP pad without loading the pad itself.

func (*Store) IdentityExists

func (s *Store) IdentityExists(id string) bool

IdentityExists checks if an identity exists.

func (*Store) ImportEd25519KeyToIdentity added in v0.0.4

func (s *Store) ImportEd25519KeyToIdentity(id string, privateKey []byte) error

ImportEd25519KeyToIdentity imports an existing Ed25519 private key seed to an identity. The privateKey should be a 32-byte Ed25519 seed.

func (*Store) ImportP256KeyToIdentity

func (s *Store) ImportP256KeyToIdentity(id string, privateKey []byte) error

ImportP256KeyToIdentity imports an existing P-256 private key to an identity.

func (*Store) ImportP256PublicKey added in v0.0.5

func (s *Store) ImportP256PublicKey(keyID SecretID, keychainFormat string, label string) error

ImportP256PublicKey imports a P-256 public key from Keychain format. The keychainFormat should be a JSON string like: "AgRLwusU2xH3whuHbLUPAKw/tgn..." (including the quotes). The imported key can be used for ECDH key derivation with a P-256 private key.

func (*Store) ImportX25519KeyToIdentity

func (s *Store) ImportX25519KeyToIdentity(id string, privateKey []byte) error

ImportX25519KeyToIdentity imports an existing X25519 private key to an identity.

func (*Store) ListIdentities

func (s *Store) ListIdentities() ([]*Identity, error)

ListIdentities returns all stored identities.

func (*Store) ListOTPPads

func (s *Store) ListOTPPads() ([]OTPPad, error)

ListOTPPads returns metadata for all stored OTP pads.

func (*Store) ListSecrets

func (s *Store) ListSecrets() ([]SecretMetadata, error)

ListSecrets returns metadata for all stored secrets.

func (*Store) LoadEd25519PublicKey added in v0.0.6

func (s *Store) LoadEd25519PublicKey(id SecretID) (ed25519.PublicKey, error)

LoadEd25519PublicKey loads an Ed25519 public key from the store.

func (*Store) LoadP256PublicKey added in v0.0.6

func (s *Store) LoadP256PublicKey(id SecretID) (*ecdh.PublicKey, error)

LoadP256PublicKey loads a P-256 public key from the store.

func (*Store) LoadPublicKey

func (s *Store) LoadPublicKey(id SecretID) ([]byte, KeyType, error)

LoadPublicKey loads a public key from the store. Returns the raw bytes and key type. For typed methods, use LoadEd25519PublicKey, LoadX25519PublicKey, or LoadP256PublicKey.

func (*Store) LoadSecret

func (s *Store) LoadSecret(id SecretID) (*memguard.LockedBuffer, *SecretMetadata, error)

LoadSecret decrypts and returns a secret in protected memory. The caller MUST call Destroy() on the returned LockedBuffer when done.

func (*Store) LoadSymmetricKey

func (s *Store) LoadSymmetricKey(id SecretID) (*memguard.LockedBuffer, error)

LoadSymmetricKey loads a symmetric key into protected memory. The caller MUST call Destroy() on the returned LockedBuffer when done.

func (*Store) LoadX25519PublicKey added in v0.0.6

func (s *Store) LoadX25519PublicKey(id SecretID) (*ecdh.PublicKey, error)

LoadX25519PublicKey loads an X25519 public key from the store.

func (*Store) NaClBoxDecryptWithStore added in v0.0.2

func (s *Store) NaClBoxDecryptWithStore(
	privateKeyID SecretID,
	peerPublicKey []byte,
	message []byte,
) ([]byte, error)

NaClBoxDecryptWithStore decrypts using a private key from the store. The private key is loaded only for this operation.

func (*Store) NaClBoxEncryptWithStore added in v0.0.2

func (s *Store) NaClBoxEncryptWithStore(
	privateKeyID SecretID,
	peerPublicKey []byte,
	plaintext []byte,
) ([]byte, error)

NaClBoxEncryptWithStore encrypts using a private key from the store. The private key is loaded only for this operation.

func (*Store) OTPBytesRemaining

func (s *Store) OTPBytesRemaining(id SecretID) (int, error)

OTPBytesRemaining returns how many unused bytes remain in the pad.

func (*Store) OTPDecrypt

func (s *Store) OTPDecrypt(id SecretID, ciphertext []byte) (*OTPResult, error)

OTPDecrypt XORs data with the next unused bytes from the pad. This is identical to OTPEncrypt (XOR is symmetric) but provided for clarity.

func (*Store) OTPDecryptBits

func (s *Store) OTPDecryptBits(id SecretID, data []byte, numBits int) (*OTPResult, error)

OTPDecryptBits XORs a specific number of bits with the pad.

func (*Store) OTPDecryptWSPR

func (s *Store) OTPDecryptWSPR(id SecretID, data [11]byte) (*OTPResult, [11]byte, error)

OTPDecryptWSPR decrypts a PackedWSPRMessage-format 11-byte array.

func (*Store) OTPEncrypt

func (s *Store) OTPEncrypt(id SecretID, plaintext []byte) (*OTPResult, error)

OTPEncrypt XORs data with the next unused bytes from the pad. The pad offset is advanced to prevent reuse.

func (*Store) OTPEncryptBits

func (s *Store) OTPEncryptBits(id SecretID, data []byte, numBits int) (*OTPResult, error)

OTPEncryptBits XORs a specific number of bits with the pad. This is useful for the 50-bit packed format you mentioned. The bits are taken from the least significant bits of the input bytes.

func (*Store) OTPEncryptWSPR

func (s *Store) OTPEncryptWSPR(id SecretID, data [11]byte) (*OTPResult, [11]byte, error)

OTPEncryptWSPR encrypts a PackedWSPRMessage-format 11-byte array. This XORs the 50 data bits (B0-B5 full bytes + B6 low 2 bits) while preserving B6 high bits and B7-B10 as zero.

Format from codex.go:

  • B0-B5: Full octets (8 bits each = 48 bits)
  • B6: Quartet (2 bits, values 0-3)
  • B7-B10: Always zero

func (*Store) OTPPeek

func (s *Store) OTPPeek(id SecretID, length int) ([]byte, error)

OTPPeek reads pad bytes without consuming them. Use for verification only.

func (*Store) OTPSetOffset

func (s *Store) OTPSetOffset(id SecretID, offset int) error

OTPSetOffset manually sets the pad offset. Use with caution.

func (*Store) OTPSkip

func (s *Store) OTPSkip(id SecretID, numBytes int) error

OTPSkip advances the pad offset without using the bytes for encryption. Use when synchronizing with a remote party that has already consumed bytes.

func (*Store) SecretExists

func (s *Store) SecretExists(id SecretID) bool

SecretExists checks if a secret exists without decrypting it.

func (*Store) Sign added in v0.0.4

func (s *Store) Sign(id SecretID, data []byte) ([]byte, error)

Sign signs data with the Ed25519 private key identified by id. Returns a 64-byte signature.

func (*Store) StoreEd25519PublicKey added in v0.0.4

func (s *Store) StoreEd25519PublicKey(id SecretID, publicKey ed25519.PublicKey, label string) error

StoreEd25519PublicKey stores an Ed25519 public key (for a contact).

func (*Store) StoreOTPPad

func (s *Store) StoreOTPPad(id SecretID, pad []byte, label string) error

StoreOTPPad stores a new one-time pad.

func (*Store) StoreP256PublicKey

func (s *Store) StoreP256PublicKey(id SecretID, publicKey *ecdh.PublicKey, label string) error

StoreP256PublicKey stores a P-256 public key (for a contact). Accepts *ecdh.PublicKey from ecdh.P256().

func (*Store) StoreSecret

func (s *Store) StoreSecret(id SecretID, keyType KeyType, secret []byte, label string) error

StoreSecret encrypts and persists a secret using age.

func (*Store) StoreX25519PublicKey

func (s *Store) StoreX25519PublicKey(id SecretID, publicKey *ecdh.PublicKey, label string) error

StoreX25519PublicKey stores an X25519 public key (for a contact). Accepts *ecdh.PublicKey from ecdh.X25519().

func (*Store) UpdateIdentity

func (s *Store) UpdateIdentity(identity *Identity) error

UpdateIdentity updates an identity's metadata (name, etc.).

func (*Store) Verify added in v0.0.4

func (s *Store) Verify(publicKeyID SecretID, signature []byte, data []byte) (bool, error)

Verify verifies a signature using a stored Ed25519 public key.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL