Development

How are XRPL addresses generated?

Last updated:

XRPL address generation is a multi-step cryptographic process that transforms a public key into a human-readable, checksummed identifier. Understanding this process is essential for developers building wallets, tools, or integrations with the XRP Ledger.

The Address Generation Pipeline

The complete process involves several cryptographic operations:

1. Generate private key (256-bit random number) 2. Derive public key from private key (algorithm-specific) 3. Hash the public key (SHA-256, then RIPEMD-160) 4. Add account type prefix 5. Compute checksum 6. Encode in Base58

Step-by-Step Process

Step 1: Private Key Generation

```javascript // Generate cryptographically secure random 256-bit number const crypto = require('crypto'); const privateKeyBytes = crypto.randomBytes(32); const privateKeyHex = privateKeyBytes.toString('hex'); ```

Step 2: Public Key Derivation

This step differs by algorithm:

```javascript // Ed25519 const ed25519 = require('ed25519'); const publicKeyEd = ed25519.publicKey(privateKeyBytes); // Result: 32-byte public key, prefixed with 'ED' when hex-encoded

// secp256k1 const secp256k1 = require('secp256k1'); const publicKeySecp = secp256k1.publicKeyCreate(privateKeyBytes, true); // compressed // Result: 33-byte compressed public key (02/03 prefix + 32 bytes) ```

Step 3: Hash the Public Key

This is where XRPL's specific hashing scheme comes in:

```javascript const crypto = require('crypto');

function accountPublicKeyToAddress(publicKey) { // Step 3a: SHA-256 hash const sha256 = crypto.createHash('sha256') .update(publicKey) .digest(); // Step 3b: RIPEMD-160 hash const ripemd160 = crypto.createHash('ripemd160') .update(sha256) .digest(); return ripemd160; // 20-byte hash } ```

Step 4: Add Type Prefix

```javascript // Account addresses use type ID 0 const ACCOUNT_ID = 0; const payload = Buffer.concat([ Buffer.from([ACCOUNT_ID]), ripemd160Hash ]); // 21 bytes total ```

Step 5: Compute Checksum

XRPL uses a double SHA-256 checksum:

```javascript function computeChecksum(payload) { const hash1 = crypto.createHash('sha256').update(payload).digest(); const hash2 = crypto.createHash('sha256').update(hash1).digest(); return hash2.slice(0, 4); // First 4 bytes }

const checksum = computeChecksum(payload); const addressBytes = Buffer.concat([payload, checksum]); // 25 bytes ```

Step 6: Base58 Encoding

XRPL uses Bitcoin's Base58Check alphabet (no 0, O, I, l to avoid confusion):

```javascript const BASE58_ALPHABET = 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz';

function encodeBase58(buffer) { let num = BigInt('0x' + buffer.toString('hex')); let encoded = ''; while (num > 0n) { const remainder = num % 58n; num = num / 58n; encoded = BASE58_ALPHABET[Number(remainder)] + encoded; } // Add leading 'r' characters for leading zero bytes for (let i = 0; i < buffer.length && buffer[i] === 0; i++) { encoded = 'r' + encoded; } return encoded; }

const address = encodeBase58(addressBytes); // Result: rN7n7otQDd6FczFgLdlqtyMVrn3HMfgnZh (for example) ```

Complete Implementation

```javascript const xrpl = require('xrpl'); const crypto = require('crypto');

function generateAddress(algorithm = 'ed25519') { // Step 1: Generate private key const privateKey = crypto.randomBytes(32); // Step 2: Derive public key (using xrpl library for simplicity) const wallet = xrpl.Wallet.fromSeed( xrpl.encodeSeed(privateKey, algorithm), { algorithm } ); // Steps 3-6 are handled internally by the library return { privateKey: wallet.privateKey, publicKey: wallet.publicKey, address: wallet.address }; }

const account = generateAddress('ed25519'); console.log('Address:', account.address); console.log('Public Key:', account.publicKey); ```

Why This Design?

The address generation scheme incorporates multiple design principles:

1. Double Hashing

Using both SHA-256 and RIPEMD-160 provides: - Additional security layer - Smaller address size (160 bits vs 256 bits) - Potential quantum resistance (attacking requires inverting two hash functions)

2. Checksum

The 4-byte checksum catches: - Transcription errors - Transmission errors - Invalid addresses (only 1 in 4 billion random strings is valid)

3. Base58 Encoding

Advantages over hex or Base64: - Human-readable (no similar-looking characters) - Compact (shorter than hex) - Double-click selectable (no special characters) - Case-sensitive (more entropy per character)

4. 'r' Prefix

All XRPL addresses start with 'r', making them: - Instantly recognizable as XRPL addresses - Distinct from Bitcoin addresses (start with 1, 3, or bc1) - Easy to validate programmatically

Address Properties

- Length: Typically 25-35 characters - Character set: Base58 (rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz) - Always starts with: 'r' - Case-sensitive: Yes - Collision resistance: 2^160 possible addresses

Comparison to Bitcoin

XRPL's address generation closely mirrors Bitcoin's P2PKH addresses:

``` Bitcoin: [Type][RIPEMD160(SHA256(pubkey))][Checksum] -> Base58 XRPL: [Type][RIPEMD160(SHA256(pubkey))][Checksum] -> Base58 ```

The main difference: Bitcoin addresses start with '1' (type 0x00), while XRPL uses 'r' for accounts.

Address Validation

```javascript const xrpl = require('xrpl');

function isValidAddress(address) { try { // Decode and verify checksum const decoded = xrpl.decodeAddress(address); return decoded.length === 20; // 160 bits } catch (e) { return false; } }

console.log(isValidAddress('rN7n7otQDd6FczFgLdlqtyMVrn3HMfgnZh')); // true console.log(isValidAddress('invalidAddress')); // false ```

Security Considerations

1. Private Key Protection: The private key must be kept secret; anyone with it controls the account 2. Deterministic Derivation: Same private key always produces same address 3. One-Way Function: Cannot derive private key from address (computationally infeasible) 4. Collision Resistance: Finding two keys with the same address requires ~2^80 operations

Common Pitfalls

1. Wrong Checksum: Manually modified addresses will fail validation 2. Case Sensitivity: 'rn7n7...' ≠ 'rN7n7...' 3. X-Address Confusion: X-addresses and classic addresses are different formats for the same account 4. Algorithm Mismatch: Cannot derive Ed25519 address from secp256k1 key

Understanding XRPL's address generation process is crucial for secure wallet implementation, address validation, and debugging integration issues. The multi-layered cryptographic approach ensures addresses are secure, error-resistant, and compatible with established blockchain standards.

Was this helpful?

Related Questions

Go Deeper

Expand your knowledge with these related lessons

Address Generation and Verification

50 minadvanced

XRPL Accounts - Theory and Practice

50 minintermediate

Understanding XRPLs Unique Model

45 minintermediate

Have more questions?

Browse our complete FAQ or contact support.