Devices
To allow each account to send data and communicate with other accounts without being tied to a specific device, every account generates a central key that all of its devices can access. This central key is derived from a randomly generated initial SEED, which is a 32-byte value.
salt: "EDH-Derived-NaCl-X25519"salt: "EDH-Derived-NaCl-Secret"Once the SEED has been generated, the following keys can be derived from it:
X25519 Key Pair
: SCRYPT(SEED, "EDH-Derived-NaCl-X25519")
Symmetric Encryption Key
: SCRYPT(SEED, "EDH-Derived-NaCl-Secret")
The key derivation function (KDF) uses the following parameters:
- Algorithm:
SCRYPT - SCRYPT parameter N (Cost):
16,384 - SCRYPT parameter r (Block Size):
8 - SCRYPT parameter p (Parallelization):
1
After all keys have been derived, the account can store its public keys in the Registry Contract so that other accounts can use them to encrypt data when communicating between accounts.
Device Keys
Each device generates its own key pair, separate from the account's central keys:
- Ethereum Wallet: A keypair used for transaction signing and on-chain identity.
- NaCl Keypair: An X25519 keypair used for encrypting data between devices.
A device's private keys are stored only on the device itself. Ever does not store any user private keys.
Managing Devices on an Account
Adding or removing a device from an account involves the following key processes:
- Adding the device's address and public key to the EDHAccount. This step grants or revokes the device's permission to modify account data in the EDHAccount Contract.
- Sharing or revoking the account's central key. For a new device to learn the SEED and derive the account's central keys, the SEED must be transmitted to that device. Developers are free to choose their own method for transmitting the SEED without using SeedVault, but we provide SeedVault as a reference implementation that can be used out of the box.
When revoking a device, a new SEED and new central keys are generated for the account. The new SEED is then shared with all remaining devices except the one being removed.
SeedVault Contract
The method for transmitting the account's central SEED to other devices is outside the scope of account registration and is left to the developer's discretion. Options include QR codes or a centralized service channel. However, Ever provides the SeedVault Contract as one channel for sharing and managing central keys via the blockchain. The process is as follows:
- For each device linked to the account, encrypt the SEED using the NaCl.box function with the following keys:
- The device's X25519 public key, and
- The X25519 private key derived from the new SEED.
- If an old SEED exists, encrypt it using the symmetric key derived from the new SEED.
- Store both pieces of encrypted data on the blockchain in the SeedVault Contract.
Encrypting Data Between Accounts
When a user has an account and wants to send data between two accounts, the sender can encrypt the data using the recipient account's X25519 public key and the sender account's private key. The NaCl Sealed Box function can be used for encryption and decryption, with the following signature:
nacl.box(message, nonce, devicePublicKey, accountNewSecretKey)
Interface: SeedVault
contract SeedVault {
event EDHVaultKeyUpdated(address indexed _account, address _updater, bytes32 publicKey, address [] devices);
function addAccountSeed(
bytes32 encryptionPublicKey,
bytes32 previousEncryptionPublicKey,
bytes memory previousSeed,
address[] memory devices,
bytes[] memory seeds
) external;
function addDeviceAccountSeed(
address accountAddress,
bytes32 encryptionPublicKey,
bytes32 previousEncryptionPublicKey,
bytes memory previousSeed,
address[] memory devices,
bytes[] memory seeds
) external;
function getDeviceVaultSeeds(address deviceAddress)
external view returns(DeviceSeedView[] memory);
function getVaultSeeds(address accountAddress, address deviceAddress)
external view returns (DeviceSeedView[] memory seeds);
function getVaultSeedsAt(address accountAddress, address deviceAddress, uint offset, uint count)
external view returns (DeviceSeedView[] memory seeds);
}
Event EDHVaultKeyUpdated : An event emitted whenever the public encryption key is updated.
addAccountSeed / addDeviceAccountSeed : Transaction functions for updating the seed or adding a seed for a new device.
getDeviceVaultSeeds / getVaultSeeds / getVaultSeedsAt : View functions for reading a device's seed within an account.
Device Recovery
Scenario 1: A Single Device Is Lost (Other Active Devices Remain)
- Use a remaining active device to call
revokeDeviceto revoke the lost device. - The system automatically generates a new SEED (SEED rotation).
- New central keys are derived from the new SEED.
- The SeedVault is updated with the new SEED for all remaining devices.
- Call
updateEncryptionPublicKeyon the EDHAccount to store the new public key. - (Optional) Register a new device to replace the lost one.
Scenario 2: All Devices Are Lost (Backup SEED Required)
- Set up a new device by generating a new Ethereum keypair and NaCl keypair.
- Import the backup SEED that was previously stored (32 bytes).
- Derive the central keys from the SEED to prove ownership of the account.
- Use the Emergency Guardian or social recovery mechanism to register the new device.
If the backup SEED is lost and all active devices are unavailable, the account cannot be recovered. Users should always store their SEED backup in a secure location.
Key Rotation
Key rotation occurs when a device is revoked, ensuring that the revoked device cannot read any new data.
Process
- Generate a new SEED: Randomly generate a new 32-byte SEED.
- Derive new keys: Use SCRYPT derivation to create a new X25519 keypair and symmetric key.
- Update the EDHAccount: Call
updateEncryptionPublicKeyto store the new public key. - Update the SeedVault: Encrypt the new SEED for each remaining active device, and encrypt the old SEED with the symmetric key derived from the new SEED.
- Update Account Storage: Re-encrypt the EVFS root key with the new key.
Accessing Old Files
After key rotation, files encrypted with previous keys remain accessible because:
encryptionPublicKeys()returns all historical public keys.- The SeedVault stores old SEEDs encrypted with the new SEED, allowing active devices to decrypt them retroactively.
- Files created after rotation are encrypted with the new key, so revoked devices cannot read them.
Security Best Practices
SEED Storage
- Never store the SEED as plaintext on a device. Use an encrypted vault (e.g., Android Keystore, iOS Keychain).
- Back up the SEED offline, for example by writing it on paper and storing it in a safe.
- The SEED is not a BIP-39 mnemonic: The EDH SEED is a random 32-byte value, not a cryptocurrency wallet seed phrase.
Device Security
- Each device has its own Ethereum keypair -- private keys are never shared between devices.
- A revoked device immediately loses access to the account (on the blockchain).
- Device private keys are never exported from the device.
Risk and Mitigation Table
| Scenario | Risk | Mitigation |
|---|---|---|
| Phone stolen | Attacker gains device access | Revoke device immediately, triggering SEED rotation |
| Server compromised | Data on the server is leaked | E2E encryption -- the server holds no decryption keys |
| SEED leaked | Attacker can read data | Generate a new SEED and revoke the compromised device |
| Device key leaked | Attacker uses a spoofed device | Revoke the device -- attacker loses access |
| Genomic data compromised | Bio-anchor is forged | Revoke the bio-anchor and re-register with a new salt |
See Also
- Account -- EDHAccount and account management
- File Storage -- EVFS and Cryptree encryption
- BIA Architecture -- Biological Identity Attestation
- BioAnchorRegistry -- Smart contract for genomic identity