Documentation
¶
Overview ¶
Package crypto — the AEAD port implemented by each concrete algorithm.
Package crypto — the Agreement port: DH-style key agreement.
Package crypto — the process-wide Agreement registry + GenerateAgreementKey / AgreementShared dispatch.
Package crypto declares the authenticated-encryption port: the AEAD contract, the redacting Key value type, and the process-wide registry that maps an Algorithm (and its 1-byte wire id) to a registered AEAD. It is the peer of internal/core/data/codec — the registry resolves an Algorithm to an AEAD exactly as codec resolves a Format to a Codec.
No algorithm bodies and no vendor types live here; concrete AEADs live under internal/service/crypto/<algo>/ (stdlib AES-GCM today) and third-party/ x-crypto/* (XChaCha20-Poly1305 tomorrow) and self-register via a package-level var initialiser when imported — no init().
Package crypto — range 0.2.4.* (ADR 0013 core/crypto block).
Package crypto — the key-derivation port implemented by each KDF scheme.
Package crypto — the process-wide Deriver registry + Subkey dispatch.
Package crypto — declares the sentinels returned by the AEAD facade. Each var's name equals its errs.Define Reason in SCREAMING_SNAKE form. DuplicateRegistration is never returned: every registrar panics at boot with conflictText of it (see registry_generic.go and registry.go).
Package crypto — the process-wide Hasher registry + Sum / SumHex dispatch.
Package crypto — the Hasher port: fingerprint / content-addressing hashing.
Package crypto — the opaque, redacting symmetric Key value type.
Package crypto — the MAC port: keyed, detached message authentication.
Package crypto — the process-wide MAC registry + MACTag / MACVerify dispatch.
Package crypto — the password-hashing port implemented by each scheme.
Package crypto — the process-wide PasswordHasher registry + HashPassword / VerifyPassword / NeedsRehash dispatch.
Package crypto — holds the process-wide AEAD registry. Service- and third-party-level scheme packages register themselves via package-level var initialisers when imported (no init()), mirroring core/data/codec.
Package crypto — the registrar every scheme registry shares (AEAD, Hasher, Signer, MAC, Deriver, Agreement, PasswordHasher, StreamSealer). The table under each one is the kernel's (kernel/plugin.Registry, ADR 0159); what this file adds is the crypto domain's refusal — the code, the reason and the fields a conflict panics with — written once instead of once per capability.
Package crypto — the Seal / Open dispatch over the AEAD registry.
Package crypto — the digital-signature port implemented by each scheme.
Package crypto — the process-wide Signer registry + GenerateKey / Sign / Verify dispatch.
Package crypto — the StreamSealer port: chunked authenticated encryption.
Package crypto — the process-wide StreamSealer registry + SealStream / OpenStream dispatch.
Index ¶
- Constants
- Variables
- func AgreementShared(name Algorithm, priv, peerPub []byte) (secret []byte, err error)
- func GenerateAgreementKey(name Algorithm) (pub, priv []byte, err error)
- func GenerateKey(name Algorithm) (pub, priv []byte, err error)
- func HashPassword(name Algorithm, password []byte) (phc string, err error)
- func MACTag(name Algorithm, key Key, message []byte) (tag []byte, err error)
- func MACVerify(name Algorithm, key Key, message, tag []byte) (ok bool, err error)
- func NeedsRehash(phc string) bool
- func NewHash(name Algorithm) (h hash.Hash, err error)
- func Open(key Key, box, aad []byte) (plaintext []byte, err error)
- func OpenStream(name Algorithm, key Key, src io.Reader, aad []byte) (opened io.Reader, err error)
- func Seal(name Algorithm, key Key, plaintext, aad []byte) (box []byte, err error)
- func SealStream(name Algorithm, key Key, dst io.Writer, aad []byte) (sealed io.WriteCloser, err error)
- func Sign(name Algorithm, priv, message []byte) (sig []byte, err error)
- func Subkey(name Algorithm, secret, salt []byte, info string, length int) (subkey []byte, err error)
- func Sum(name Algorithm, data []byte) (digest []byte, err error)
- func SumHex(name Algorithm, data []byte) (digest string, err error)
- func Verify(name Algorithm, pub, message, sig []byte) (ok bool, err error)
- func VerifyPassword(password []byte, phc string) (ok bool, err error)
- type AEAD
- type Agreement
- type Algorithm
- type Deriver
- type Hasher
- type Key
- type MAC
- type PasswordHasher
- type Signer
- type StreamSealer
Constants ¶
const CodeAgreementFailed errs.Code = 0x00_02_04_11 // 0.2.4.17
CodeAgreementFailed identifies an AgreementShared call whose scheme rejected the inputs (e.g. a low-order peer point) — wrapped, never leaking key bytes.
const CodeDecryptionFailed errs.Code = 0x00_02_04_04 // 0.2.4.4
CodeDecryptionFailed identifies any Open failure — bad authentication tag, malformed framing, unknown wire id, or wrong key. It is deliberately undifferentiated so Open cannot become a padding/format oracle.
const CodeDerivationFailed errs.Code = 0x00_02_04_0B // 0.2.4.11
CodeDerivationFailed identifies a Subkey call whose requested length exceeds the scheme's maximum output — a caller data error, not a fault.
const CodeDigestMismatch errs.Code = 0x00_02_04_14 // 0.2.4.20
CodeDigestMismatch identifies a VerifyingReader whose computed digest did not match the expected hex at EOF. The digest is public, so the mismatch is non-oracle — it surfaces only on the terminal read, never mid-stream.
const CodeDuplicateRegistration errs.Code = 0x00_02_04_01 // 0.2.4.1
CodeDuplicateRegistration identifies an init-time collision on a scheme registry; two distinct schemes tried to claim the same Algorithm or wire id. Surfaced via panic at boot through the DuplicateRegistration sentinel.
const CodeEntropyFailed errs.Code = 0x00_02_04_05 // 0.2.4.5
CodeEntropyFailed identifies a crypto/rand failure while generating a nonce in Seal — a host entropy fault, not a caller error.
const CodeInvalidKey errs.Code = 0x00_02_04_03 // 0.2.4.3
CodeInvalidKey identifies a NewKey call whose input was not exactly KeyLen bytes, or a cipher that rejected the key material.
const CodeInvalidKeyEnvelope errs.Code = 0x00_02_04_13 // 0.2.4.19
CodeInvalidKeyEnvelope identifies a structurally invalid key-envelope string passed to UnwrapKey — a corrupt $kenv$ frame, NOT a wrong-passphrase oracle.
const CodeInvalidPasswordHash errs.Code = 0x00_02_04_0E // 0.2.4.14
CodeInvalidPasswordHash identifies a stored PHC string that cannot be parsed during VerifyPassword — server-side data corruption, not a password mismatch.
const CodeKeyGenerationFailed errs.Code = 0x00_02_04_09 // 0.2.4.9
CodeKeyGenerationFailed identifies a crypto/rand failure while generating a signing keypair in GenerateKey — a host entropy fault, not a caller error.
const CodePasswordHashFailed errs.Code = 0x00_02_04_0D // 0.2.4.13
CodePasswordHashFailed identifies a crypto/rand failure while generating a password salt in HashPassword — a host entropy fault, not a caller error.
const CodeSigningFailed errs.Code = 0x00_02_04_08 // 0.2.4.8
CodeSigningFailed identifies a Sign call whose private key was not well-formed for the scheme (e.g. the wrong length) — a caller data error, not a fault.
const CodeStreamTruncated errs.Code = 0x00_02_04_12 // 0.2.4.18
CodeStreamTruncated identifies a streaming Open that hit EOF before the final-flag chunk — the stream was cut short, not legitimately ended.
const CodeUnknownAgreementAlgorithm errs.Code = 0x00_02_04_10 // 0.2.4.16
CodeUnknownAgreementAlgorithm identifies a GenerateAgreementKey/AgreementShared call naming a key-agreement Algorithm that no imported package has registered.
const CodeUnknownAlgorithm errs.Code = 0x00_02_04_02 // 0.2.4.2
CodeUnknownAlgorithm identifies a Seal/SealAs call naming an Algorithm that no imported package has registered.
const CodeUnknownHashAlgorithm errs.Code = 0x00_02_04_06 // 0.2.4.6
CodeUnknownHashAlgorithm identifies a Sum/SumHex call naming a hash Algorithm that no imported package has registered.
const CodeUnknownKDFAlgorithm errs.Code = 0x00_02_04_0A // 0.2.4.10
CodeUnknownKDFAlgorithm identifies a Subkey call naming a key-derivation Algorithm that no imported package has registered.
const CodeUnknownMACAlgorithm errs.Code = 0x00_02_04_0F // 0.2.4.15
CodeUnknownMACAlgorithm identifies a MACTag/MACVerify call naming a MAC Algorithm that no imported package has registered.
const CodeUnknownPasswordAlgorithm errs.Code = 0x00_02_04_0C // 0.2.4.12
CodeUnknownPasswordAlgorithm identifies a HashPassword/VerifyPassword call whose Algorithm (or PHC id segment) no imported package has registered.
const CodeUnknownSignatureAlgorithm errs.Code = 0x00_02_04_07 // 0.2.4.7
CodeUnknownSignatureAlgorithm identifies a Sign/Verify/GenerateKey call naming an Algorithm that no imported signature package has registered.
const KeyLen int = 32
KeyLen is the required symmetric key length in bytes (256-bit). Both shipped AEADs — AES-256-GCM and XChaCha20-Poly1305 — take a 32-byte key, so a single fixed length keeps the surface tiny and the validation total.
const Version byte = 0x01
Version is the box wire-format version, the first byte of every sealed box (Version[id][nonce][ciphertext||tag]). It is frozen post-v1.0.0; a future framing change bumps it and Open rejects an unknown version as DecryptionFailed. Concrete AEADs embed it via this constant.
Variables ¶
var ( // UnknownAlgorithm is returned by Seal/SealAs when no AEAD is registered // under the requested Algorithm — typically a missing blank-import. UnknownAlgorithm = errs.Static(CodeUnknownAlgorithm, "UNKNOWN_ALGORITHM", "No AEAD is registered under that algorithm", "core/crypto.Seal: algorithm absent from registry; blank-import the scheme's package to register it", 0, 0) // InvalidKey is returned by NewKey when the supplied material is not // exactly KeyLen bytes (or by an AEAD when the cipher rejects the key). InvalidKey = errs.Static(CodeInvalidKey, "INVALID_KEY", "Encryption key has the wrong length", "core/crypto.NewKey: key must be exactly KeyLen bytes", 0, 65) // DecryptionFailed is the single non-oracle error returned by Open for any // failure — bad tag, malformed framing, unknown wire id, or wrong key. DecryptionFailed = errs.Static(CodeDecryptionFailed, "DECRYPTION_FAILED", "Decryption failed", "core/crypto.Open: authentication, framing, or key check failed (cause withheld to avoid an oracle)", 400, 65) // EntropyFailed wraps a crypto/rand failure while generating a Seal nonce; // it signals a host entropy fault rather than a caller error. EntropyFailed = errs.Static(CodeEntropyFailed, "ENTROPY_FAILED", "Could not gather entropy for encryption", "core/crypto.Seal: crypto/rand.Read failed while generating a nonce", 0, 0) // UnknownHashAlgorithm is returned by Sum/SumHex when no Hasher is // registered under the requested Algorithm — typically a missing blank-import. UnknownHashAlgorithm = errs.Static(CodeUnknownHashAlgorithm, "UNKNOWN_HASH_ALGORITHM", "No hasher is registered under that algorithm", "core/crypto.Sum: hash algorithm absent from registry; blank-import the hasher's package to register it", 0, 0) // UnknownSignatureAlgorithm is returned by Sign/Verify/GenerateKey when no // Signer is registered under the requested Algorithm — usually a missing // blank-import of the scheme's package. UnknownSignatureAlgorithm = errs.Static(CodeUnknownSignatureAlgorithm, "UNKNOWN_SIGNATURE_ALGORITHM", "No signer is registered under that algorithm", "core/crypto.Sign: signature algorithm absent from registry; blank-import the signer's package to register it", 0, 0) // SigningFailed is returned by Sign when the supplied private key is not // well-formed for the scheme (e.g. the wrong length). SigningFailed = errs.Static(CodeSigningFailed, "SIGNING_FAILED", "Signing key is malformed", "core/crypto.Sign: private key is not valid for the scheme (wrong length or encoding)", 0, 65) // KeyGenerationFailed wraps a crypto/rand failure while generating a signing // keypair; it signals a host entropy fault rather than a caller error. KeyGenerationFailed = errs.Static(CodeKeyGenerationFailed, "KEY_GENERATION_FAILED", "Could not gather entropy for key generation", "core/crypto.GenerateKey: crypto/rand failed while generating a signing keypair", 0, 0) // UnknownKDFAlgorithm is returned by Subkey when no Deriver is registered // under the requested Algorithm — usually a missing blank-import. UnknownKDFAlgorithm = errs.Static(CodeUnknownKDFAlgorithm, "UNKNOWN_KDF_ALGORITHM", "No key-derivation function is registered under that algorithm", "core/crypto.Subkey: KDF algorithm absent from registry; blank-import the deriver's package to register it", 0, 0) // DerivationFailed is returned by Subkey when the requested length exceeds // the scheme's maximum output (e.g. HKDF's 255*HashLen ceiling). DerivationFailed = errs.Static(CodeDerivationFailed, "DERIVATION_FAILED", "Requested derived-key length is too large", "core/crypto.Subkey: requested length exceeds the scheme's maximum output", 0, 65) // UnknownPasswordAlgorithm is returned by HashPassword/VerifyPassword when no // PasswordHasher is registered under the requested Algorithm or PHC id — // usually a missing blank-import. UnknownPasswordAlgorithm = errs.Static(CodeUnknownPasswordAlgorithm, "UNKNOWN_PASSWORD_ALGORITHM", "No password hasher is registered under that algorithm", "core/crypto.VerifyPassword: password scheme absent from registry; blank-import the hasher's package to register it", 0, 0) // PasswordHashFailed wraps a crypto/rand failure while generating a password // salt; it signals a host entropy fault rather than a caller error. PasswordHashFailed = errs.Static(CodePasswordHashFailed, "PASSWORD_HASH_FAILED", "Could not gather entropy for password hashing", "core/crypto.HashPassword: crypto/rand failed while generating a salt", 0, 0) // InvalidPasswordHash is returned by VerifyPassword when the stored PHC // string cannot be parsed — server-side data corruption, never a mismatch. InvalidPasswordHash = errs.Static(CodeInvalidPasswordHash, "INVALID_PASSWORD_HASH", "Stored password hash is malformed", "core/crypto.VerifyPassword: stored PHC string is not well-formed for its scheme", 0, 0) // UnknownMACAlgorithm is returned by MACTag/MACVerify when no MAC is // registered under the requested Algorithm — typically a missing blank-import. UnknownMACAlgorithm = errs.Static(CodeUnknownMACAlgorithm, "UNKNOWN_MAC_ALGORITHM", "No MAC is registered under that algorithm", "core/crypto.MACTag: MAC algorithm absent from registry; blank-import the scheme's package to register it", 0, 0) // UnknownAgreementAlgorithm is returned by GenerateAgreementKey/AgreementShared // when no Agreement scheme is registered under the requested Algorithm. UnknownAgreementAlgorithm = errs.Static(CodeUnknownAgreementAlgorithm, "UNKNOWN_AGREEMENT_ALGORITHM", "No key-agreement scheme is registered under that algorithm", "core/crypto.AgreementShared: agreement algorithm absent from registry; blank-import the scheme's package to register it", 0, 0) // AgreementFailed wraps an AgreementShared fault where the scheme rejected the // inputs (e.g. a low-order peer point); it never leaks key bytes. AgreementFailed = errs.Static(CodeAgreementFailed, "AGREEMENT_FAILED", "Key agreement failed to derive a shared secret", "core/crypto.AgreementShared: the scheme rejected the inputs (cause withheld of key bytes)", 0, 65) // StreamTruncated is returned by a streaming Open reader when the stream ends // before its final-flag chunk — a truncated or tampered stream, not a clean EOF. StreamTruncated = errs.Static(CodeStreamTruncated, "STREAM_TRUNCATED", "The authenticated stream was truncated before its final chunk", "core/crypto.OpenStream: reader hit EOF before decrypting the final-flag chunk", 0, 65) // InvalidKeyEnvelope is returned by UnwrapKey when the supplied $kenv$ string // is structurally invalid (bad field count, magic, version, kdf/aead id, or // base64). It signals corruption only — a wrong passphrase surfaces the // non-oracle DecryptionFailed instead, so this is no key/password oracle. InvalidKeyEnvelope = errs.Static(CodeInvalidKeyEnvelope, "INVALID_KEY_ENVELOPE", "Key envelope is malformed", "service/crypto/key/keyenvelope.UnwrapKey: $kenv$ string is not well-formed", 0, 65) // DigestMismatch is returned by a VerifyingReader on its final (EOF) read when // the computed digest does not match the expected value. The digest is public, // so the comparison is non-oracle and surfaces only at the terminal read. DigestMismatch = errs.Static(CodeDigestMismatch, "DIGEST_MISMATCH", "Stream digest does not match the expected value", "service/crypto/hash/stdhash.VerifyingReader: computed digest differs from the expected hex at EOF", 0, 65) // DuplicateRegistration is the conflict every registrar refuses at boot: a // distinct scheme already holds the Algorithm — or, for an AEAD, the wire // id — a second one claims. The registrar panics with conflictText of it, // so the panic carries the dotted-quad header AND the key that collided. DuplicateRegistration = errs.Static(CodeDuplicateRegistration, "DUPLICATE_REGISTRATION", "A scheme is already registered under that algorithm or wire id", "core/crypto: a distinct scheme already holds this Algorithm, or this AEAD wire id", 0, 0) )
Functions ¶
func AgreementShared ¶
AgreementShared derives the raw shared secret with the Agreement scheme registered as name. The result MUST be passed through a KDF before use as a key. A name with no registered scheme returns UnknownAgreementAlgorithm; a scheme Shared fault is wrapped into AgreementFailed, leaking no key bytes.
func GenerateAgreementKey ¶
GenerateAgreementKey draws a fresh keypair from the Agreement scheme registered as name. A name with no registered scheme returns UnknownAgreementAlgorithm; an entropy fault from the scheme propagates unchanged so callers see the original cause.
func GenerateKey ¶
GenerateKey draws a fresh keypair for the Signer registered as name. A name with no registered signer returns UnknownSignatureAlgorithm (blank-import the scheme's package to register it).
func HashPassword ¶
HashPassword returns a PHC-string hash of password using the PasswordHasher registered as name. A name with no registered hasher returns UnknownPasswordAlgorithm (blank-import the scheme's package to register it).
func MACTag ¶
MACTag returns the authentication tag over message under key for the MAC registered as name. It is named MACTag (not Tag) so the dispatch verb never collides with the signer/verifier surface. A name with no registered MAC returns UnknownMACAlgorithm (blank-import the scheme's package to register it).
func MACVerify ¶
MACVerify reports whether tag authenticates message under key for the MAC registered as name, using the scheme's constant-time comparison. A name with no registered MAC returns (false, UnknownMACAlgorithm) so a miss is never mistaken for a bad-tag false.
func NeedsRehash ¶
NeedsRehash reports whether the stored PHC hash was produced with cost parameters weaker than its scheme's current policy, so a caller can re-hash on a successful login. A malformed or unknown-scheme phc reports false.
func NewHash ¶
NewHash returns a fresh streaming hash.Hash for the Hasher registered as name (for io.Copy over large inputs). A name with no registered hasher returns UnknownHashAlgorithm.
func Open ¶
Open decrypts a box produced by Seal, verifying aad, and returns the plaintext. The scheme is resolved from the box's 1-byte id header — the caller never names it. Any failure (short box, unknown id, bad tag, wrong key) returns the single non-oracle DecryptionFailed.
func OpenStream ¶
OpenStream wraps src so reads are opened under key with aad by the StreamSealer registered as name. A name with no registered sealer returns the shared UnknownAlgorithm sentinel; a truncated stream surfaces later as StreamTruncated from the returned reader.
func Seal ¶
Seal encrypts plaintext under the AEAD registered as name, binding aad, and returns the self-framed box. A name with no registered scheme returns UnknownAlgorithm (blank-import the scheme's package to register it).
func SealStream ¶
func SealStream(name Algorithm, key Key, dst io.Writer, aad []byte) (sealed io.WriteCloser, err error)
SealStream wraps dst so writes are sealed under key with aad by the StreamSealer registered as name. Streaming extends the AEAD domain, so a name with no registered sealer returns the shared UnknownAlgorithm sentinel; a scheme construction fault propagates unchanged.
func Sign ¶
Sign produces a detached signature over message using priv under the Signer registered as name. A name with no registered signer returns UnknownSignatureAlgorithm; a malformed priv returns SigningFailed.
func Subkey ¶
func Subkey(name Algorithm, secret, salt []byte, info string, length int) (subkey []byte, err error)
Subkey derives a length-byte subkey from secret (with optional salt and the context label info) using the Deriver registered as name. A name with no registered deriver returns UnknownKDFAlgorithm (blank-import the scheme's package to register it); an over-long length returns DerivationFailed.
func Sum ¶
Sum returns the digest of data under the Hasher registered as name. A name with no registered hasher returns UnknownHashAlgorithm (blank-import the scheme's package to register it).
func SumHex ¶
SumHex is Sum rendered as canonical lowercase hex — the frozen string form for content IDs and cache keys.
func Verify ¶
Verify reports whether sig is a valid signature for message under pub for the Signer registered as name. An unregistered name returns (false, UnknownSignatureAlgorithm); an invalid signature is (false, nil) so Verify never becomes an oracle on WHY a check failed.
func VerifyPassword ¶
VerifyPassword reports whether password matches the stored PHC hash. The scheme is read from phc's id segment — no algorithm argument is needed. A malformed phc or unregistered scheme returns an error; a genuine mismatch is (false, nil).
Types ¶
type AEAD ¶
type AEAD interface {
// Algorithm reports the canonical key under which this scheme registers.
Algorithm() Algorithm
// ID reports the 1-byte wire identifier embedded in the box header so Open
// can resolve the scheme without the caller naming it.
ID() byte
// Seal encrypts plaintext, binding aad, and returns the self-framed box
// (Version + id + random nonce + ciphertext||tag).
Seal(key Key, plaintext, aad []byte) (box []byte, err error)
// Open reverses Seal: it validates the framing, decrypts, and verifies aad,
// returning the plaintext or the non-oracle DecryptionFailed.
Open(key Key, box, aad []byte) (plaintext []byte, err error)
}
AEAD is an authenticated-encryption-with-associated-data scheme. Each implementation owns its complete self-describing wire framing (Version[id][nonce][ciphertext||tag]) so the registry can dispatch Open by reading the 1-byte id, and so the nonce — generated from crypto/rand inside Seal — never reaches a caller. Implementations MUST be safe for concurrent use and MUST return the shared non-oracle DecryptionFailed for every Open failure (bad tag, bad header, wrong key) so they cannot become an oracle.
IFACE-PLUGIN: the registry hands plug-in AEAD instances back to callers behind this interface; concrete scheme types stay unexported in their own packages.
func Lookup ¶
Lookup returns the AEAD registered under name.
IFACE-PLUGIN: the registry stores plug-in scheme instances behind the AEAD interface — concrete types are intentionally unexported per scheme.
func Register ¶
Register inserts a into the registry under a.Algorithm() + a.ID() and returns it so callers can bind the singleton to a typed package-level variable like `var AEAD = crypto.Register(aesGCM{})`. Panics on a nil scheme or when a distinct scheme already claims the same Algorithm or wire id.
IFACE-PLUGIN: the registry hands plug-in AEAD instances back to callers so each scheme keeps its concrete type unexported; the stable contract is the AEAD interface itself.
"Nil" here means UNUSABLE, not only an untyped nil: a typed nil pointer and a plug-in whose type is not comparable both satisfy the port and neither can serve one call (see internal/kernel/plugin).
type Agreement ¶
type Agreement interface {
// Algorithm reports the canonical key under which this scheme registers.
Algorithm() Algorithm
// GenerateKey draws a fresh public/private keypair from the scheme's
// entropy source.
GenerateKey() (pub, priv []byte, err error)
// MUST be passed through a KDF before any use as a key.
Shared(priv, peerPub []byte) (secret []byte, err error)
}
Agreement is a key-agreement scheme (Diffie-Hellman style): it produces an ephemeral keypair and derives a shared secret from a local private key and a peer public key. The raw Shared output is low-level key material and MUST be run through a KDF (a Deriver) before use as a key — the pkg/v1 facade never hands the raw secret back to generic callers. Implementations self-register via RegisterAgreement.
IFACE-PLUGIN: the registry hands plug-in Agreement instances back behind this interface; concrete scheme types stay unexported in their own packages.
func LookupAgreement ¶
LookupAgreement returns the Agreement scheme registered under name.
IFACE-PLUGIN: the registry stores plug-in Agreement instances behind the Agreement interface — concrete types are intentionally unexported per scheme.
func RegisterAgreement ¶
RegisterAgreement inserts a under a.Algorithm() and returns it so callers can bind the singleton to a typed package-level variable. Panics on a nil scheme or when a distinct scheme already claims the same Algorithm.
IFACE-PLUGIN: the registry hands plug-in Agreement instances back to callers so each scheme keeps its concrete type unexported; the contract is the Agreement interface itself.
"Nil" here means UNUSABLE, not only an untyped nil: a typed nil pointer and a plug-in whose type is not comparable both satisfy the port and neither can serve one call (see internal/kernel/plugin).
type Algorithm ¶
type Algorithm string
Algorithm is the typed key under which an AEAD registers (e.g. "aes-256-gcm"). The zero value Algorithm("") is reserved invalid, mirroring codec.Format.
func Available ¶
func Available() []Algorithm
Available returns the sorted list of registered Algorithms, or nil before any Register.
func AvailableAgreements ¶
func AvailableAgreements() []Algorithm
AvailableAgreements returns the sorted list of registered agreement Algorithms.
func AvailableDerivers ¶
func AvailableDerivers() []Algorithm
AvailableDerivers returns the sorted list of registered KDF Algorithms.
func AvailableHashers ¶
func AvailableHashers() []Algorithm
AvailableHashers returns the sorted list of registered hash Algorithms.
func AvailableMACs ¶
func AvailableMACs() []Algorithm
AvailableMACs returns the sorted list of registered MAC Algorithms.
func AvailablePasswordHashers ¶
func AvailablePasswordHashers() []Algorithm
AvailablePasswordHashers returns the sorted list of registered password Algorithms.
func AvailableSigners ¶
func AvailableSigners() []Algorithm
AvailableSigners returns the sorted list of registered signature Algorithms.
func AvailableStreamSealers ¶
func AvailableStreamSealers() []Algorithm
AvailableStreamSealers returns the sorted list of registered streaming-AEAD Algorithms.
type Deriver ¶
type Deriver interface {
// Algorithm reports the canonical key under which this scheme registers.
Algorithm() Algorithm
// Derive expands secret (with optional salt and the context label info) into
// a length-byte subkey, or DerivationFailed when length exceeds the scheme's
// maximum output.
Derive(secret, salt []byte, info string, length int) (subkey []byte, err error)
}
Deriver is a key-derivation function for KEY SEPARATION: it expands one high-entropy secret into independent, purpose-bound subkeys. It is NOT a password hash — the input must already be a strong key (an AEAD Key, an HKDF PRK, a Diffie-Hellman shared secret), never a human password. Password stretching (argon2id) is a separate, deliberately slow port.
salt is optional domain randomness (nil is allowed); info is a context label that binds each subkey to its purpose ("aead-key", "mac-key", …) so two derivations from the same secret never collide. Implementations MUST be safe for concurrent use.
IFACE-PLUGIN: the registry hands plug-in Deriver instances back to callers behind this interface; concrete scheme types stay unexported in their own packages.
func LookupDeriver ¶
LookupDeriver returns the Deriver registered under name.
IFACE-PLUGIN: the registry stores plug-in Deriver instances behind the Deriver interface — concrete types are intentionally unexported per scheme.
func RegisterDeriver ¶
RegisterDeriver inserts d under d.Algorithm() and returns it so callers can bind the singleton to a typed package-level variable like `var Deriver = crypto.RegisterDeriver(hkdfSHA256{})`. Panics on a nil deriver or when a distinct deriver already claims the same Algorithm.
IFACE-PLUGIN: the registry hands plug-in Deriver instances back to callers so each scheme keeps its concrete type unexported; the stable contract is the Deriver interface itself.
"Nil" here means UNUSABLE, not only an untyped nil: a typed nil pointer and a plug-in whose type is not comparable both satisfy the port and neither can serve one call (see internal/kernel/plugin).
type Hasher ¶
type Hasher interface {
// Algorithm reports the canonical key under which this hasher registers.
Algorithm() Algorithm
// New returns a fresh hash.Hash for streaming (io.Copy) or one-shot use.
New() hash.Hash
}
Hasher is a fingerprint / content-addressing hash scheme producing a non-keyed digest of arbitrary bytes (content IDs, cache keys, dedup keys).
It is explicitly NOT authentication: no Hasher is a MAC, none takes a key, and a digest is public — never branch on a secret-dependent comparison of one. Keyed/authenticated integrity belongs to the AEAD and (future) signature ports. Implementations self-register via RegisterHasher.
IFACE-PLUGIN: the registry hands plug-in Hasher instances back behind this interface; concrete scheme types stay unexported in their own packages.
func LookupHasher ¶
LookupHasher returns the Hasher registered under name.
IFACE-PLUGIN: the registry stores plug-in Hasher instances behind the Hasher interface — concrete types are intentionally unexported per scheme.
func RegisterHasher ¶
RegisterHasher inserts h under h.Algorithm() and returns it so callers can bind the singleton to a typed package-level variable like `var Hasher = crypto.RegisterHasher(sha256Hasher{})`. Panics on a nil hasher or when a distinct hasher already claims the same Algorithm.
IFACE-PLUGIN: the registry hands plug-in Hasher instances back to callers so each scheme keeps its concrete type unexported; the stable contract is the Hasher interface itself.
"Nil" here means UNUSABLE, not only an untyped nil: a typed nil pointer and a plug-in whose type is not comparable both satisfy the port and neither can serve one call (see internal/kernel/plugin).
type Key ¶
type Key struct {
// contains filtered or unexported fields
}
Key is an opaque, redacting 256-bit symmetric key. Every rendering — String, GoString and Format, so %v, %s, %#v, %d and every other verb — writes "<redacted>", so an accidental print never leaks the secret; Bytes hands a fresh copy to the cipher and is the only way out. All copies of a Key share one backing array, so Zeroize on any copy clears the secret everywhere — call it when you are done with the key.
The bytes sit behind a pointer rather than in the struct: fmt cannot call Format on a Key held in an UNEXPORTED field of another struct, so it prints that field's own fields instead, and a pointer prints an address where a slice would print the key as a list of byte values. A zero-size field of a non-comparable type keeps == from compiling, so no pointer comparison can pass for a key comparison.
func NewKey ¶
NewKey builds a Key from raw, which MUST be exactly KeyLen (32) bytes. A wrong length returns InvalidKey rather than silently truncating or padding; the bytes are copied so a later mutation of raw cannot affect the Key.
func (Key) Bytes ¶
Bytes returns a fresh copy of the raw key material for handoff to a cipher. Callers MUST NOT log the result; the redaction only covers the renderings. A zero-value Key returns nil.
func (Key) Format ¶ added in v0.13.0
Format implements fmt.Formatter, so EVERY verb writes "<redacted>" — %d included, which bypasses String and would otherwise print the struct's bytes. %q writes it quoted.
func (Key) GoString ¶
GoString implements fmt.GoStringer so %#v stays redacted too — fmt bypasses String for Go-syntax formatting and would otherwise dump the raw slice.
type MAC ¶
type MAC interface {
// Algorithm reports the canonical key under which this MAC registers.
Algorithm() Algorithm
// Tag returns the authentication tag over message under key.
Tag(key Key, message []byte) []byte
// Verify reports whether tag authenticates message under key, using a
// constant-time comparison so it never becomes a timing oracle.
Verify(key Key, message, tag []byte) bool
// New returns a fresh streaming hash.Hash keyed by key, paralleling
// Hasher.New, for incremental tagging over large inputs.
New(key Key) hash.Hash
}
MAC is a detached message-authentication-code scheme: it binds a secret Key to a message and yields an authentication tag. Unlike a Hasher digest, a MAC tag IS secret-comparison-sensitive — callers MUST route equality through Verify (constant-time), never `==` or bytes.Equal, which is the exact inverse of the Hasher rule. Implementations self-register via RegisterMAC.
IFACE-PLUGIN: the registry hands plug-in MAC instances back behind this interface; concrete scheme types stay unexported in their own packages.
func LookupMAC ¶
LookupMAC returns the MAC registered under name.
IFACE-PLUGIN: the registry stores plug-in MAC instances behind the MAC interface — concrete types are intentionally unexported per scheme.
func RegisterMAC ¶
RegisterMAC inserts m under m.Algorithm() and returns it so callers can bind the singleton to a typed package-level variable. Panics on a nil MAC or when a distinct MAC already claims the same Algorithm.
IFACE-PLUGIN: the registry hands plug-in MAC instances back to callers so each scheme keeps its concrete type unexported; the contract is the MAC interface.
"Nil" here means UNUSABLE, not only an untyped nil: a typed nil pointer and a plug-in whose type is not comparable both satisfy the port and neither can serve one call (see internal/kernel/plugin).
type PasswordHasher ¶
type PasswordHasher interface {
// Algorithm reports the canonical key under which this scheme registers; it
// is also the PHC id segment (the first `$`-delimited field).
Algorithm() Algorithm
// Hash returns a PHC-string hash of password with a fresh random salt and
// the scheme's current cost parameters, or PasswordHashFailed on an entropy
// fault.
Hash(password []byte) (phc string, err error)
// Verify reports whether password matches the stored PHC hash, comparing in
// constant time. A malformed phc returns InvalidPasswordHash; a genuine
// mismatch is (false, nil) so Verify is not an oracle on WHY it failed.
Verify(password []byte, phc string) (ok bool, err error)
// NeedsRehash reports whether phc was produced with cost parameters weaker
// than this scheme's current policy, so callers can transparently re-hash on
// a successful login. A malformed phc reports false (Verify surfaces the error).
NeedsRehash(phc string) (stale bool)
}
PasswordHasher stretches a human password into a slow, salted, self-describing PHC-string hash for storage. UNLIKE the Deriver (key separation) and Hasher (fingerprints) ports, this one is DELIBERATELY SLOW and salted: it is the only crypto surface meant to consume a low-entropy human secret.
The returned hash is a PHC string (`$id$params$salt$digest`) that embeds the scheme id and its cost parameters, so Verify needs no side-channel: the stored string fully describes how to check it. Implementations MUST compare digests in constant time and MUST be safe for concurrent use.
IFACE-PLUGIN: the registry hands plug-in PasswordHasher instances back to callers behind this interface; concrete scheme types stay unexported.
func LookupPasswordHasher ¶
func LookupPasswordHasher(name Algorithm) (p PasswordHasher, ok bool)
LookupPasswordHasher returns the PasswordHasher registered under name.
IFACE-PLUGIN: the registry stores plug-in PasswordHasher instances behind the PasswordHasher interface — concrete types are intentionally unexported per scheme.
func RegisterPasswordHasher ¶
func RegisterPasswordHasher(p PasswordHasher) PasswordHasher
RegisterPasswordHasher inserts p under p.Algorithm() and returns it so callers can bind the singleton to a typed package-level variable. Panics on a nil hasher or when a distinct hasher already claims the same Algorithm.
IFACE-PLUGIN: the registry hands plug-in PasswordHasher instances back to callers so each scheme keeps its concrete type unexported; the contract is the PasswordHasher interface itself.
"Nil" here means UNUSABLE, not only an untyped nil: a typed nil pointer and a plug-in whose type is not comparable both satisfy the port and neither can serve one call (see internal/kernel/plugin).
type Signer ¶
type Signer interface {
// Algorithm reports the canonical key under which this scheme registers.
Algorithm() Algorithm
// GenerateKey draws a fresh keypair from crypto/rand, returning the public
// and private key bytes (or KeyGenerationFailed on a host entropy fault).
GenerateKey() (pub, priv []byte, err error)
// Sign produces a detached signature over message using priv, or
// SigningFailed when priv is not a well-formed private key for this scheme.
Sign(priv, message []byte) (sig []byte, err error)
// Verify reports whether sig is a valid signature for message under pub. A
// malformed key or signature is reported as false, never as a panic.
Verify(pub, message, sig []byte) (ok bool)
}
Signer is a detached digital-signature scheme over a public/private keypair. Keys and signatures are scheme-specific byte slices (their lengths are fixed per scheme); the registry dispatches on the Algorithm name. Implementations MUST be safe for concurrent use, MUST NOT panic on a malformed key (return SigningFailed instead), and Verify MUST run in constant time with respect to the signature so it cannot become a timing oracle.
Unlike the AEAD port, a signature scheme has no hidden nonce and no wire framing: the caller holds the keypair and chooses what bytes to sign. The private key is secret material — treat it like Key.Bytes(): never log it.
IFACE-PLUGIN: the registry hands plug-in Signer instances back to callers behind this interface; concrete scheme types stay unexported in their own packages.
func LookupSigner ¶
LookupSigner returns the Signer registered under name.
IFACE-PLUGIN: the registry stores plug-in Signer instances behind the Signer interface — concrete types are intentionally unexported per scheme.
func RegisterSigner ¶
RegisterSigner inserts s under s.Algorithm() and returns it so callers can bind the singleton to a typed package-level variable. Panics on a nil signer or when a distinct signer already claims the same Algorithm.
IFACE-PLUGIN: the registry hands plug-in Signer instances back to callers so each scheme keeps its concrete type unexported; the contract is the Signer interface itself.
"Nil" here means UNUSABLE, not only an untyped nil: a typed nil pointer and a plug-in whose type is not comparable both satisfy the port and neither can serve one call (see internal/kernel/plugin).
type StreamSealer ¶
type StreamSealer interface {
// Algorithm reports the canonical key under which this scheme registers.
Algorithm() Algorithm
// Writer wraps dst so writes are sealed under key with aad; Close writes
// the final authenticated chunk.
Writer(key Key, dst io.Writer, aad []byte) (io.WriteCloser, error)
// Reader wraps src so reads are opened under key with aad; a truncated
// stream surfaces as StreamTruncated from the returned reader.
Reader(key Key, src io.Reader, aad []byte) (io.Reader, error)
}
StreamSealer is a streaming authenticated-encryption scheme: it seals and opens an io.Writer / io.Reader pair in fixed-size chunks under a Key and associated data, extending the whole-buffer AEAD domain to arbitrarily large payloads. The Reader honours the hold-back contract: it MUST NOT surface a chunk's plaintext downstream before that chunk authenticates, and a stream cut short surfaces as StreamTruncated rather than as accepted plaintext (the final chunk carries a flag that a truncated stream never reaches). Implementations self-register via RegisterStreamSealer.
IFACE-PLUGIN: the registry hands plug-in StreamSealer instances back behind this interface; concrete scheme types stay unexported in their own packages.
func LookupStreamSealer ¶
func LookupStreamSealer(name Algorithm) (s StreamSealer, ok bool)
LookupStreamSealer returns the StreamSealer registered under name.
IFACE-PLUGIN: the registry stores plug-in StreamSealer instances behind the StreamSealer interface — concrete types are intentionally unexported per scheme.
func RegisterStreamSealer ¶
func RegisterStreamSealer(s StreamSealer) StreamSealer
RegisterStreamSealer inserts s under s.Algorithm() and returns it so callers can bind the singleton to a typed package-level variable. Panics on a nil sealer or when a distinct sealer already claims the same Algorithm.
IFACE-PLUGIN: the registry hands plug-in StreamSealer instances back to callers so each scheme keeps its concrete type unexported; the contract is the StreamSealer interface itself.
"Nil" here means UNUSABLE, not only an untyped nil: a typed nil pointer and a plug-in whose type is not comparable both satisfy the port and neither can serve one call (see internal/kernel/plugin).