Hidden Services Over Mix - reference
The reference implementation of the hidden services protocol over mix in Rust. The crate contains implementation of the following:
Ed25519-KeyBlind
Ed25519 signature with key blinding.
This crate wrap ed25519-dalek and adds Tor-specific Ed25519 key blinding.
This crate is based on Arti Tor client and compatible with its implementation, see tests.
Time
Hidden-service time is represented by HSEpoch.
An epoch is a fixed-length interval counted from the Unix epoch. It is used when deriving epoch-specific blinded identity keys, discovery keys, and certificates.
Hidden services identifiers (HSId)
HsId is the public hidden-service identity. It is the validated Ed25519 public key behind a .mix address.
The module provides:
HsId: compact public service identity bytes.HsIdKey: validated Ed25519 public identity key.HsIdKeypair: expanded identity keypair for signing.HsBlindIdKeyandHsBlindIdKeypair: epoch-specific blinded identity keys.DiscoveryKey: descriptor lookup key derived from the blinded key, public entropy, and replica number.
Key Certificates (KeyCert)
KeyCert binds a certified public key to a signing key for a specific HSEpoch.
Certificates currently support these roles:
DescriptorSigningKey: a blinded hidden-service identity key certifies the short-term descriptor signing key.IntroAuthenticationKey: an introduction authentication key certifies the descriptor signing key for one intro point.ServiceEncryptionKey: the descriptor signing key certifies an X25519 service encryption key for one intro point (TODO: need to cross certify this key).
Descriptor
Hidden-service descriptors are split into:
- an outer signed layer, visible to discovery nodes.
- an encrypted inner layer, visible only to clients that know the service identity.
The outer layer contains the descriptor epoch, descriptor signing certificate, revision counter, encrypted inner layer, and descriptor signature.
Validation checks the descriptor-signing certificate, verifies the outer signature, and confirms the descriptor's blinded key maps to the expected discovery key.
The inner layer contains introduction points. Each introduction point includes public mix routing information, an introduction authentication certificate, and a service encryption certificate. After decryption, inner validation checks that those certificates match the descriptor signing key and epoch.
Inner-layer encryption uses descriptor-specific key material derived from the hidden-service identity, blinded key, random salt, and revision counter. The ciphertext is authenticated with HMAC before decryption.