import { CHash } from '@noble/curves/abstract/utils';
import { CurveFn } from '@noble/curves/abstract/weierstrass';
import { CurveFn as CurveFn_2 } from '@noble/curves/abstract/edwards';
import { CurveType } from '@noble/curves/abstract/weierstrass';
import { IField } from '@noble/curves/abstract/modular';

export declare const bls12381Fr: IField<bigint>;

export declare const createBls12_381: (randomBytes: RandomBytes) => {
    utils: {
        randomPrivateKey: () => Uint8Array;
    };
};

/**
 * Creates a curve function with the ability to generate curves using custom hash functions.
 * The function returns a curve function that includes a create method for generating curves with custom hash functions.
 *
 * @param curveDef - The curve definition excluding hash-related properties
 * @param hash - The default hash function to use
 * @param randomBytes - The random bytes function to use
 * @returns A curve function with an additional create method for generating curves with custom hash functions
 */
export declare function createCurve(curveDef: CurveDef, hash: CHash, randomBytes: RandomBytes): CurveFnWithCreate;

/**
 * ed25519 curve with EdDSA signatures.
 * @example
 * import { ed25519 } from '@noble/curves/ed25519';
 * const priv = ed25519.utils.randomPrivateKey();
 * const pub = ed25519.getPublicKey(priv);
 * const msg = new TextEncoder().encode('hello');
 * const sig = ed25519.sign(msg, priv);
 * ed25519.verify(sig, msg, pub); // Default mode: follows ZIP215
 * ed25519.verify(sig, msg, pub, { zip215: false }); // RFC8032 / FIPS 186-5
 */
export declare const createEd25519: (randomBytes: RandomBytes) => CurveFn_2;

/**
 * Creates a HMAC function using the provided hash function.
 * The function generates HMAC for the concatenated messages using the provided key.
 *
 * @param hash - The hash function to use for HMAC generation
 * @returns A function that generates HMAC for the concatenated messages
 */
export declare const createHmacFn: (hash: CHash) => (key: Uint8Array, ...msgs: Uint8Array[]) => Uint8Array<ArrayBufferLike>;

/**
 * Creates a NIST curve instance based on the specified curve name.
 *
 * @param curveName - Name of the NIST curve to create. Must be one of: 'P-256', 'P-384', 'P-521'.
 * @param randomBytes - Function to generate random bytes for cryptographic operations.
 * @returns NistCurve instance for the specified NIST curve.
 * @throws {Error} If an unsupported curve name is provided.
 */
export declare const createNistCurve: (curveName: NistCurveName, randomBytes: RandomBytes) => NistCurve;

/** NIST P256 (aka secp256r1, prime256v1) curve, ECDSA and ECDH methods. */
export declare const createP256: (randomBytes: RandomBytes) => CurveFnWithCreate;

/** NIST P384 (aka secp384r1) curve, ECDSA and ECDH methods. */
export declare const createP384: (randomBytes: RandomBytes) => CurveFnWithCreate;

/** NIST P521 (aka secp521r1) curve, ECDSA and ECDH methods. */
export declare const createP521: (randomBytes: RandomBytes) => CurveFnWithCreate;

/**
 * secp256k1 curve, ECDSA and ECDH methods.
 *
 * Field: `2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n`
 *
 * @example
 * ```js
 * import { secp256k1 } from '@noble/curves/secp256k1';
 * const priv = secp256k1.utils.randomPrivateKey();
 * const pub = secp256k1.getPublicKey(priv);
 * const msg = new Uint8Array(32).fill(1); // message hash (not message) in ecdsa
 * const sig = secp256k1.sign(msg, priv); // `{prehash: true}` option is available
 * const isValid = secp256k1.verify(sig, msg, pub) === true;
 * ```
 */
export declare const createSecp256k1: (randomBytes: RandomBytes) => CurveFnWithCreate;

/**
 * Type definition for curve configuration, excluding hash-related properties.
 * Matches the API of @noble/hashes but allows creating curves with custom hash functions.
 */
export declare type CurveDef = Readonly<Omit<CurveType, 'hash' | 'hmac' | 'randomBytes'>>;

/**
 * Extended curve function type that includes a create method for generating curves with custom hash functions.
 */
export declare type CurveFnWithCreate = CurveFn & {
    create: (hash: CHash) => CurveFn;
};

/**
 * Twisted Edwards curve options.
 *
 * * a: formula param
 * * d: formula param
 * * p: prime characteristic (order) of finite field, in which arithmetics is done
 * * n: order of prime subgroup a.k.a total amount of valid curve points
 * * h: cofactor. h*n is group order; n is subgroup order
 * * Gx: x coordinate of generator point a.k.a. base point
 * * Gy: y coordinate of generator point
 */
export declare type EdwardsOpts = Readonly<{
    a: bigint;
    d: bigint;
    p: bigint;
    n: bigint;
    h: bigint;
    Gx: bigint;
    Gy: bigint;
}>;

/**
 * When Weierstrass curve has `a=0`, it becomes Koblitz curve.
 * Koblitz curves allow using **efficiently-computable GLV endomorphism ψ**.
 * Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
 * For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
 *
 * Endomorphism consists of beta, lambda and splitScalar:
 *
 * 1. GLV endomorphism ψ transforms a point: `P = (x, y) ↦ ψ(P) = (β·x mod p, y)`
 * 2. GLV scalar decomposition transforms a scalar: `k ≡ k₁ + k₂·λ (mod n)`
 * 3. Then these are combined: `k·P = k₁·P + k₂·ψ(P)`
 * 4. Two 128-bit point-by-scalar multiplications + one point addition is faster than
 *    one 256-bit multiplication.
 *
 * where
 * * beta: β ∈ Fₚ with β³ = 1, β ≠ 1
 * * lambda: λ ∈ Fₙ with λ³ = 1, λ ≠ 1
 * * splitScalar decomposes k ↦ k₁, k₂, by using reduced basis vectors.
 *   Gauss lattice reduction calculates them from initial basis vectors `(n, 0), (-λ, 0)`
 *
 * Check out `test/misc/endomorphism.js` and
 * [gist](https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066).
 */
export declare type EndomorphismOpts = {
    beta: bigint;
    splitScalar: (k: bigint) => {
        k1neg: boolean;
        k1: bigint;
        k2neg: boolean;
        k2: bigint;
    };
};

/**
 * Function type for validating a public key.
 * @param publicKey - The public key as a Uint8Array
 * @returns {boolean} - Returns true if the public key is valid, otherwise false.
 */
declare type IsValidPublicKey = (publicKey: Uint8Array) => boolean;

export declare type Jwk = {
    kty: string;
    crv: string;
    x: string;
    y: string;
    d?: string;
};

/**
 * Modifies a curve function to ensure proper handling of input types for signing and verification.
 * Wraps the curve's sign and verify methods to convert any byte-like inputs to Uint8Array
 * before passing them to the underlying curve implementation.
 *
 * @param curve - The curve function to modify
 * @returns A modified curve function with type-safe sign and verify methods
 */
export declare const modifyCurve: (curve: CurveFnWithCreate) => CurveFnWithCreate;

/**
 * Extended curve type for NIST curves, including curve name and JWK conversion helpers.
 * @property curveName - The name of the NIST curve ('P-256', 'P-384', or 'P-521')
 * @property toJwkPrivateKey - Converts a private key to a JWK object
 * @property toJwkPublicKey - Converts a public key to a JWK object
 */
export declare type NistCurve = CurveFnWithCreate & {
    /** Name of the NIST curve */
    curveName: NistCurveName;
    /** Function to generate random bytes for cryptographic operations */
    randomBytes: RandomBytes;
    /** Converts a private key to a JWK object */
    toJwkPrivateKey: ToJwkPrivateKey;
    /** Converts a public key to a JWK object */
    toJwkPublicKey: ToJwkPublicKey;
    /** Converts a JWK private key to raw private key format */
    toRawPrivateKey: ToRawPrivateKey;
    /** Converts a JWK public key to raw uncompressed public key format */
    toRawPublicKey: ToRawPublicKey;
    /** Validates a public key */
    isValidPublicKey: IsValidPublicKey;
};

/**
 * Type representing supported NIST curve names.
 * Possible values: 'P-256', 'P-384', 'P-521'
 */
export declare type NistCurveName = 'P-256' | 'P-384' | 'P-521';

/**
 * Function type that generates random bytes.
 * @param bytesLength - Optional number of bytes to generate. If not provided, implementation should choose appropriate length.
 * @returns Uint8Array containing the generated random bytes.
 */
export declare type RandomBytes = (bytesLength?: number) => Uint8Array;

/**
 * Represents a signature-like object containing r and s values.
 * Used for elliptic curve digital signatures.
 */
export declare type SignatureLike = {
    r: bigint;
    s: bigint;
};

/**
 * Function type for converting a private key to a JWK object.
 * @param privateKey - The private key as a Uint8Array
 * @returns JWK representation of the private key
 */
declare type ToJwkPrivateKey = (privateKey: Uint8Array) => Jwk;

/**
 * Converts a private key to JSON Web Key (JWK) format.
 * The function first derives the public key from the private key, then creates a JWK
 * representation that includes both the public key components and the private key.
 *
 * @param params - Parameters containing curve, curve name, and private key
 * @returns JWK representation of the private key
 *
 * @example
 * const jwk = toJwkPrivateKey({
 *   curve: p256,
 *   curveName: 'P-256',
 *   privateKey: '...'
 * });
 */
export declare const toJwkPrivateKey: ({ curve, curveName, privateKey, }: ToJwkPrivateKeyParams) => Jwk;

/**
 * Parameters for converting a private key to JWK format.
 */
export declare type ToJwkPrivateKeyParams = {
    /** Curve function instance */
    curve: CurveFn;
    /** Name of the elliptic curve */
    curveName: NistCurveName;
    /** Private key */
    privateKey: Uint8Array;
};

/**
 * Function type for converting a public key to a JWK object.
 * @param publicKey - The public key as a Uint8Array
 * @returns JWK representation of the public key
 */
declare type ToJwkPublicKey = (publicKey: Uint8Array) => Jwk;

/**
 * Converts a public key to JSON Web Key (JWK) format.
 *
 * @param params - Parameters containing curve, curve name, and public key
 * @returns JWK representation of the public key
 *
 * @example
 * const jwk = toJwkPublicKey({
 *   curve: p256,
 *   curveName: 'P-256',
 *   publicKey: '04...'
 * });
 */
export declare const toJwkPublicKey: ({ curve, curveName, publicKey, }: ToJwkPublicKeyParams) => Jwk;

/**
 * Parameters for converting a public key to JWK format.
 */
export declare type ToJwkPublicKeyParams = {
    /** Curve function instance */
    curve: CurveFn;
    /** Name of the elliptic curve */
    curveName: NistCurveName;
    /** Public key */
    publicKey: Uint8Array;
};

/**
 * Function type for converting a JWK private key to raw private key format.
 * @param privateKey - The JWK private key containing x,y,d coordinates in base64url format
 * @returns Uint8Array containing the raw private key
 */
declare type ToRawPrivateKey = (privateKey: Jwk) => Uint8Array;

/**
 * Function type for converting a JWK public key to raw uncompressed public key format.
 * The resulting format is: 0x04 || x || y where x and y are coordinates.
 * @param publicKey - The JWK public key containing x and y coordinates in base64url format
 * @returns Uint8Array containing the raw uncompressed public key
 */
declare type ToRawPublicKey = (publicKey: Jwk) => Uint8Array;

/**
 * Weierstrass curve options.
 *
 * * p: prime characteristic (order) of finite field, in which arithmetics is done
 * * n: order of prime subgroup a.k.a total amount of valid curve points
 * * h: cofactor, usually 1. h*n is group order; n is subgroup order
 * * a: formula param, must be in field of p
 * * b: formula param, must be in field of p
 * * Gx: x coordinate of generator point a.k.a. base point
 * * Gy: y coordinate of generator point
 */
export declare type WeierstrassOpts<T> = Readonly<{
    p: bigint;
    n: bigint;
    h: bigint;
    a: T;
    b: T;
    Gx: T;
    Gy: T;
}>;

export { }
