The Lifecycle of a Cryptographic Key
← Back to Cryptography I: Blockchain Security and Cryptographic Foundations
Introduction
Let's follow the lifecycle of a cryptographic key in rippled, from its creation as random noise to its role as the foundation of an account's identity. This journey touches every aspect of rippled's cryptographic system and shows how the pieces fit together.
Understanding this lifecycle is crucial because keys are the foundation of everything in XRPL. Every account, every transaction, every validator message—all depend on the proper generation, handling, and use of cryptographic keys.
The Journey Begins: Birth Through Randomness
Everything begins with randomness. Not the pseudo-randomness of Math.random() or std::rand(), but true cryptographic randomness—numbers that are fundamentally unpredictable.
Why Randomness Matters
If an attacker can predict your random numbers, they can predict your keys. If they can predict your keys, they own your account. The stakes couldn't be higher.
// ❌ WRONG - Predictable and insecure
void generateWeakKey() {
std::srand(std::time(nullptr)); // Predictable seed!
std::uint8_t buf[32];
for (auto& byte : buf)
byte = std::rand() % 256; // NOT cryptographically secure
}
// ✅ CORRECT - Cryptographically secure
SecretKey generateStrongKey() {
std::uint8_t buf[32];
beast::rngfill(buf, sizeof(buf), crypto_prng()); // CSPRNG
SecretKey sk{Slice{buf, sizeof(buf)}};
secure_erase(buf, sizeof(buf)); // Clean up
return sk;
}The Birth of a Secret Key
In rippled, randomness comes from the crypto_prng() function, which wraps OpenSSL's RAND_bytes:
What happens here:
Allocate buffer: A 32-byte buffer is created on the stack
Fill with randomness:
crypto_prng()fills it with cryptographically secure random bytes from OpenSSLCreate SecretKey: The buffer is wrapped in a
SecretKeyobjectSecure cleanup: The temporary buffer is securely erased to prevent key material from lingering in memory
Where Randomness Comes From
When you call crypto_prng(), OpenSSL pulls entropy from multiple sources:
This multi-source approach ensures that even if one entropy source is weak, others provide backup security.
Growth: From Secret to Public
With a secret key in hand, we need to derive its public key—the identity we can share with the world. This derivation is one of the beautiful ideas in modern cryptography: a mathematical function that's easy to compute in one direction but effectively impossible to reverse.
The One-Way Function
This asymmetry is what makes public-key cryptography possible.
Two Algorithms, Two Approaches
XRPL supports two cryptographic algorithms, each with its own derivation process:
secp256k1: Elliptic Curve Point Multiplication
How it works:
Elliptic curve has a special "generator" point G
Public key = Secret key × G (point multiplication on the curve)
Result is a point with X and Y coordinates
Compressed format stores X coordinate + one bit for Y (33 bytes total)
Prefix byte: 0x02 or 0x03 (indicates Y parity)
X coordinate: 32 bytes
Why it's secure:
Computing
Public = Secret × Gis fastComputing
SecretfromPublicrequires solving the discrete logarithm problemNo known efficient algorithm exists for this problem
ed25519: Curve25519 Operations
How it works:
Uses Ed25519 curve operations (optimized variant of Curve25519)
Derives public key through curve arithmetic
Adds 0xED prefix byte to identify key type
Total 33 bytes (1 prefix + 32 public key)
Why it's secure:
Based on different curve with different security proofs
Specifically designed for signing (not encryption)
More resistant to implementation errors
The Beauty of One-Way Functions
The public key can be:
Posted on websites
Included in transactions
Sent to strangers
Stored in public databases
No matter who has it or what they do with it, they can't derive your secret key. Your private identity remains private.
Alternative Path: Deterministic Generation
Sometimes we don't want pure randomness. Sometimes we want to be able to recreate the exact same key pair from a remembered or stored value. This is where seed-based deterministic key generation comes in.
Why Deterministic Keys?
Problem with pure randomness:
Solution with seeds:
How Seeds Work
A seed is a small piece of data—typically 16 bytes—that serves as the "master secret" for an entire family of keys:
For ed25519: Simple and Direct
Simple, deterministic, and secure. Same seed always produces same key.
For secp256k1: Handling Edge Cases
Why the loop? Not all 32-byte values are valid secret keys for secp256k1. The value must be less than the curve's "order" (a large prime number). If the hash result is too large, increment a counter and try again.
The odds of needing more than one attempt are vanishingly small (roughly 1 in 2^128), but the code handles it correctly.
The Generator Pattern
The Generator class enables creating multiple independent keys from one seed:
Each ordinal produces a cryptographically independent key pair. This enables powerful features like:
Hierarchical wallets: One seed, many accounts
Key rotation: Generate new keys without remembering multiple seeds
Backup simplicity: One seed backs up everything
From Key to Identity: Account IDs
A public key isn't an address. To get the human-readable XRPL address (starting with 'r'), we need one more transformation:
The RIPESHA Double Hash
Why two hash functions?
Compactness: 20 bytes instead of 33 bytes
Defense in depth: If SHA-256 is broken, RIPEMD-160 provides protection; if RIPEMD-160 is broken, SHA-256 does
Compatibility: Same scheme used by other blockchain systems
Why hash at all?
Shorter addresses are easier to use
Provides a level of indirection (can't derive public key from address)
Quantum-resistant: even if quantum computers break elliptic curve crypto, they can't derive the public key from the address alone
The Complete Lifecycle
Let's trace a key from birth to address:
Each step is irreversible:
Can't derive secret from public
Can't derive public from account ID
Can't derive account ID from address (but can decode)
Lifecycle Management: RAII and Secure Cleanup
The SecretKey class demonstrates proper lifecycle management:
RAII (Resource Acquisition Is Initialization):
Constructor acquires resource (the secret key)
Destructor releases resource (securely erases key)
No manual cleanup needed
Automatic cleanup even if exceptions occur
Usage pattern:
Even if sign() throws an exception, the destructor still runs and the key is erased. This is defensive programming—making it impossible to forget cleanup.
Key Type Detection
How does rippled know which algorithm a key uses? The first byte:
This automatic detection means higher-level code doesn't need to track key types—the keys themselves carry the information.
Summary: The Key Lifecycle
Key Takeaways
Randomness is critical: Weak randomness = weak keys = stolen funds
One-way functions enable public-key crypto: Easy to derive public from secret, impossible to reverse
Two algorithms, same security guarantees: secp256k1 for compatibility, ed25519 for performance
Deterministic generation enables backups: One seed can recover many keys
Secure cleanup prevents leaks: Keys must be erased from memory when no longer needed
RAII makes security automatic: Proper C++ patterns prevent human error
In the next chapter, we'll see how these keys are used to create and verify signatures—the mathematical proof of authorization that makes XRPL secure.
Last updated

