declare module "gm-crypto" {
  export namespace SM2 {
    export enum constants {
      C1C2C3,
      C1C3C2,
      /** 未压缩 */
      PC = '04'
    }
    /** Generates a new asymmetric key pair */
    export function generateKeyPair(): {
      privateKey: string;
      publicKey: string;
    };
    /** 
     * Encrypt data 
     * @param data Plain message
     * @param key Public key generated by SM2.generateKeyPair()
     * @param options encrypt options
     * */
    export function encrypt(data: string | ArrayBuffer | Buffer, key: string, options?: EncryptOptions): string;
    export function encrypt(data: string | ArrayBuffer | Buffer, key: string, options?: Omit<EncryptOptions, "outputEncoding">): ArrayBuffer;
    /** 
     * Decrypt data 
     * @param data Ciphered data
     * @param key Public key generated by SM2.generateKeyPair()
     * @param options 
     * */
    export function decrypt(data: string | ArrayBuffer | Buffer, key: string, options?: DecryptOptions): string;
    export function decrypt(data: string | ArrayBuffer | Buffer, key: string, options?: Omit<DecryptOptions, "outputEncoding">): ArrayBuffer;
    export interface EncryptOptions {
      /** 
       * Concatenation mode
       * @default SM2.constants.C1C3C2
       *  */
      mode?: SM2.constants;
      /** 
       * The encoding of the plain data string,if `data` is not a string then `inputEncoding` is ignored.
       * @default "utf8"
       */
      inputEncoding?: BufferEncoding;
      /** If `outputEncoding` is provided, a string will be returned, otherwise a [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) is returned. */
      outputEncoding: BufferEncoding;
    }
    export interface DecryptOptions {
      /** 
       * Concatenation mode
       * @default SM2.constants.C1C3C2
       *  */
      mode?: SM2.constants;
      /** 
       * The encoding of the plain data string,if `data` is not a string then `inputEncoding` is ignored.
       */
      inputEncoding?: BufferEncoding;
      /** If `outputEncoding` is provided, a string will be returned, otherwise a [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) is returned. */
      outputEncoding: BufferEncoding;
    }
  }
  export namespace SM3 {
    /**
     * Calculates the digest.
     * @param data Data message
     * @param inputEncoding The encoding of the data string, if data is not a string then inputEncoding is ignored.Default is "utf8"
     * @param outputEncoding If `outputEncoding` is provided, a string will be returned, otherwise a [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) is returned.
     */
    export function digest(data: string | ArrayBuffer | Buffer, inputEncoding: string, outputEncoding: BufferEncoding): string;
    export function digest(data: string | ArrayBuffer | Buffer, inputEncoding?: BufferEncoding): ArrayBuffer;
  }
  export namespace SM4 {
    export enum constants {
      ECB = 1,
      CBC
    }
    /**
     * Encrypt data.
     * @param data Plain message
     * @param key Cipher key(any string of 32 hexadecimal digits)
     * @param options Options
     */
    export function encrypt(data: string | ArrayBuffer | Buffer, key: string, options?: EncryptOptions): string;
    export function encrypt(data: string | ArrayBuffer | Buffer, key: string, options?: Omit<EncryptOptions, "outputEncoding">): ArrayBuffer;
    export interface EncryptOptions {
      /**
       * Block cipher mode
       * @default SM4.constants.ECB
       */
      mode?: SM4.constants;
      /**
       * Initialization vector(any string of 32 hexadecimal digits)
       */
      iv?: string;
      /**
       * The encoding of the plain data string,if data is not a string then inputEncoding is ignored.
       * @default "utf8"
       */
      inputEncoding?: BufferEncoding;
      /** If `outputEncoding` is provided, a string will be returned, otherwise a [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) is returned. */
      outputEncoding: BufferEncoding;
    }
    /**
     * Decrypt data.
     * @param data Ciphered data
     * @param key Cipher key(any string of 32 hexadecimal digits)
     * @param options Options
     */
    export function decrypt(data: string | ArrayBuffer | Buffer, key: string, options?: DecryptOptions): string;
    export function decrypt(data: string | ArrayBuffer | Buffer, key: string, options?: Omit<DecryptOptions, "outputEncoding">): ArrayBuffer;
    export interface DecryptOptions {
      /**
       * Block cipher mode
       * @default "ECB"
       */
      mode?: SM4.constants;
      /**
       * Initialization vector(any string of 32 hexadecimal digits)
       */
      iv?: string;
      /**
       * The encoding of the plain data string,if data is not a string then inputEncoding is ignored.
       */
      inputEncoding?: BufferEncoding;
      /** If `outputEncoding` is provided, a string will be returned, otherwise a [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) is returned. */
      outputEncoding: BufferEncoding;
    }
  }
}