Cryptographic Primitives
BN254 Curve
Lateo uses the BN254 (alt-bn128) elliptic curve — the same curve used by Ethereum’s EIP-196/EIP-197 precompiles. Stellar Protocol 25 provides native host functions for BN254 operations.
| Parameter | Value |
|---|---|
| Curve | BN254 (alt-bn128) |
| Base field (Fp) | 21888242871839275222246405745257275088696311157297823662689037894645226208583 |
| Scalar field (Fr) | 21888242871839275222246405745257275088548364400416034343698204186575808495617 |
| Security level | ~100 bits |
| Embedding degree | 12 |
Poseidon2
Poseidon2 is a ZK-friendly hash function optimized for arithmetic circuits. It operates natively over the BN254 scalar field.
Lateo uses Poseidon2 with domain separators to prevent cross-domain attacks:
| Domain | Separator | Construction |
|---|---|---|
| Commitment | 0x01 | Poseidon2(amount, pubKey, blinding, 0x01) |
| Nullifier | 0x02 | Poseidon2(commitment, pathIndices, privKey, 0x02) |
| Public key derivation | 0x03 | Poseidon2(privKey, 0x03) |
| Signature | 0x04 | Poseidon2(commitment, privKey, 0x04) |
| Merkle tree internal nodes | N/A | Poseidon2(left, right) |
The domain separator is appended as an additional input to the hash. This ensures that a valid commitment hash cannot be reused as a nullifier or vice versa.
Groth16 Proving System
Groth16 provides succinct non-interactive zero-knowledge proofs with:
| Property | Value |
|---|---|
| Proof size | 256 bytes (constant) |
| Verification time | ~3ms (BN254 pairing) |
| Prover time | 8-15 seconds (WASM, single core) |
| Trusted setup | Required (circuit-specific) |
| Soundness | Computational (discrete log assumption) |
| Zero-knowledge | Perfect (statistical) |
Proof structure
A Groth16 proof consists of three elliptic curve points:
A ∈ G1 (64 bytes, Y-coordinate negated for verification)
B ∈ G2 (128 bytes, two Fp2 elements)
C ∈ G1 (64 bytes)Verification equation
e(A, B) = e(α, β) · e(Σ aᵢ·ICᵢ, γ) · e(C, δ)Where α, β, γ, δ are from the trusted setup and ICᵢ are the verification key’s IC points. This is computed on-chain using bn254_pairing_check.
Key Derivation
Agent BN254 private keys are derived deterministically:
privKey = SHA256(agentId || serverEncryptionKey) mod BN254_FR
pubKey = Poseidon2(privKey, 0x03)This ensures keys are reproducible from the agent ID without storing the raw private key.
Note Encryption
Output notes are encrypted with X25519 (Curve25519 Diffie-Hellman) so only the intended recipient can decrypt them:
encryptedOutput = X25519_Encrypt(recipientEncPubKey, noteData)The encrypted outputs are stored on-chain in the NewCommitmentEvent — allowing future client-side note scanning.