Ed25519 Keypair Generation Guide
For External Integration with Arkipel Communities

Overview
This document specifies how to generate Ed25519 keypairs compatible with an arkipel system, including:
- 32-byte seeds (64-character hex strings)
- ZBase32-encoded public keys
- 12-word BIP-39 mnemonics (from first 16 bytes of seed)
- Hex-encoded private keys
Key Requirements
| Parameter | Format | Notes |
|---|---|---|
| Seed | 64-character hex string | First 32 chars (16 bytes) used for mnemonic |
| Public Key | ZBase32-encoded string | Derived from full 32-byte seed |
| Private Key | 64-character hex string | Full 32-byte seed |
| Mnemonic Phrase | 12-word BIP-39 phrase | From first 16 bytes of seed |
Implementation Specifications
1. Seed Handling
- Input: Optional 32-character hex string (16 bytes)
-
Processing:
- If no seed provided, generate random 16-byte seed (32 hex chars)
- Pad to 32 bytes (64 hex chars) with zeros for Ed25519
- Use first 16 bytes (32 hex chars) for mnemonic generation
2. Keypair Generation
Generate Ed25519 keypairs compatible with our system.
2.1. Key Concepts
- Uses 32-byte seeds (64-character hex strings)
- Produces ZBase32-encoded public keys
- Generates 12-word BIP-39 mnemonics from first 16 bytes of seed
- Hex-encoded private keys
2.2. Arkipel Reference Implementation Test Vectors for keypair generation
Seed (hex)
a1b2c3d4e5f678901234567890abcdef
Public Key
yy5g76ch3mm7f4qcw3w3ag8h1x7k53631hjhn8ugic1buunid331
Private Key
a1b2c3d4e5f678901234567890abcdef00000000000000000000000000000000
Mnemonic Phrase
payment noodle vivid slogan guide elite emotion member joy luxury vibrant tattoo
2.3. Implementations Examples
3. Message Signing
Sign messages using the private key generated by your keypair.
3.1. Key Concepts
- Uses Ed25519’s
signfunction - Produces a 64-byte signature (128 hex characters)
- Requires the private key in binary format
3.2. Arkipel Reference Implementation Test Vectors for signing
3.2.1 Test 1
Private Key (hex)
a1b2c3d4e5f678901234567890abcdef00000000000000000000000000000000
Message
"Hello, world!"
Signature (hex)
0c52f48fecf760bd13ce590ca413a7d178a743331fb42ef7661d52b7232479250959839ae1ac75075cf77fb55cce742ac7666cf25af0c044b6e9fb674211eb05
3.2.2 Test 2
Private Key (hex)
a1b2c3d4e5f678901234567890abcdef00000000000000000000000000000000
Message
"Test"
Signature (hex)
84bc691a6de351d018ae2a0a25c6007c2a0c07237503710457734159647a6c12628a13e5090af9a89c92ce9aca4badc60b581c07fa1345a9c7d558f0d336bd07
3.3. Implementations Examples
4. Signature Verification
Verify signatures using the public key.
4.1 Key Concepts
- Uses Ed25519’s
verifyfunction - Requires public key in binary format (decoded from ZBase32)
- Returns boolean (true/false) indicating validity
4.2. Arkipel Reference Implementation Test Vectors for signature verification
4.2.1 Test 1
Public Key
yy5g76ch3mm7f4qcw3w3ag8h1x7k53631hjhn8ugic1buunid331
Message
"Hello, world!"
Signature (hex)
0c52f48fecf760bd13ce590ca413a7d178a743331fb42ef7661d52b7232479250959839ae1ac75075cf77fb55cce742ac7666cf25af0c044b6e9fb674211eb05
Expected Result
true
4.2.2 Test 2
Public Key
yy5g76ch3mm7f4qcw3w3ag8h1x7k53631hjhn8ugic1buunid331
Message
"Hello, world!"
Signature (hex)
1111111111111111111111111111111111111111111111111111111111111111
Expected Result
false
4.2.3 Test 3
Public Key
yy5g76ch3mm7f4qcw3w3ag8h1x7k53631hjhn8ugic1buunid331
Message
"Wrong message"
Signature (hex)
0c52f48fecf760bd13ce590ca413a7d178a743331fb42ef7661d52b7232479250959839ae1ac75075cf77fb55cce742ac7666cf25af0c044b6e9fb674211eb05
Expected Result
false
4.3. Implementations Examples
5. Complete Workflow Example and Validation
5.1. Generate Keypair
TODO
5.2. Sign a Message
TODO
5.3 Verify the Signature
TODO
###
Appendix
Why was ZBase32 chosen over other encoding schemes like Base64 or Base58 for the public keys
ZBase32 was likely chosen over Base64 or Base58 for public keys in your system for several important reasons. Here’s a detailed comparison that explains why ZBase32 is often preferred for certain use cases, particularly for public keys in distributed systems:
1. Character Set Comparison
| Encoding | Character Set | Case-Sensitive | Human-Friendly | URL-Safe | Padding | Length Efficiency |
|---|---|---|---|---|---|---|
| Base64 | A-Z, a-z, 0-9, +, /, = | Yes | No | No* | Yes | High |
| Base58 | A-Z, a-z, 0-9 (excluding 0, O, I, l) | Yes | No | Yes | No | Medium |
| ZBase32 | y, b, n, d, r, f, g, 8, e, j, k, m, c, p, q, x, o, t, 1, u, w, i, s, z, a, 3, 4, 5, h, 7, 6, 9 | No | Yes | Yes | No | Medium |
*Base64 requires URL-safe variants that replace + and / with - and _
2. Key Advantages of ZBase32
2.1. Case Insensitivity
- ZBase32: All characters are lowercase (no case sensitivity issues)
- Base64/Base58: Case-sensitive, which can cause problems in:
- User input (typos, case mismatches)
- Database lookups
- URL parameters
- Visual display (hard to distinguish 0 vs O, 1 vs l)
2.2. Human-Friendly Design
- ZBase32:
- Excludes visually similar characters (0/O, 1/l/I)
- Uses only lowercase letters and a few digits
- Easier to read aloud and transcribe
- Base64:
- Includes +, /, and = which are problematic in URLs
- Includes both uppercase and lowercase letters
- Base58:
- Better than Base64 but still case-sensitive
- Excludes more confusing characters than ZBase32
2.3. URL and Filename Safety
- ZBase32: No special characters that need encoding in URLs
- Base64: Requires URL-safe variant or encoding
- Base58: URL-safe but includes both cases
2.4. Sorting and Comparison
- ZBase32: Case-insensitive sorting works naturally
- Base64/Base58: Requires case-sensitive comparison
2.5. Implementation Consistency
- ZBase32:
- No padding characters (unlike Base64’s =)
- Consistent length for given binary input
- Less prone to implementation errors
2.6. Error Detection
- ZBase32: Some implementations include checksums
- Base64: No built-in error detection
- Base58: Often used with checksums (like in Bitcoin)
2.7. Length Efficiency
For encoding 32-byte Ed25519 public keys:
- Base64: 44 characters (with padding)
- Base58: ~44 characters
- ZBase32: 52 characters, While ZBase32 is slightly longer, the tradeoff is worth it for the other benefits
3. Specific Use Case Benefits for Public Keys
3.1. Database and Indexing:
- Case-insensitive comparison is faster and simpler
- No need for case-sensitive indexes
- Example SQL query:
-- Works naturally with ZBase32
SELECT * FROM accounts WHERE public_key = 'xn...';
-- Requires exact case matching with Base64/Base58
SELECT * FROM accounts WHERE LOWER(public_key) = LOWER('Ab...');
3.2. User Experience:
- Easier to read and manually enter
- Less prone to transcription errors
- Example public key display:
ZBase32: yy5g76ch3mm7f4qcw3w3ag8h1x7k53631hjhn8ugic1buunid331
Base64: 3x6X7J4Q5nK7mZ9pL2vW8yT4uV6sR0qP1oN/+== (with = padding)
3.3. API and URL Usage:
-
Can be safely used in URLs without encoding:
https://api.example.com/accounts/yy5g76ch3mm7f4qcw3w3ag8h1x7k53631hjhn8ugic1buunid331 -
No need for URL encoding/decoding
3.4. Visual Display:
- No confusing characters (0 vs O, 1 vs l)
- Consistent appearance across fonts
3.5. Security:
- Reduces risk of phishing attacks using similar-looking characters
- Harder to create visually similar but different keys
4. When to Choose Each Encoding
| Use Case | Recommended Encoding | Reason |
|---|---|---|
| URL-safe tokens | ZBase32 or Base58 | No special characters |
| Public keys | ZBase32 | Human-friendly, case-insensitive |
| Cryptocurrency addresses | Base58 | Tradition, checksum support |
| Configuration files | Base64 | Space efficiency |
| Binary data storage | Base64 | Most space-efficient |
5. Real-World Examples
5.1. Systems using ZBase32:
- Signal Protocol (for key fingerprints)
- DNSSEC (for key fingerprints)
- Some blockchain systems
5.2. Systems using Base58:
- Bitcoin addresses
- IPFS CIDs
5.3. Systems using Base64:
- JSON Web Tokens (JWT)
- Data URLs
- Email attachments
6. Tradeoffs
| Factor | ZBase32 | Base64 | Base58 |
|---|---|---|---|
| Implementation complexity | Medium | Low | Medium |
| Storage efficiency | Medium | High | Medium |
| Human readability | High | Low | High |
| URL safety | High | Low* | High |
| Case sensitivity | None | Yes | Yes |
| Character confusion | Low | High | Medium |
| Padding requirements | None | Yes | None |
*Base64 requires URL-safe variant
7. Recommendation
For arkipel’s use case of public keys that need to be:
- Displayed to users
- Used in URLs
- Stored in databases with case-insensitive comparison
- Manually entered in some cases
ZBase32 is the optimal choice despite its slightly longer length. The benefits in usability, safety, and implementation simplicity outweigh the minor storage efficiency disadvantage.