一键导入
subsystem-summary-of-crypto
read this skill for a token-efficient summary of the crypto subsystem
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
read this skill for a token-efficient summary of the crypto subsystem
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
extending yourself with a new reusable skill by interviewing the user
analyzing a change to determine what tests are needed and adding them to the test suite
modifying build configuration to enable/disable variants, switch compilers or flags, or otherwise prepare for a build
reviewing a change for semantic correctness, simplicity, design consistency, and completeness
reviewing a git diff for small localized coding mistakes that can be fixed without high-level understanding
how to run make correctly to get a good build, and otherwise understand the build system
| name | subsystem-summary-of-crypto |
| description | read this skill for a token-efficient summary of the crypto subsystem |
The src/crypto/ subsystem provides all cryptographic primitives for stellar-core: hashing (SHA-256, BLAKE2b, SipHash), Ed25519 key management and signatures, Curve25519 ECDH key agreement, StrKey encoding/decoding, hex utilities, and random number generation. It is built on top of libsodium and uses xdrpp for serialization. There are no background threads or event loops in this subsystem; it is a stateless utility layer with one notable piece of process-wide shared state: the signature verification cache.
ByteSlice (ByteSlice.h)A lightweight, non-owning, read-only view over contiguous byte data. Acts as a universal adaptor for passing byte containers into crypto functions. Implicitly constructs from xdr::opaque_array<N>, xdr::msg_ptr, std::vector<uint8_t>, std::string, rust::Vec<uint8_t>, RustBuf, char const*, and raw (void*, size_t). Provides data(), size(), begin(), end(), operator[] (bounds-checked), and empty().
CryptoError (CryptoError.h)Simple exception class inheriting std::runtime_error. Thrown by all crypto functions on failure (e.g., libsodium errors, invalid inputs).
SecretKey (SecretKey.h / SecretKey.cpp)Represents an Ed25519 signing keypair (secret key + derived public key).
Internal state:
mKeyType (PublicKeyType) — always PUBLIC_KEY_TYPE_ED25519mSecretKey (uint512 / 64-byte opaque array) — the libsodium combined secret keymPublicKey (PublicKey) — the corresponding public key (XDR type)Seed struct holds a 32-byte seed; its destructor zeroes memory.Key methods:
getPublicKey() — returns const ref to mPublicKeygetStrKeySeed() — returns StrKey-encoded seed as SecretValuegetStrKeyPublic() — returns StrKey-encoded public key as std::stringisZero() — true if seed is all-zerosign(ByteSlice) — produces a 64-byte Ed25519 detached signature via crypto_sign_detachedrandom() — generates a cryptographically random keypair via crypto_sign_keypairfromSeed(ByteSlice) — derives keypair from a 32-byte seed via crypto_sign_seed_keypairfromStrKeySeed(string) — decodes a StrKey seed string, then derives keypairDestructor zeroes mSecretKey memory to prevent key leakage.
PublicKey (XDR-defined, utilities in SecretKey.h/cpp)The XDR union type for public keys. The crypto subsystem provides KeyFunctions<PublicKey> specialization and the PubKeyUtils namespace.
PubKeyUtils namespace (SecretKey.h / SecretKey.cpp)Signature verification and public key utilities.
Key functions:
verifySig(PublicKey, Signature, ByteSlice) → VerifySigResult — Verifies an Ed25519 signature. Uses a process-wide RandomEvictionCache<Hash, bool> (capacity 250,000 entries) protected by gVerifySigCacheMutex. Returns both the validity result and whether it was a cache hit/miss. Supports switching between libsodium (crypto_sign_verify_detached) and Rust ed25519-dalek (rust_bridge::verify_ed25519_signature_dalek) at the protocol 24 boundary.clearVerifySigCache() — clears the global cacheseedVerifySigCache(unsigned int) — seeds the cache's random eviction PRNGflushVerifySigCacheCounts(hits, misses) — atomically reads and resets cache hit/miss countersenableRustDalekVerify() — one-way flag to switch signature verification to Rust ed25519-dalekrandom() — generates a random (non-signing-capable) public keyVerifySigResult (SecretKey.h)Struct with two fields: bool valid (signature validity) and VerifySigCacheLookupResult cacheResult (enum: MISS, HIT, NO_LOOKUP).
Free functions:
sha256(ByteSlice) → uint256 — one-shot SHA-256 hash via crypto_hash_sha256subSha256(ByteSlice seed, uint64_t counter) → Hash — SHA-256 of seed concatenated with XDR-serialized counter; used for sub-seeding per-transaction PRNGs in SorobanhmacSha256(HmacSha256Key, ByteSlice) → HmacSha256Mac — HMAC-SHA-256 via crypto_auth_hmacsha256hmacSha256Verify(HmacSha256Mac, HmacSha256Key, ByteSlice) → bool — constant-time HMAC verification via crypto_auth_hmacsha256_verifyhkdfExtract(ByteSlice) → HmacSha256Key — unsalted HKDF-extract: HMAC(<zero_key>, bytes)hkdfExpand(HmacSha256Key, ByteSlice) → HmacSha256Key — single-step HKDF-expand: HMAC(key, bytes||0x01)SHA256 class — incremental (streaming) SHA-256 hasher:
reset() — reinitializes stateadd(ByteSlice) — feeds datafinish() → uint256 — finalizes and returns hash (single use; throws if called again)XDRSHA256 struct — CRTP subclass of XDRHasher<XDRSHA256> wrapping SHA256. Used by xdrSha256<T>(t) template to hash any XDR object without intermediate serialization buffer.
Free function:
blake2(ByteSlice) → uint256 — one-shot BLAKE2b (256-bit output) via crypto_generichashBLAKE2 class — incremental BLAKE2b hasher (same API pattern as SHA256):
reset(), add(ByteSlice), finish() → uint256XDRBLAKE2 struct — CRTP subclass of XDRHasher<XDRBLAKE2> wrapping BLAKE2. Used by xdrBlake2<T>(t) template.
BLAKE2 is used internally in the signature verification cache key computation (verifySigCacheKey hashes public key + signature + message via BLAKE2).
Fast, randomized, non-cryptographic hash for in-memory data structures (hash maps, etc.).
shortHash namespace:
initialize() — generates a random per-process SipHash key via crypto_shorthash_keygen; must be called once at startupgetShortHashInitKey() → array<unsigned char, 16> — returns current key (used for child process inheritance)computeHash(ByteSlice) → uint64_t — SipHash-2-4 via crypto_shorthash, mutex-protected to set gHaveHashed flagxdrComputeHash<T>(t) → uint64_t — hashes any XDR object without intermediate buffer, using XDRShortHasherXDRShortHasher struct — CRTP subclass of XDRHasher<XDRShortHasher> wrapping SipHash24 state. Initialized with the process-wide key.
Thread safety: All access to the global key gKey is mutex-protected via gKeyMutex.
CRTP base class template XDRHasher<Derived> providing an xdrpp-compatible archiver that feeds XDR-serialized bytes to a hash function without allocating an intermediate serialization buffer.
Mechanism:
mBuf) for batching small writesqueueOrHash(bytes, size) — buffers small writes; flushes and calls Derived::hashBytes() for larger onesflush() — sends any buffered bytes to the derived hasheroperator() overloads handle XDR scalars (32/64-bit with endian swap), byte arrays (with XDR padding), and composite types (delegating to xdr::xdr_traits<T>::save)Three concrete derivations: XDRSHA256, XDRBLAKE2, XDRShortHasher.
Implements Stellar's base32-encoded key format with version byte and CRC-16 checksum.
strKey namespace:
StrKeyVersionByte enum — version bytes for different key types: STRKEY_PUBKEY_ED25519 ('G'), STRKEY_SEED_ED25519 ('S'), STRKEY_PRE_AUTH_TX ('T'), STRKEY_HASH_X ('X'), STRKEY_SIGNED_PAYLOAD_ED25519 ('P'), STRKEY_MUXED_ACCOUNT_ED25519 ('M'), STRKEY_CONTRACT ('C')toStrKey(ver, ByteSlice) → SecretValue — encodes: base32(version_byte || payload || crc16)fromStrKey(string, &ver, &decoded) → bool — decodes and validates CRC-16 checksumgetStrKeySize(dataSize) → size_t — computes encoded string length for a given payload sizeTemplate-based key conversion utilities using the KeyFunctions<T> trait.
KeyFunctions<T> trait — specialization point for each key type, providing:
getKeyTypeName(), getKeyVersionIsSupported(), getKeyVersionIsVariableLength()toKeyType() / toKeyVersion() — convert between StrKeyVersionByte and the key type enumgetEd25519Value() / getKeyValue() / setKeyValue() — access raw key bytesSpecializations provided: KeyFunctions<PublicKey> (in SecretKey.h/cpp), KeyFunctions<SignerKey> (in SignerKey.h/cpp).
KeyUtils namespace template functions:
toStrKey<T>(key) — converts any key type to StrKey stringtoShortString<T>(key) — first 5 characters of StrKey (for logging)fromStrKey<T>(string) — parses StrKey string into a typed keygetKeyVersionSize(StrKeyVersionByte) — returns expected raw key size for a version bytecanConvert<T, F>(fromKey) — checks if key type conversion is possibleconvertKey<T, F>(fromKey) — converts between key types sharing the same Ed25519 valueHex encoding/decoding utilities using libsodium.
binToHex(ByteSlice) → string — hex-encodes byteshexAbbrev(ByteSlice) → string — returns first 6 hex characters (3 bytes) for logginghexToBin(string) → vector<uint8_t> — hex-decodes a stringhexToBin256(string) → uint256 — hex-decodes exactly 32 bytes, throws otherwiseProvides KeyFunctions<SignerKey> specialization supporting four signer key types:
SIGNER_KEY_TYPE_ED25519 — standard Ed25519 public keySIGNER_KEY_TYPE_PRE_AUTH_TX — pre-authorized transaction hashSIGNER_KEY_TYPE_HASH_X — hash(x) preimage signerSIGNER_KEY_TYPE_ED25519_SIGNED_PAYLOAD — Ed25519 key with attached payload (variable length, up to 96 bytes)Factory functions for creating SignerKey objects:
preAuthTxKey(TransactionFrame) — creates a pre-auth signer key from a transaction's contents hashpreAuthTxKey(FeeBumpTransactionFrame) — same for fee-bump transactionshashXKey(ByteSlice) — creates a hash-x signer key by SHA-256 hashing the inputed25519PayloadKey(uint256, opaque_vec<64>) — creates an ed25519-signed-payload signer keyProvides Curve25519 Diffie-Hellman key agreement for the P2P overlay authentication system (PeerAuth). These keys are distinct from Ed25519 signing keys and are generated per-session.
Key functions:
curve25519RandomSecret() → Curve25519Secret — generates random 32-byte scalar via randombytes_bufcurve25519DerivePublic(Curve25519Secret) → Curve25519Public — derives public point via crypto_scalarmult_baseclearCurve25519Keys(pub, sec) — zeroes both keys via sodium_memzerocurve25519DeriveSharedKey(localSecret, localPublic, remotePublic, localFirst) → HmacSha256Key — performs ECDH (crypto_scalarmult), concatenates shared_secret || publicA || publicB (ordered by localFirst), then applies hkdfExtractcurve25519Encrypt<N>(remotePublic, ByteSlice) → opaque_vec<N> — sealed box encryption via crypto_box_sealcurve25519Decrypt(localSecret, localPublic, ByteSlice) → opaque_vec<> — sealed box decryption via crypto_box_seal_openrandomBytes(size_t length) → vector<uint8_t> — generates cryptographically secure random bytes via libsodium's randombytes_buf. In fuzzing builds, uses a deterministic PRNG instead.StrKeyUtils::logKey(ostream, string) (SecretKey.cpp)Attempts to interpret a key string in all known formats (public key StrKey, seed StrKey, raw hex) and logs all possible interpretations. Used for diagnostic/debugging output.
HashUtils namespace (SecretKey.h / SecretKey.cpp)random() → Hash — generates a random 32-byte hash via randombytes_bufThe crypto subsystem is mostly stateless/pure-functional. The two pieces of process-wide shared mutable state are:
Signature verification cache (gVerifySigCache, gVerifyCacheHit, gVerifyCacheMiss, gUseRustDalekVerify) — protected by gVerifySigCacheMutex. The cache is a RandomEvictionCache<Hash, bool> of 250K entries. Cache keys are BLAKE2 hashes of (public_key || signature || message). Access is serialized by mutex, but individual verify operations are performed outside the lock.
ShortHash global key (gKey, gHaveHashed) — protected by gKeyMutex. Initialized once at startup via shortHash::initialize().
There are no background threads, event loops, or async tasks in the crypto subsystem.
SecretKey::sign(message) → crypto_sign_detached(message, secret_key) → 64-byte Signature
PubKeyUtils::verifySig(pubkey, sig, message) → compute BLAKE2 cache key → lock mutex → check gVerifySigCache → if miss, unlock, verify via libsodium or Rust dalek (depending on gUseRustDalekVerify flag) → lock mutex → insert result into cache → return VerifySigResult
Raw key bytes → strKey::toStrKey(version_byte, bytes) → prepend version byte, append CRC-16 → base32-encode → StrKey string
StrKey string → strKey::fromStrKey() → base32-decode → verify CRC-16 → extract version byte and payload → KeyUtils::fromStrKey<T>() → construct typed key
curve25519RandomSecret() → curve25519DerivePublic() → exchange public keys → curve25519DeriveSharedKey() → crypto_scalarmult (ECDH) → concatenate with ordered public keys → hkdfExtract() → HmacSha256Key
Any XDR object → xdrSha256<T>(t) / xdrBlake2<T>(t) / shortHash::xdrComputeHash<T>(t) → xdr::archive(hasher, t) → XDRHasher::operator() dispatches by XDR type → batched hashBytes() calls → finalize
SecretKey owns its mSecretKey (64-byte secret), mPublicKey (XDR PublicKey), and mKeyTypeByteSlice borrows (non-owning view) from any byte containerSHA256, BLAKE2 classes own their respective libsodium hash statesXDRHasher<D> owns a 256-byte internal buffer; derived types own their hash stateXDRShortHasher owns a SipHash24 state initialized from the global keygVerifySigCache) is a process-wide singleton RandomEvictionCache<Hash, bool>gKey) is a process-wide singleton byte arrayCurve25519Secret / Curve25519Public are value types (XDR opaque_array<32> wrappers)SignerKey is an XDR union owned by its creator; SignerKeyUtils functions are pure factories