import { type CurveFn as BLSCurveFn } from '@noble/curves/abstract/bls';
import type { Fp2 } from '@noble/curves/abstract/tower';
import type { ProjConstructor, ProjPointType } from '@noble/curves/abstract/weierstrass';
import type { MSMInput } from './msm-worker.ts';
export interface Coder<F, T> {
    encode(from: F): T;
    decode(to: T): F;
}
type RandFn = (len: number) => Uint8Array;
export type BigintToString<T> = T extends bigint ? `${T}` : T extends Array<infer U> ? Array<BigintToString<U>> : T extends null ? null : T extends object ? {
    [K in keyof T]: BigintToString<T[K]>;
} : T;
export type StringToBigint<T> = T extends `${bigint}` ? bigint : T extends Array<infer U> ? Array<StringToBigint<U>> : T extends null ? null : T extends object ? {
    [K in keyof T]: StringToBigint<T[K]>;
} : T;
export declare const stringBigints: {
    encode<F>(o: F): BigintToString<F>;
    decode<T>(o: T): StringToBigint<T>;
};
export type Constraint = Record<number, bigint>;
export type CircuitInfo = {
    nVars: number;
    nPubInputs: number;
    nOutputs: number;
    constraints: [Constraint, Constraint, Constraint][];
};
export type G1Point = [bigint, bigint, bigint];
export type G2Point = [[bigint, bigint], [bigint, bigint], [bigint, bigint]];
export interface PointsWithCoders {
    G1: ProjConstructor<bigint>;
    G2: ProjConstructor<Fp2>;
    G1c: Coder<ProjPointType<bigint>, G1Point>;
    G2c: Coder<ProjPointType<Fp2>, G2Point>;
}
export type ProvingKey = {
    protocol?: 'groth';
    nVars: number;
    nPublic: number;
    domainBits: number;
    domainSize: number;
    polsA: Constraint[];
    polsB: Constraint[];
    polsC: Constraint[];
    A: G1Point[];
    B1: G1Point[];
    B2: G2Point[];
    C: G1Point[];
    vk_alfa_1: G1Point;
    vk_beta_1: G1Point;
    vk_delta_1: G1Point;
    vk_beta_2: G2Point;
    vk_delta_2: G2Point;
    hExps: G1Point[];
};
export type VerificationKey = {
    protocol?: 'groth';
    nPublic: number;
    IC: G1Point[];
    vk_alfa_1: G1Point;
    vk_beta_2: G2Point;
    vk_gamma_2: G2Point;
    vk_delta_2: G2Point;
};
export type GrothProof = {
    protocol: 'groth';
    pi_a: G1Point;
    pi_b: G2Point;
    pi_c: G1Point;
};
/**
 * nqr: Override NonQuadratic Residue
 * unsafePreserveToxic: Output toxic values for tests
 */
export type GrothOpts = {
    nqr?: number | bigint;
    unsafePreserveToxic?: boolean;
    G1msm?: (input: MSMInput<bigint>[]) => Promise<ProjPointType<bigint>>;
    G2msm?: (input: MSMInput<Fp2>[]) => Promise<ProjPointType<Fp2>>;
};
export interface ToxicWaste {
    t: bigint;
    kalfa: bigint;
    kbeta: bigint;
    kgamma: bigint;
    kdelta: bigint;
}
export interface ProofWithSignals {
    proof: GrothProof;
    publicSignals: bigint[];
}
export interface SnarkConstructorOutput {
    utils: PointsWithCoders;
    groth: {
        setup(circuit: CircuitInfo, rnd?: RandFn): {
            pkey: ProvingKey;
            vkey: VerificationKey;
            toxic: ToxicWaste | undefined;
        };
        createProof(pkey: ProvingKey, witness: bigint[], rnd?: RandFn): Promise<ProofWithSignals>;
        verifyProof(vkey: VerificationKey, proofWithSignals: ProofWithSignals): boolean;
    };
}
export declare function buildSnark(curve: BLSCurveFn, opts?: GrothOpts): SnarkConstructorOutput;
/**
 * ZK Snarks over bn254 (aka bn128) curve.
 * @example
 * ```js
 * const proof = await zkp.bn254.groth.createProof(provingKey, witness);
 * const isValid = zkp.bn254.groth.verifyProof(verificationKey, proof);
 * ```
 */
export declare const bn254: SnarkConstructorOutput;
export {};
//# sourceMappingURL=index.d.ts.map