sig
  module type Core =
    sig
      type ekey
      type dkey
      val of_secret :
        Cstruct.t ->
        Nocrypto.Cipher_block.S.Core.ekey * Nocrypto.Cipher_block.S.Core.dkey
      val e_of_secret : Cstruct.t -> Nocrypto.Cipher_block.S.Core.ekey
      val d_of_secret : Cstruct.t -> Nocrypto.Cipher_block.S.Core.dkey
      val key : int array
      val block : int
      val encrypt :
        key:Nocrypto.Cipher_block.S.Core.ekey ->
        blocks:int -> Native.buffer -> int -> Native.buffer -> int -> unit
      val decrypt :
        key:Nocrypto.Cipher_block.S.Core.dkey ->
        blocks:int -> Native.buffer -> int -> Native.buffer -> int -> unit
    end
  module type ECB =
    sig
      type key
      val of_secret : Cstruct.t -> Nocrypto.Cipher_block.S.ECB.key
      val key_sizes : int array
      val block_size : int
      val encrypt :
        key:Nocrypto.Cipher_block.S.ECB.key -> Cstruct.t -> Cstruct.t
      val decrypt :
        key:Nocrypto.Cipher_block.S.ECB.key -> Cstruct.t -> Cstruct.t
    end
  module type CBC =
    sig
      type key
      val of_secret : Cstruct.t -> Nocrypto.Cipher_block.S.CBC.key
      val key_sizes : int array
      val block_size : int
      val next_iv : iv:Cstruct.t -> Cstruct.t -> Cstruct.t
      val encrypt :
        key:Nocrypto.Cipher_block.S.CBC.key ->
        iv:Cstruct.t -> Cstruct.t -> Cstruct.t
      val decrypt :
        key:Nocrypto.Cipher_block.S.CBC.key ->
        iv:Cstruct.t -> Cstruct.t -> Cstruct.t
    end
  module type CTR =
    sig
      type key
      val of_secret : Cstruct.t -> Nocrypto.Cipher_block.S.CTR.key
      val key_sizes : int array
      val block_size : int
      val stream :
        key:Nocrypto.Cipher_block.S.CTR.key ->
        ctr:Cstruct.t -> ?off:int -> int -> Cstruct.t
      val encrypt :
        key:Nocrypto.Cipher_block.S.CTR.key ->
        ctr:Cstruct.t -> ?off:int -> Cstruct.t -> Cstruct.t
      val decrypt :
        key:Nocrypto.Cipher_block.S.CTR.key ->
        ctr:Cstruct.t -> ?off:int -> Cstruct.t -> Cstruct.t
    end
  module type GCM =
    sig
      type key
      type result = { message : Cstruct.t; tag : Cstruct.t; }
      val of_secret : Cstruct.t -> Nocrypto.Cipher_block.S.GCM.key
      val key_sizes : int array
      val block_size : int
      val encrypt :
        key:Nocrypto.Cipher_block.S.GCM.key ->
        iv:Cstruct.t ->
        ?adata:Cstruct.t -> Cstruct.t -> Nocrypto.Cipher_block.S.GCM.result
      val decrypt :
        key:Nocrypto.Cipher_block.S.GCM.key ->
        iv:Cstruct.t ->
        ?adata:Cstruct.t -> Cstruct.t -> Nocrypto.Cipher_block.S.GCM.result
    end
  module type CCM =
    sig
      type key
      val of_secret :
        maclen:int -> Cstruct.t -> Nocrypto.Cipher_block.S.CCM.key
      val key_sizes : int array
      val mac_sizes : int array
      val block_size : int
      val encrypt :
        key:Nocrypto.Cipher_block.S.CCM.key ->
        nonce:Cstruct.t -> ?adata:Cstruct.t -> Cstruct.t -> Cstruct.t
      val decrypt :
        key:Nocrypto.Cipher_block.S.CCM.key ->
        nonce:Cstruct.t -> ?adata:Cstruct.t -> Cstruct.t -> Cstruct.t option
    end
end