import { type WebCryptoKey } from '../webcrypto'; import { type P256PublicJwk } from './primitives'; export declare const MEMBER_KEY_RECORD_VERSION = 1; /** * Whose keys a store holds. A device member's binding names its SDK device * id; a client member's has none, as in its bundle. */ export interface MemberKeyBinding { readonly tenantId: string; readonly deviceId?: string; } export interface MemberKeys { readonly binding: MemberKeyBinding; /** Signs chain entries and key packages. The private key is not extractable. */ readonly signing: { readonly publicJwk: P256PublicJwk; readonly privateKey: WebCryptoKey; }; /** Opens key packages. The private key is not extractable. `epoch` starts at 1. */ readonly kem: MemberKemKey; /** The KEM key of a rotation that has begun and not finished, at `kem.epoch + 1`. */ readonly nextKem?: MemberKemKey; } export interface MemberKemKey { readonly epoch: number; readonly publicJwk: P256PublicJwk; readonly privateKey: WebCryptoKey; } /** The custody port of one member's keys. Each store expects one writer. */ export interface MemberKeyStore { /** The keys bound to `binding`, or `undefined` when the store holds none for it. A malformed record throws. */ load(binding: MemberKeyBinding): Promise; /** The keys bound to `binding`. A store that holds none for it creates new ones, which replace any other binding's keys. */ loadOrCreate(binding: MemberKeyBinding): Promise; } /** * A new member's record for `binding`: a fresh signing key and a fresh KEM * key at epoch 1, as one canonical JSON text. The text holds both private * scalars; only the member's own custody stores it. */ export declare function generateMemberKeyRecord(binding: MemberKeyBinding): Promise; /** * The keys of a stored record, imported non-extractable, or `undefined` when * the text is not a canonical v1 record, or a private scalar does not match * its public point. Never throws for hostile input. */ export declare function openMemberKeyRecord(text: unknown): Promise; /** * Begin a KEM rotation: the record with a new KEM key at `kemEpoch + 1` * beside the current one. A record whose rotation has begun comes back * unchanged, so a resumed rotation keeps its key. A record that is not * canonical v1 text throws. */ export declare function beginMemberKemRotation(text: string): Promise; /** * Finish the KEM rotation to `epoch`: the next key becomes current, and the * old private key is gone from the record. A repeat after the rotation * finished comes back unchanged. Any other `epoch` returns `undefined`. A * record that is not canonical v1 text throws. */ export declare function finishMemberKemRotation(text: string, epoch: number): string | undefined;