pps-php

Key Management

PPS uses Ed25519 keys.

The server stores only public keys.

The client stores private key material.


Key Material

seed: 32 bytes
public key: 32 bytes
secret key: 64 bytes

Master Seed

A master seed can derive normal and duress seeds.

normal_seed = HKDF(master_seed, "PulseProofSentinel/seed/v1|normal")
duress_seed = HKDF(master_seed, "PulseProofSentinel/seed/v1|duress")

For stronger duress isolation, use independent seeds.


Key Identifier

Each device key has a key identifier:

kid = 16 random bytes

Use pairwise kid values per Relying Party to reduce correlation.


Key Rotation

Each single-device Pulse rotates the signing key.

K_t signs Pulse containing pk_t and next_pk_{t+1}

After success:

server current_pk = next_pk
client current_seed = next_seed

The old private key should be deleted.


Rotation Certificates

Rotation certificates allow offline catch-up.

cert_t = Sign(K_t, pk_t -> pk_{t+1})

The client stores pending certificates until the server acknowledges them.


Secure Storage

Recommended storage:

Secure Enclave
StrongBox
TPM
hardware security key
encrypted key store

Avoid storing seeds in plain text.


Recovery

Recovery options:

secondary registered device
encrypted cloud backup
recovery codes
social recovery
threshold recovery
admin-assisted recovery

Recovery flows must resist social engineering.