RecoveryKeyRotation

Recovery key rotation, format version 1 (docs/recovery-key-lifecycle.md). Rotation statement:

u32 length | userId (UTF-8)
u32 length | authorizer userId (UTF-8) | u32 length | authorizer deviceId (UTF-8)
current recovery public key (32)
new recovery public key (32)
expected recovery key epoch: i64 (>= 1)
timestamp: i64, epoch milliseconds
nonce (16)

Each construction prefixes u32 length | domain (UTF-8):

  • authorization, Ed25519 by the current recovery key: KSecureMessage-RecoveryKeyRotation-v1;

  • proof of possession, Ed25519 by the new recovery key: KSecureMessage-RecoveryKeyRotation-NewKeyPoP-v1;

  • RecoveryKeyRotationId, SHA-256: KSecureMessage-RecoveryKeyRotationId-v1.

Integers are big-endian. No domain is shared with server request authentication, device recovery, routine rotation or last-device recovery.

Properties

Link copied to clipboard
const val PUBLIC_KEY_SIZE: Int

Size of a recovery public key (Ed25519).

Link copied to clipboard
const val SIGNATURE_SIZE: Int

Size of a signature (Ed25519).

Link copied to clipboard

Accepted clock difference in each direction: now - VALIDITY_WINDOW <= timestamp <= now + VALIDITY_WINDOW. The same as for server requests.

Functions

Link copied to clipboard

The bytes the current recovery key signs.

Link copied to clipboard
fun authorize(currentKey: LastDeviceRecoveryKey, newKey: LastDeviceRecoveryKey, authorizer: DeviceAddress, expectedEpoch: Long, timestamp: Instant, nonce: RequestNonce = RequestNonce.random()): RecoveryKeyRotationAuthorization

The rotation of authorizer's user from currentKey (registered at expectedEpoch) to newKey, signed by both. timestamp is truncated to milliseconds. Throws IllegalArgumentException if both keys are the same.

Link copied to clipboard

The bytes the new recovery key signs.

Link copied to clipboard
Link copied to clipboard

true if authorization's current key signature verifies with currentPublicKey. The server passes the registered recovery key (or, for an exact retry, the statement's). Does not check the proof of possession.

Link copied to clipboard

true if the proof of possession verifies with the statement's new key.