import type { ContextItem, ContextChannel } from './types.js';
/** Leaf pre-image domain tag. */
export declare const LEAF_TAG = "CPA:v0.1:leaf\n";
/** Internal-node domain tag. */
export declare const NODE_TAG = "CPA:v0.1:node\n";
/** Signing / cpa_ref domain tag (used only for cpa_ref). */
export declare const SIGN_TAG = "CPA:v0.1:sign\n";
declare function utf8(s: string): Uint8Array;
/**
 * The leaf pre-image: EXACTLY these four fields. content and trust_tier
 * are EXCLUDED so the root is identical whether or not content is later
 * disclosed. JCS sorts keys, so field order here is irrelevant.
 */
export interface LeafPreimage {
    byte_len: number;
    channel: ContextChannel;
    content_ref: string;
    ctx_id: string;
}
/** Extract the canonical leaf pre-image from a context item. */
export declare function leafPreimage(leaf: ContextItem): LeafPreimage;
/** leaf_hash = sha256( utf8(LEAF_TAG) || utf8(canonicalizeJCS(preimage)) )
 *  Returns the raw 32-byte digest. */
export declare function leafHash(leaf: ContextItem): Uint8Array;
/** node_hash = sha256( utf8(NODE_TAG) || left32 || right32 ) over RAW
 *  32-byte digests. Returns the raw 32-byte digest. */
export declare function nodeHash(left: Uint8Array, right: Uint8Array): Uint8Array;
/**
 * Build the partition_root (raw 32-byte digest) for one partition's
 * leaves. Leaves are sorted ascending by ctx_id (JS string / code-point
 * order). ctx_id MUST be unique within the partition; a duplicate throws.
 * Single leaf => partition_root = that leaf digest (no node hashing).
 * Throws on an empty leaf list (empty partitions are omitted upstream).
 */
export declare function buildPartitionRootBytes(leaves: ContextItem[]): Uint8Array;
/** Hex convenience wrapper around buildPartitionRootBytes. */
export declare function buildPartitionRoot(leaves: ContextItem[]): string;
/**
 * Build the top root (raw 32-byte digest) over present partition roots.
 * Input is the ordered list of RAW 32-byte partition_root digests, taken
 * in CHANNEL_ORDER by the caller. Same NODE_TAG odd-promotion rule.
 *   - Zero partitions => EMPTY sentinel: sha256( utf8(NODE_TAG) ||
 *     utf8("EMPTY") ).
 *   - One partition => root = that partition_root.
 */
export declare function buildTopRootBytes(partitionRootsInChannelOrder: Uint8Array[]): Uint8Array;
/** Hex convenience wrapper around buildTopRootBytes. */
export declare function buildTopRoot(partitionRootsInChannelOrder: string[]): string;
/** The frozen empty-tree top root, as 64-hex. Signable sentinel. */
export declare function emptyTreeRoot(): string;
export declare function bytesToHex(bytes: Uint8Array): string;
export declare function hexToBytes(hex: string): Uint8Array;
export { utf8 as utf8Bytes };
/** One audit step: the sibling digest (64-hex) and which side it sits on.
 *  side === 'left'  => fold as node_hash(sibling, acc)
 *  side === 'right' => fold as node_hash(acc, sibling) */
export interface InclusionStep {
    sibling: string;
    side: 'left' | 'right';
}
/** An inclusion proof for one leaf, identified by its ctx_id. The path is
 *  ordered bottom-up (leaf level first). */
export interface InclusionProof {
    ctx_id: string;
    path: InclusionStep[];
}
/**
 * Build an inclusion proof for the leaf whose ctx_id === ctx_id, against
 * the partition formed by `leaves`. Leaves are sorted by ctx_id exactly as
 * buildPartitionRootBytes does. Walks bottom-up, recording the sibling
 * digest (hex) and side at each level, and recording NO step when the
 * target/ancestor is the promoted odd node at a level (it carries straight
 * up, mirroring `reduce`).
 *
 * Throws on an empty partition, a duplicate ctx_id, or a ctx_id not found
 * (these are producer-side invariants; the verifier never calls this).
 */
export declare function buildInclusionProof(leaves: ContextItem[], ctx_id: string): InclusionProof;
/**
 * Verify an inclusion proof: recompute leaf_hash(leaf), fold the path with
 * node_hash respecting each step's side, and compare the hex result to
 * partition_root. Returns false on any structural problem or mismatch
 * (fail-closed; never throws on malformed proof material).
 */
export declare function verifyInclusionProof(leaf: ContextItem, proof: InclusionProof, partition_root: string): boolean;
//# sourceMappingURL=merkle.d.ts.map