Cryptography¶
The XE network uses a small set of well-established cryptographic primitives. All implementations -- Go node, CLI client, web wallet -- must produce identical outputs for the same inputs.
Key generation¶
Algorithm: Ed25519
Two modes of key generation:
| Function | Description |
|---|---|
GenerateKeyPair() |
Generate a random ed25519 keypair using crypto/rand |
KeyPairFromSeed(seed) |
Deterministic derivation from a 32-byte seed. Panics on invalid seed length. |
TryKeyPairFromSeed(seed) |
Like KeyPairFromSeed but returns an error instead of panicking for invalid seed length. Use for untrusted input. |
KeyPairFromSeed always produces the same keypair for a given seed. This is how the standalone CLI and web wallet derive keys -- the user stores only the seed.
Account addresses¶
An account address is the hex-encoded ed25519 public key -- 64 hexadecimal characters (32 bytes).
There is no checksum, prefix, or other encoding. The raw public key bytes in hex are the address.
Hashing¶
Two hash functions are used for different purposes:
| Algorithm | Use | Digest size |
|---|---|---|
| SHA-256 | Block content hashing | 32 bytes |
| Blake2b | Proof of work | 8 bytes (truncated) |
Block hashing¶
The block hash is SHA-256(canonical_bytes) where canonical_bytes is the output of MarshalBlockCanonical. The hash is hex-encoded for storage and display.
Important
The canonical encoding excludes the PoW nonce. The hash covers only the content that the account holder signs. See Binary Encoding for the exact byte layout.
Signing¶
Block signing¶
Ed25519 signatures over the SHA-256 hash of canonical block bytes.
SignBlock computes the hash and signs in one step. VerifyBlock recomputes the hash from the block fields and verifies the signature against the account's public key (the account address, hex-decoded).
Vote signing¶
Representatives sign votes over the canonical vote binary encoding:
payload = EncodeVote(vote) // without the signature fields
signature = ed25519.Sign(repPrivateKey, payload)
See Binary Encoding for the vote wire format.
Attestation signing¶
Timekeepers sign lease attestations:
Where || denotes concatenation and timestamp is the attestation timestamp as a string.
Chat signing¶
P2P chat messages carry ed25519 detached signatures over the message envelope (serialized message content). This proves the sender's identity without requiring the recipient to trust the relay.
Directory signing¶
Account directory registrations are signed:
Where account is the hex address and timestamp is a string representation.
State chain signing¶
DAO state chain blocks are signed over the SHA-256 hash of the serialized block operations:
Multiple DAO members sign the same hash to reach the signing threshold.
Web wallet implementation¶
The web wallet uses JavaScript equivalents that must produce byte-identical results:
| Go | JavaScript | Purpose |
|---|---|---|
crypto/ed25519 |
tweetnacl.js |
Key generation, signing, verification |
crypto/sha256 |
Web Crypto API (subtle.digest) |
Block hashing |
golang.org/x/crypto/blake2b |
blakejs |
Proof of work |
Cross-implementation compatibility
The canonical encoding must match byte-for-byte between Go and JavaScript. A single byte difference in the canonical form produces a completely different hash and an invalid signature. Both implementations use VERSION_BYTE = 0x02, identical type bytes, and identical field ordering.
Summary¶
┌─────────────────────────────────────────────┐
│ Cryptographic Flow │
├─────────────────────────────────────────────┤
│ │
│ seed (32 bytes) │
│ │ │
│ ▼ │
│ KeyPairFromSeed(seed) │
│ ├── publicKey (32 bytes) = address │
│ └── privateKey (64 bytes) │
│ │
│ Block signing: │
│ canonical = MarshalBlockCanonical(block) │
│ hash = SHA-256(canonical) │
│ sig = ed25519.Sign(privateKey, hash) │
│ │
│ Block verification: │
│ hash = SHA-256(MarshalBlockCanonical(b)) │
│ ok = ed25519.Verify(pubKey, hash, sig) │
│ │
│ Proof of work: │
│ result = Blake2b_8(nonce_LE || hash) │
│ valid = result >= difficulty │
│ │
└─────────────────────────────────────────────┘
See also¶
- Binary Encoding -- canonical byte layout for hashing
- Proof of Work -- Blake2b PoW algorithm
- Wallet Security -- AES-GCM seed encryption in the browser
- Accounts and Keys -- account model and key concepts