// Generated by Lisette bindgen
// Source: crypto/cipher (Go stdlib)
// Go: 1.25.10
// Lisette: 0.2.1

import "go:io"

/// NewCBCDecrypter returns a BlockMode which decrypts in cipher block chaining
/// mode, using the given Block. The length of iv must be the same as the
/// Block's block size and must match the iv used to encrypt the data.
pub fn NewCBCDecrypter(b: Block, iv: Slice<byte>) -> BlockMode

/// NewCBCEncrypter returns a BlockMode which encrypts in cipher block chaining
/// mode, using the given Block. The length of iv must be the same as the
/// Block's block size.
pub fn NewCBCEncrypter(b: Block, iv: Slice<byte>) -> BlockMode

/// NewCFBDecrypter returns a [Stream] which decrypts with cipher feedback mode,
/// using the given [Block]. The iv must be the same length as the [Block]'s block
/// size.
/// 
/// Deprecated: CFB mode is not authenticated, which generally enables active
/// attacks to manipulate and recover the plaintext. It is recommended that
/// applications use [AEAD] modes instead. The standard library implementation of
/// CFB is also unoptimized and not validated as part of the FIPS 140-3 module.
/// If an unauthenticated [Stream] mode is required, use [NewCTR] instead.
pub fn NewCFBDecrypter(block: Block, iv: Slice<byte>) -> Stream

/// NewCFBEncrypter returns a [Stream] which encrypts with cipher feedback mode,
/// using the given [Block]. The iv must be the same length as the [Block]'s block
/// size.
/// 
/// Deprecated: CFB mode is not authenticated, which generally enables active
/// attacks to manipulate and recover the plaintext. It is recommended that
/// applications use [AEAD] modes instead. The standard library implementation of
/// CFB is also unoptimized and not validated as part of the FIPS 140-3 module.
/// If an unauthenticated [Stream] mode is required, use [NewCTR] instead.
pub fn NewCFBEncrypter(block: Block, iv: Slice<byte>) -> Stream

/// NewCTR returns a [Stream] which encrypts/decrypts using the given [Block] in
/// counter mode. The length of iv must be the same as the [Block]'s block size.
pub fn NewCTR(block: Block, iv: Slice<byte>) -> Stream

/// NewGCM returns the given 128-bit, block cipher wrapped in Galois Counter Mode
/// with the standard nonce length.
/// 
/// In general, the GHASH operation performed by this implementation of GCM is not constant-time.
/// An exception is when the underlying [Block] was created by aes.NewCipher
/// on systems with hardware support for AES. See the [crypto/aes] package documentation for details.
pub fn NewGCM(cipher: Block) -> Result<AEAD, error>

/// NewGCMWithNonceSize returns the given 128-bit, block cipher wrapped in Galois
/// Counter Mode, which accepts nonces of the given length. The length must not
/// be zero.
/// 
/// Only use this function if you require compatibility with an existing
/// cryptosystem that uses non-standard nonce lengths. All other users should use
/// [NewGCM], which is faster and more resistant to misuse.
pub fn NewGCMWithNonceSize(cipher: Block, size: int) -> Result<AEAD, error>

/// NewGCMWithRandomNonce returns the given cipher wrapped in Galois Counter
/// Mode, with randomly-generated nonces. The cipher must have been created by
/// [crypto/aes.NewCipher].
/// 
/// It generates a random 96-bit nonce, which is prepended to the ciphertext by Seal,
/// and is extracted from the ciphertext by Open. The NonceSize of the AEAD is zero,
/// while the Overhead is 28 bytes (the combination of nonce size and tag size).
/// 
/// A given key MUST NOT be used to encrypt more than 2^32 messages, to limit the
/// risk of a random nonce collision to negligible levels.
pub fn NewGCMWithRandomNonce(cipher: Block) -> Result<AEAD, error>

/// NewGCMWithTagSize returns the given 128-bit, block cipher wrapped in Galois
/// Counter Mode, which generates tags with the given length.
/// 
/// Tag sizes between 12 and 16 bytes are allowed.
/// 
/// Only use this function if you require compatibility with an existing
/// cryptosystem that uses non-standard tag lengths. All other users should use
/// [NewGCM], which is more resistant to misuse.
pub fn NewGCMWithTagSize(cipher: Block, tagSize: int) -> Result<AEAD, error>

/// NewOFB returns a [Stream] that encrypts or decrypts using the block cipher b
/// in output feedback mode. The initialization vector iv's length must be equal
/// to b's block size.
/// 
/// Deprecated: OFB mode is not authenticated, which generally enables active
/// attacks to manipulate and recover the plaintext. It is recommended that
/// applications use [AEAD] modes instead. The standard library implementation of
/// OFB is also unoptimized and not validated as part of the FIPS 140-3 module.
/// If an unauthenticated [Stream] mode is required, use [NewCTR] instead.
pub fn NewOFB(b: Block, iv: Slice<byte>) -> Stream

/// AEAD is a cipher mode providing authenticated encryption with associated
/// data. For a description of the methodology, see
/// https://en.wikipedia.org/wiki/Authenticated_encryption.
pub interface AEAD {
  fn NonceSize() -> int
  fn Open(
    mut dst: Slice<byte>,
    nonce: Slice<byte>,
    ciphertext: Slice<byte>,
    additionalData: Slice<byte>,
  ) -> Result<Slice<byte>, error>
  fn Overhead() -> int
  fn Seal(
    mut dst: Slice<byte>,
    nonce: Slice<byte>,
    plaintext: Slice<byte>,
    additionalData: Slice<byte>,
  ) -> Slice<byte>
}

/// A Block represents an implementation of block cipher
/// using a given key. It provides the capability to encrypt
/// or decrypt individual blocks. The mode implementations
/// extend that capability to streams of blocks.
pub interface Block {
  fn BlockSize() -> int
  fn Decrypt(mut dst: Slice<byte>, src: Slice<byte>)
  fn Encrypt(mut dst: Slice<byte>, src: Slice<byte>)
}

/// A BlockMode represents a block cipher running in a block-based mode (CBC,
/// ECB etc).
pub interface BlockMode {
  fn BlockSize() -> int
  fn CryptBlocks(mut dst: Slice<byte>, src: Slice<byte>)
}

/// A Stream represents a stream cipher.
pub interface Stream {
  fn XORKeyStream(mut dst: Slice<byte>, src: Slice<byte>)
}

/// StreamReader wraps a [Stream] into an [io.Reader]. It calls XORKeyStream
/// to process each slice of data which passes through.
pub struct StreamReader {
  pub S: Option<Stream>,
  pub R: Option<io.Reader>,
}

/// StreamWriter wraps a [Stream] into an io.Writer. It calls XORKeyStream
/// to process each slice of data which passes through. If any [StreamWriter.Write]
/// call returns short then the StreamWriter is out of sync and must be discarded.
/// A StreamWriter has no internal buffering; [StreamWriter.Close] does not need
/// to be called to flush write data.
pub struct StreamWriter {
  pub S: Option<Stream>,
  pub W: Option<io.Writer>,
  pub Err: error,
}

impl StreamReader {
  fn Read(self, mut dst: Slice<byte>) -> Partial<int, error>
}

impl StreamWriter {
  /// Close closes the underlying Writer and returns its Close return value, if the Writer
  /// is also an io.Closer. Otherwise it returns nil.
  #[allow(unused_result)]
  fn Close(self) -> Result<(), error>

  fn Write(self, src: Slice<byte>) -> Partial<int, error>
}
