import { BaseWallet } from 'ethers';
import { BuildItUint256WithSignerParams, CtUint256Like, ctInt256, ctString, ctUint, ctUint256, itInt256, itString, itUint, itUint256, itUint256Signed, SerializableCtUint, SerializableCtUint256 } from './types';
/**
 * Low-level AES block encryption used by the COTI garbled-circuit scheme.
 *
 * Encrypts up to 16 bytes of plaintext by XORing with AES-ECB(random `r`).
 * Returns the 16-byte ciphertext block and the random `r` used (also 16 bytes).
 *
 * @param key - 128-bit AES key (16 bytes).
 * @param plaintext - Up to 16 bytes; shorter inputs are zero-padded on the left.
 * @returns The ciphertext block and random `r` (each 16 bytes).
 * @throws RangeError if `plaintext` exceeds 16 bytes or `key` is not 16 bytes.
 */
export declare function encrypt(key: Uint8Array, plaintext: Uint8Array): {
    ciphertext: Uint8Array;
    r: Uint8Array;
};
/**
 * Low-level AES block decryption. Inverts {@link encrypt}.
 *
 * Decrypts one 16-byte block. When `r2` and `ciphertext2` are provided, decrypts
 * a second block and returns the 32-byte concatenation of both plaintext blocks.
 *
 * @param key - 128-bit AES key (16 bytes).
 * @param r - 16-byte random value from encryption.
 * @param ciphertext - 16-byte ciphertext block.
 * @param r2 - Optional second-block random value (must pair with `ciphertext2`).
 * @param ciphertext2 - Optional second-block ciphertext (must pair with `r2`).
 * @returns 16-byte plaintext, or 32 bytes when a second block is supplied.
 * @throws RangeError if any input has an invalid length or block pairs are mismatched.
 */
export declare function decrypt(key: Uint8Array, r: Uint8Array, ciphertext: Uint8Array, r2?: Uint8Array | null, ciphertext2?: Uint8Array | null): Uint8Array;
/**
 * Generates a 2048-bit RSA key pair in DER encoding.
 *
 * @returns Public and private keys as `Uint8Array` DER blobs.
 */
export declare function generateRSAKeyPair(): {
    publicKey: Uint8Array;
    privateKey: Uint8Array;
};
/**
 * Decrypts an RSA-OAEP (SHA-256) ciphertext with a DER-encoded private key.
 *
 * @param privateKey - RSA private key as a DER `Uint8Array`.
 * @param ciphertext - Hex-encoded RSA ciphertext (no `0x` prefix required by forge).
 * @returns Decrypted payload as a lowercase hex string.
 * @throws Error if the key or ciphertext format is invalid.
 */
export declare function decryptRSA(privateKey: Uint8Array, ciphertext: string): string;
/**
 * Recovers a user's AES key by XORing two RSA-decrypted key shares.
 *
 * Each share is RSA-OAEP encrypted; after decryption both shares are parsed as
 * hex AES keys and XORed to produce the final 128-bit user key.
 *
 * @param privateKey - RSA private key used to decrypt both shares.
 * @param encryptedKeyShare0 - Hex RSA ciphertext of the first share.
 * @param encryptedKeyShare1 - Hex RSA ciphertext of the second share.
 * @returns Recovered AES key as a 32-character lowercase hex string.
 * @throws Error if RSA decryption or key parsing fails.
 */
export declare function recoverUserKey(privateKey: Uint8Array, encryptedKeyShare0: string, encryptedKeyShare1: string): string;
/**
 * Signs a message hash with an Ethereum secp256k1 private key.
 *
 * @param message - 32-byte message digest as a hex string (e.g. from `solidityPackedKeccak256`).
 * @param privateKey - Signer's private key (hex string).
 * @returns 65-byte signature (`r` || `s` || `v`) as a `Uint8Array`.
 */
export declare function sign(message: string, privateKey: string): Uint8Array;
/**
 * Signs a ctUint ciphertext for COTI input-text (IT) submission.
 *
 * Hashes `(signer, contract, selector, ciphertext)` with `solidityPackedKeccak256`
 * and signs the digest with the sender's wallet private key.
 *
 * @param sender - Wallet and user AES key (key is not used for signing).
 * @param contractAddress - Target contract address.
 * @param functionSelector - 4-byte function selector (e.g. `"0x11223344"`).
 * @param ct - Encrypted value ({@link ctUint} bigint) being signed.
 * @returns 65-byte signature as a `Uint8Array`.
 */
export declare function signInputText(sender: {
    wallet: BaseWallet;
    userKey: string;
}, contractAddress: string, functionSelector: string, ct: bigint): Uint8Array;
/**
 * @deprecated Use {@link prepareIT} for unsigned integer input-text values. This
 * legacy helper is limited to 64-bit plaintexts and will be removed in a
 * future major version.
 *
 * Encrypts a plaintext, signs the ciphertext, and returns an {@link itUint}
 * ready for smart contract submission.
 *
 * @param plaintext - Unsigned value up to 64 bits.
 * @param sender - Wallet and user AES key.
 * @param contractAddress - Target contract address.
 * @param functionSelector - 4-byte function selector.
 * @returns Signed input text with {@link ctUint} ciphertext.
 * @throws RangeError if `plaintext` exceeds 64 bits or is negative.
 */
export declare function buildInputText(plaintext: bigint, sender: {
    wallet: BaseWallet;
    userKey: string;
}, contractAddress: string, functionSelector: string): itUint;
/**
 * Builds signed input text for a UTF-8 string.
 *
 * Encodes the string in 8-byte chunks (each stored as a {@link ctUint}),
 * encrypts and signs each chunk independently, and returns an {@link itString}.
 *
 * @param plaintext - UTF-8 string to encrypt.
 * @param sender - Wallet and user AES key.
 * @param contractAddress - Target contract address.
 * @param functionSelector - 4-byte function selector.
 * @returns Signed string input text with one ciphertext/signature pair per chunk.
 * @throws RangeError if any chunk exceeds 64 bits after encoding.
 */
export declare function buildStringInputText(plaintext: string, sender: {
    wallet: BaseWallet;
    userKey: string;
}, contractAddress: string, functionSelector: string): itString;
/**
 * Decrypts a ctUint ciphertext using the user's AES key.
 *
 * `ctUint` is stored on-chain as a bigint packing 32 bytes (16-byte AES
 * ciphertext + 16-byte random `r`). This function decrypts to a plaintext
 * of up to 64 bits. For 128-bit input-text values use `prepareIT` instead.
 *
 * - A zero ciphertext is short-circuited to `0n` without validating the key,
 *   since it represents uninitialized/empty on-chain storage. This allows DApps
 *   to read empty balances before the user has configured their AES key.
 *   Note: this means `decryptUint(0n, invalidKey)` returns `0n` without throwing.
 * - For non-zero ciphertexts, key validation is performed by `encodeKey`
 *   (strips "0x", lowercases, enforces 128-bit hex). Invalid keys throw
 *   rather than producing garbage.
 *
 * @param ciphertext - The ctUint value (32-byte wire format as a bigint).
 * @param userKey - The AES key (32 hex chars, optionally "0x"-prefixed).
 * @returns The decrypted plaintext as a bigint (up to 64 bits).
 * @throws Error if the key is invalid (null, wrong length, non-hex) and ciphertext is non-zero.
 */
export declare function decryptUint(ciphertext: ctUint, userKey: string): bigint;
/**
 * Decrypts a canonical {@link ctUint256} ciphertext using the user's AES key.
 *
 * @param ciphertext - Object with `ciphertextHigh` and `ciphertextLow` parts.
 * @param userKey - AES key (32 hex chars, optionally `0x`-prefixed).
 * @returns Decrypted plaintext as a bigint (up to 256 bits).
 * @throws Error if the key is invalid.
 */
export declare function decryptUint256(ciphertext: ctUint256, userKey: string): bigint;
/**
 * Decrypts a {@link ctString} ciphertext back to a UTF-8 string.
 *
 * Each chunk is decrypted via {@link decryptUint}; trailing zero padding added
 * during {@link buildStringInputText} is trimmed before decoding.
 *
 * @param ciphertext - String ciphertext with an array of {@link ctUint} chunks.
 * @param userKey - AES key (32 hex chars, optionally `0x`-prefixed).
 * @returns Decrypted UTF-8 string.
 * @throws Error if the key is invalid for any non-zero chunk.
 */
export declare function decryptString(ciphertext: ctString, userKey: string): string;
/**
 * Generates 16 bytes of cryptographically random AES key material as a
 * node-forge binary string (each character's code point is one byte 0–255).
 *
 * @returns 16-character forge binary string (not hex).
 * @example
 * ```ts
 * const hexKey = Buffer.from(generateRandomAesKeyBinaryString(), "binary").toString("hex")
 * ```
 */
export declare function generateRandomAesKeyBinaryString(): string;
/**
 * @deprecated Use {@link generateRandomAesKeyBinaryString} instead. Despite the
 * name, the return value is a 16-byte binary string, not a numeric or hex value.
 */
export declare function generateRandomAesKeySizeNumber(): string;
/**
 * Converts a node-forge binary string into a `Uint8Array`.
 *
 * In forge binary strings each character's Unicode code point represents one
 * byte (0–255). This is **not** UTF-8 encoding of human-readable text.
 *
 * @param binaryString - Forge binary string (one byte per character code point).
 * @returns Byte array with one entry per character.
 */
export declare function binaryStringToBytes(binaryString: string): Uint8Array;
/**
 * @deprecated Use {@link binaryStringToBytes} instead. Despite the name, this does
 * not UTF-8-encode a string; it converts a forge binary string to bytes.
 */
export declare function encodeString(str: string): Uint8Array;
/**
 * Validates and normalizes an AES key: ensures it is present, strips the "0x"
 * prefix, and lowercases it. COTI uses a 128-bit AES key, so only 32-character
 * hex strings are accepted.
 *
 * @param aesKey - The AES key, optionally prefixed with "0x".
 * @returns The normalized lowercase hex string.
 * @throws Error if the key is empty/null/undefined, contains non-hex characters, or is not 32 hex characters.
 */
export declare function normalizeAesKey(aesKey: string | null | undefined): string;
/**
 * Parses and validates a user AES key hex string into a 16-byte `Uint8Array`.
 *
 * Delegates to {@link normalizeAesKey} for validation (strips `0x`, lowercases,
 * enforces 128-bit length) before hex decoding.
 *
 * @param userKey - AES key as a 32-character hex string (optional `0x` prefix).
 * @returns 128-bit key as 16 bytes.
 * @throws Error if the key is missing, wrong length, or contains non-hex characters.
 */
export declare function encodeKey(userKey: string): Uint8Array;
/**
 * Encodes an unsigned integer as a 16-byte big-endian byte array.
 *
 * @param plaintext - Integer value (typically up to 128 bits).
 * @returns 16-byte big-endian representation.
 */
export declare function encodeUint(plaintext: bigint): Uint8Array;
/**
 * Decodes a big-endian byte array into an unsigned bigint.
 *
 * @param plaintextBytes - Byte array (commonly 16 bytes from {@link encodeUint}).
 * @returns Decoded unsigned integer.
 * @throws SyntaxError if `plaintextBytes` is empty.
 */
export declare function decodeUint(plaintextBytes: Uint8Array): bigint;
/**
 * AES-ECB encrypts a 16-byte random value (the `r` component of COTI encryption).
 *
 * @param r - Random value as a forge binary string or 16-byte `Uint8Array`.
 * @param key - 128-bit AES key (16 bytes).
 * @returns Encrypted 16-byte block.
 * @throws RangeError if `key` is not 16 bytes.
 */
export declare function encryptNumber(r: string | Uint8Array, key: Uint8Array): Uint8Array;
/**
 * Prepares a signed input text ({@link itUint}) for an unsigned integer.
 *
 * Encrypts up to **128-bit** plaintext, signs the resulting {@link ctUint},
 * and returns the ciphertext/signature pair for smart contract submission.
 * For 256-bit values use {@link prepareIT256} instead.
 *
 * @param plaintext - Unsigned value up to 128 bits.
 * @param sender - Wallet and user AES key.
 * @param contractAddress - Target contract address.
 * @param functionSelector - 4-byte function selector.
 * @returns Signed input text.
 * @throws RangeError if `plaintext` exceeds 128 bits or is negative.
 */
export declare function prepareIT(plaintext: bigint, sender: {
    wallet: BaseWallet;
    userKey: string;
}, contractAddress: string, functionSelector: string): itUint;
/**
 * Encrypts an unsigned value into a {@link ctUint} without building an IT signature.
 *
 * Plaintext must fit in **64 bits**. The resulting {@link ctUint} bigint packs
 * 32 bytes on the wire (16-byte ciphertext + 16-byte random `r`). For 128-bit
 * input-text values use {@link prepareIT} instead.
 *
 * @param plaintext - Unsigned value up to 64 bits.
 * @param userKey - AES key (32 hex chars, optionally `0x`-prefixed).
 * @returns Encrypted ctUint ciphertext as a bigint.
 * @throws RangeError if `plaintext` exceeds 64 bits or is negative.
 * @throws Error if the key is invalid.
 */
export declare function encryptUint(plaintext: bigint, userKey: string): ctUint;
/**
 * Encrypts an unsigned value into a {@link ctUint256} without building an IT signature.
 *
 * Values up to 128 bits use compact encoding; larger values up to 256 bits use
 * full two-block encoding. For signed submission use {@link prepareIT256},
 * {@link prepareSignedIT256}, or {@link buildItUint256WithSigner} instead.
 *
 * @param plaintext - Unsigned value up to 256 bits.
 * @param userKey - AES key (32 hex chars, optionally `0x`-prefixed).
 * @returns Encrypted ctUint256 ciphertext.
 * @throws RangeError if `plaintext` exceeds 256 bits or is negative.
 * @throws Error if the key is invalid.
 */
export declare function encryptUint256(plaintext: bigint, userKey: string): ctUint256;
/**
 * Strict coercion for app/JSON payloads into canonical ctUint types.
 *
 * - `'ctUint64'`: coerces string/number/bigint to {@link ctUint}.
 * - `'ctUint256'`: accepts flat `{ ciphertextHigh, ciphertextLow }` or
 *   `[high, low]` tuples only.
 *
 * For nested on-chain shapes use {@link decryptCtUint256} instead.
 *
 * @param value - Serializable payload from JSON/RPC.
 * @param type - Target ciphertext type discriminator.
 * @returns Canonical `bigint` or {@link ctUint256}.
 * @throws Error if the payload cannot be coerced.
 */
export declare function normalizeCtPayload(value: SerializableCtUint, type: 'ctUint64'): ctUint;
export declare function normalizeCtPayload(value: SerializableCtUint256, type: 'ctUint256'): ctUint256;
export declare function normalizeCtPayload(value: SerializableCtUint | SerializableCtUint256, type: 'ctUint64' | 'ctUint256'): ctUint | ctUint256;
/**
 * Returns whether `value` matches a supported {@link ctUint256} wire shape.
 *
 * Accepts flat objects, two-element tuples, and nested four-limb objects as
 * defined by {@link CtUint256Like}. Does not validate ciphertext correctness.
 *
 * @param value - Value to inspect (e.g. from RPC or contract return data).
 * @returns `true` if the shape is recognized.
 */
export declare function isCtUint256Shape(value: unknown): value is CtUint256Like;
/**
 * Returns whether a ctUint256 value represents zero / uninitialized storage.
 *
 * Handles scalar zero, flat `{ ciphertextHigh, ciphertextLow }`, tuple, and
 * nested four-limb shapes. Returns `false` for unrecognized shapes.
 *
 * @param ciphertext - Ciphertext value in any supported wire format.
 * @returns `true` if all ciphertext limbs are zero.
 */
export declare function isZeroCtUint256(ciphertext: unknown): boolean;
/**
 * Decrypts a ctUint256 from any supported wire shape.
 *
 * Unlike {@link decryptUint256}, accepts flat, tuple, and nested on-chain/RPC
 * formats (see {@link isCtUint256Shape}). For strict JSON coercion use
 * {@link normalizeCtPayload} first.
 *
 * @param ciphertext - Flat, tuple, or nested ctUint256 payload.
 * @param userKey - AES key (32 hex chars, optionally `0x`-prefixed).
 * @returns Decrypted plaintext as a bigint (up to 256 bits).
 * @throws Error if the shape is invalid or the key is invalid.
 */
export declare function decryptCtUint256(ciphertext: unknown, userKey: string): bigint;
/**
 * Builds a signed {@link itUint256Signed} using an external wallet signer.
 *
 * Encrypts the value, then signs an ABI-packed payload of
 * `(signer, contract, selector, ciphertextHigh, ciphertextLow)`. Intended for
 * browser wallets — **not** interchangeable with {@link prepareIT256}, which
 * signs raw ciphertext bytes for private-key callers.
 *
 * @param params - Value, AES key, addresses, selector, and async sign callback.
 * @returns Encrypted ctUint256 and hex signature string from the wallet.
 * @throws RangeError if `value` exceeds 256 bits or is negative.
 * @throws Error if the AES key is invalid.
 */
export declare function buildItUint256WithSigner({ value, aesKey, signerAddress, contractAddress, functionSelector, signMessage }: BuildItUint256WithSignerParams): Promise<itUint256Signed>;
/**
 * Prepares a signed 256-bit input text ({@link itUint256}) for smart contract submission.
 *
 * Encrypts the plaintext (up to 256 bits), signs the raw 64-byte ciphertext bytes
 * with the sender's private key, and returns the ciphertext/signature pair.
 * For browser-wallet signing use {@link buildItUint256WithSigner} instead.
 *
 * @param plaintext - Unsigned value up to 256 bits.
 * @param sender - Wallet and user AES key.
 * @param contractAddress - Target contract address.
 * @param functionSelector - 4-byte function selector.
 * @returns Signed 256-bit input text.
 * @throws RangeError if `plaintext` exceeds 256 bits or is negative.
 */
export declare function prepareIT256(plaintext: bigint, sender: {
    wallet: BaseWallet;
    userKey: string;
}, contractAddress: string, functionSelector: string): itUint256;
/**
 * Encrypts a signed int256 into a {@link ctInt256} without building an IT signature.
 *
 * Negative values are encoded as 256-bit two's complement, then encrypted with
 * the same wire format as {@link encryptUint256}.
 *
 * @param plaintext - Signed value in `[-(2^255), 2^255 - 1]`.
 * @param userKey - AES key (32 hex chars, optionally `0x`-prefixed).
 * @returns Encrypted ctInt256 ciphertext.
 * @throws RangeError if `plaintext` is outside int256 range.
 * @throws Error if the key is invalid.
 */
export declare function encryptInt256(plaintext: bigint, userKey: string): ctInt256;
/**
 * Decrypts a {@link ctInt256} ciphertext and returns the signed plaintext.
 *
 * @param ciphertext - Encrypted int256 (same wire shape as ctUint256).
 * @param userKey - AES key (32 hex chars, optionally `0x`-prefixed).
 * @returns Signed plaintext in int256 range.
 * @throws Error if the key is invalid.
 */
export declare function decryptInt256(ciphertext: ctInt256, userKey: string): bigint;
/**
 * Prepares a signed int256 input text ({@link itInt256}) for smart contract submission.
 *
 * Encodes `plaintext` as 256-bit two's complement, then delegates to
 * {@link prepareIT256} for encrypt + private-key IT signature.
 *
 * @param plaintext - Signed value in `[-(2^255), 2^255 - 1]`.
 * @param sender - Wallet and user AES key.
 * @param contractAddress - Target contract address.
 * @param functionSelector - 4-byte function selector.
 * @returns Signed 256-bit input text.
 * @throws RangeError if `plaintext` is outside int256 range.
 */
export declare function prepareSignedIT256(plaintext: bigint, sender: {
    wallet: BaseWallet;
    userKey: string;
}, contractAddress: string, functionSelector: string): itInt256;
/**
 * Builds a COTI input-text (IT) signature over (signer, contract, selector, ciphertext).
 *
 * @deprecated Use `signInputText` with an ethers `Wallet` for private-key
 * signing. For browser signers, use `buildItUint256WithSigner` for 256-bit
 * values. This private-key convenience wrapper will be removed in a future
 * major version.
 *
 * @param signerAddress - Address of the signer; must match the address derived from privateKey.
 * @param contractAddress - Target contract address.
 * @param functionSelector - 4-byte function selector (e.g. "0x11223344").
 * @param ciphertext - The encrypted value being signed.
 * @param privateKey - Signer's private key.
 * @returns The 65-byte signature as a hex string.
 * @throws Error if signerAddress does not match the address derived from privateKey.
 */
export declare function buildItSignature(signerAddress: string, contractAddress: string, functionSelector: string, ciphertext: bigint, privateKey: string): string;
