XE uses standard cryptographic primitives with cross-implementation compatibility between Go and JavaScript (tweetnacl/blakejs).
Key Generation
Ed25519 via crypto/rand or deterministic from 32-byte seed.
Signing Contexts
- Block hashing —
SHA-256(networkID ‖ canonical bytes ‖ aux bytes). The aux tail binds the certificate hash and timekeeper attestations into the hash (empty for non-lease blocks). Genesis blocks are hashed with the network-ID prefix cleared — they are created before the network ID is known. - Block signing —
ed25519.Sign(privateKey, hash) - Vote signing — ed25519 over canonical vote encoding
- Attestation signing — ed25519 over
SHA-256(leaseHash || timestamp) - Chat signing — ed25519 detached signature over message envelope
- Directory signing —
ed25519.Sign(priv, SHA-256("xe/directory-registration/v1\x00" ‖ len‖networkID ‖ len‖account ‖ len‖nodePeer ‖ len‖timestamp)), where eachlenis an 8-byte big-endian length prefix framing the field that follows
Proof of Work
Anti-spam only, not consensus. Always computed client-side.
result = blake2b_8(nonce_LE || blockHash)
valid = result >= difficulty- Block DefaultDifficulty:
0xfffff80000000000(~2²¹ attempts, ~1s) - Chat DefaultPoWDifficulty:
0xffffc00000000000(~2¹⁸ attempts — chat spam pricing is tuned independently of block mining) - TestDifficulty:
0x0000000000000002(instant) - Nonce: little-endian; result compared as big-endian
- Both difficulties are advertised in
GET /node
Functions: ComputePoW, ComputePoWConcurrent, ComputePoWWithContext, ValidatePoW