/** * The member key bundle (#654 design §7.1, §7.2, E2b; owner decision 10a). * * A bundle is the public half of one member: its id, its ECDSA P-256 signing * key, its P-256 KEM key, the KEM epoch, and `kemSig`. A device member also * names its SDK device id. A client member does not. * * `kemSig` is the member's own signature over its KEM key and epoch. The * fingerprint covers only the signing key, so a KEM rotation keeps the member * id and the fingerprint. The self-signature binds the KEM key to the member: * a Host that swaps the KEM key breaks the signature. * * An `add` chain entry carries the bundle. The pairing MACs bind it. In a * later slice, the device registers it with device proof. */ import { z } from 'zod'; import type { WebCryptoKey } from '../webcrypto'; import { type Bytes, type P256PublicJwk } from './primitives'; export declare const MEMBER_KEY_BUNDLE_VERSION = 1; /** Prepended to the canonical KEM statement, so `kemSig` never verifies as another signed object. */ export declare const MEMBER_KEM_DOMAIN_PREFIX = "byok-member-kem-v1\n"; export interface MemberKeyBundleV1 { readonly v: typeof MEMBER_KEY_BUNDLE_VERSION; readonly memberId: string; readonly signingPublicJwk: P256PublicJwk; readonly kemPublicJwk: P256PublicJwk; readonly kemEpoch: number; /** ECDSA P-256 / SHA-256 by the signing key over the KEM statement, base64url of the 64-byte P1363 form. */ readonly kemSig: string; /** The SDK device id of a device member. A client member has none. */ readonly deviceId?: string; } export declare const KemEpochSchema: z.ZodNumber; export declare const KemSigSchema: z.ZodString; /** `MEMBER_KEM_DOMAIN_PREFIX || canonicalJson({ memberId, kemPublicKey: { x, y }, kemEpoch })`. */ export declare function memberKemSigningInput(memberId: string, kemPublicJwk: P256PublicJwk, kemEpoch: number): Bytes; export interface CreateMemberKeyBundleInput { readonly signingPublicJwk: P256PublicJwk; readonly signingPrivateKey: WebCryptoKey; readonly kemPublicJwk: P256PublicJwk; readonly kemEpoch: number; readonly deviceId?: string; } /** Build a bundle: derive the member id and sign the KEM statement. Bad input throws `sealed_secret_invalid`. */ export declare function createMemberKeyBundle(input: CreateMemberKeyBundleInput): Promise; /** Both keys are points on P-256, and the KEM key is not the signing key. */ export declare function isValidMemberKemKey(kemPublicJwk: P256PublicJwk, signingPublicJwk: P256PublicJwk): Promise; /** The KEM key is valid for the member, and `kemSig` is the member's signature over it. Never throws. */ export declare function verifyMemberKem(member: { readonly memberId: string; readonly signingPublicJwk: P256PublicJwk; }, kem: { readonly kemPublicJwk: P256PublicJwk; readonly kemEpoch: number; readonly kemSig: string; }): Promise; /** * Parse a received bundle. It is valid when its shape is strict, `memberId` * is the id of `signingPublicJwk` (which also checks that key is on the * curve), the KEM key is a different point on the curve, and `kemSig` * verifies. Returns `undefined` for anything else; it never throws for * hostile input. */ export declare function parseMemberKeyBundle(value: unknown): Promise;