// Generated by Lisette bindgen
// Source: crypto/rsa (Go stdlib)
// Go: 1.25.10
// Lisette: 0.3.0

import "go:crypto"
import "go:hash"
import "go:io"
import "go:math/big"

/// DecryptOAEP decrypts ciphertext using RSA-OAEP.
/// 
/// OAEP is parameterised by a hash function that is used as a random oracle.
/// Encryption and decryption of a given message must use the same hash function
/// and sha256.New() is a reasonable choice.
/// 
/// The random parameter is legacy and ignored, and it can be nil.
/// 
/// The label parameter must match the value given when encrypting. See
/// [EncryptOAEP] for details.
pub fn DecryptOAEP(
  hash: hash.Hash,
  random: io.Reader,
  priv: Ref<PrivateKey>,
  ciphertext: Slice<byte>,
  label: Slice<byte>,
) -> Result<Slice<byte>, error>

/// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS #1 v1.5.
/// The random parameter is legacy and ignored, and it can be nil.
/// 
/// Note that whether this function returns an error or not discloses secret
/// information. If an attacker can cause this function to run repeatedly and
/// learn whether each instance returned an error then they can decrypt and
/// forge signatures as if they had the private key. See
/// DecryptPKCS1v15SessionKey for a way of solving this problem.
pub fn DecryptPKCS1v15(
  random: io.Reader,
  priv: Ref<PrivateKey>,
  ciphertext: Slice<byte>,
) -> Result<Slice<byte>, error>

/// DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding
/// scheme from PKCS #1 v1.5. The random parameter is legacy and ignored, and it
/// can be nil.
/// 
/// DecryptPKCS1v15SessionKey returns an error if the ciphertext is the wrong
/// length or if the ciphertext is greater than the public modulus. Otherwise, no
/// error is returned. If the padding is valid, the resulting plaintext message
/// is copied into key. Otherwise, key is unchanged. These alternatives occur in
/// constant time. It is intended that the user of this function generate a
/// random session key beforehand and continue the protocol with the resulting
/// value.
/// 
/// Note that if the session key is too small then it may be possible for an
/// attacker to brute-force it. If they can do that then they can learn whether a
/// random value was used (because it'll be different for the same ciphertext)
/// and thus whether the padding was correct. This also defeats the point of this
/// function. Using at least a 16-byte key will protect against this attack.
/// 
/// This method implements protections against Bleichenbacher chosen ciphertext
/// attacks [0] described in RFC 3218 Section 2.3.2 [1]. While these protections
/// make a Bleichenbacher attack significantly more difficult, the protections
/// are only effective if the rest of the protocol which uses
/// DecryptPKCS1v15SessionKey is designed with these considerations in mind. In
/// particular, if any subsequent operations which use the decrypted session key
/// leak any information about the key (e.g. whether it is a static or random
/// key) then the mitigations are defeated. This method must be used extremely
/// carefully, and typically should only be used when absolutely necessary for
/// compatibility with an existing protocol (such as TLS) that is designed with
/// these properties in mind.
/// 
///   - [0] “Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption
///     Standard PKCS #1”, Daniel Bleichenbacher, Advances in Cryptology (Crypto '98)
///   - [1] RFC 3218, Preventing the Million Message Attack on CMS,
///     https://www.rfc-editor.org/rfc/rfc3218.html
pub fn DecryptPKCS1v15SessionKey(
  random: io.Reader,
  priv: Ref<PrivateKey>,
  ciphertext: Slice<byte>,
  key: Slice<byte>,
) -> Result<(), error>

/// EncryptOAEP encrypts the given message with RSA-OAEP.
/// 
/// OAEP is parameterised by a hash function that is used as a random oracle.
/// Encryption and decryption of a given message must use the same hash function
/// and sha256.New() is a reasonable choice.
/// 
/// The random parameter is used as a source of entropy to ensure that
/// encrypting the same message twice doesn't result in the same ciphertext.
/// Most applications should use [crypto/rand.Reader] as random.
/// 
/// The label parameter may contain arbitrary data that will not be encrypted,
/// but which gives important context to the message. For example, if a given
/// public key is used to encrypt two types of messages then distinct label
/// values could be used to ensure that a ciphertext for one purpose cannot be
/// used for another by an attacker. If not required it can be empty.
/// 
/// The message must be no longer than the length of the public modulus minus
/// twice the hash length, minus a further 2.
pub fn EncryptOAEP(
  hash: hash.Hash,
  random: io.Reader,
  pub_: Ref<PublicKey>,
  msg: Slice<byte>,
  label: Slice<byte>,
) -> Result<Slice<byte>, error>

/// EncryptPKCS1v15 encrypts the given message with RSA and the padding
/// scheme from PKCS #1 v1.5.  The message must be no longer than the
/// length of the public modulus minus 11 bytes.
/// 
/// The random parameter is used as a source of entropy to ensure that
/// encrypting the same message twice doesn't result in the same
/// ciphertext. Most applications should use [crypto/rand.Reader]
/// as random. Note that the returned ciphertext does not depend
/// deterministically on the bytes read from random, and may change
/// between calls and/or between versions.
/// 
/// WARNING: use of this function to encrypt plaintexts other than
/// session keys is dangerous. Use RSA OAEP in new protocols.
pub fn EncryptPKCS1v15(
  random: io.Reader,
  pub_: Ref<PublicKey>,
  msg: Slice<byte>,
) -> Result<Slice<byte>, error>

/// GenerateKey generates a random RSA private key of the given bit size.
/// 
/// If bits is less than 1024, [GenerateKey] returns an error. See the "[Minimum
/// key size]" section for further details.
/// 
/// Most applications should use [crypto/rand.Reader] as rand. Note that the
/// returned key does not depend deterministically on the bytes read from rand,
/// and may change between calls and/or between versions.
/// 
/// [Minimum key size]: https://pkg.go.dev/crypto/rsa#hdr-Minimum_key_size
pub fn GenerateKey(random: io.Reader, bits: int) -> Result<Ref<PrivateKey>, error>

/// GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit
/// size and the given random source.
/// 
/// Table 1 in "[On the Security of Multi-prime RSA]" suggests maximum numbers of
/// primes for a given bit size.
/// 
/// Although the public keys are compatible (actually, indistinguishable) from
/// the 2-prime case, the private keys are not. Thus it may not be possible to
/// export multi-prime private keys in certain formats or to subsequently import
/// them into other code.
/// 
/// This package does not implement CRT optimizations for multi-prime RSA, so the
/// keys with more than two primes will have worse performance.
/// 
/// Deprecated: The use of this function with a number of primes different from
/// two is not recommended for the above security, compatibility, and performance
/// reasons. Use [GenerateKey] instead.
/// 
/// [On the Security of Multi-prime RSA]: http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
pub fn GenerateMultiPrimeKey(random: io.Reader, nprimes: int, bits: int) -> Result<Ref<PrivateKey>, error>

/// SignPKCS1v15 calculates the signature of hashed using
/// RSASSA-PKCS1-V1_5-SIGN from RSA PKCS #1 v1.5.  Note that hashed must
/// be the result of hashing the input message using the given hash
/// function. If hash is zero, hashed is signed directly. This isn't
/// advisable except for interoperability.
/// 
/// The random parameter is legacy and ignored, and it can be nil.
/// 
/// This function is deterministic. Thus, if the set of possible
/// messages is small, an attacker may be able to build a map from
/// messages to signatures and identify the signed messages. As ever,
/// signatures provide authenticity, not confidentiality.
pub fn SignPKCS1v15(
  random: io.Reader,
  priv: Ref<PrivateKey>,
  hash: crypto.Hash,
  hashed: Slice<byte>,
) -> Result<Slice<byte>, error>

/// SignPSS calculates the signature of digest using PSS.
/// 
/// digest must be the result of hashing the input message using the given hash
/// function. The opts argument may be nil, in which case sensible defaults are
/// used. If opts.Hash is set, it overrides hash.
/// 
/// The signature is randomized depending on the message, key, and salt size,
/// using bytes from rand. Most applications should use [crypto/rand.Reader] as
/// rand.
pub fn SignPSS(
  rand: io.Reader,
  priv: Ref<PrivateKey>,
  hash: crypto.Hash,
  digest: Slice<byte>,
  opts: Ref<PSSOptions>,
) -> Result<Slice<byte>, error>

/// VerifyPKCS1v15 verifies an RSA PKCS #1 v1.5 signature.
/// hashed is the result of hashing the input message using the given hash
/// function and sig is the signature. A valid signature is indicated by
/// returning a nil error. If hash is zero then hashed is used directly. This
/// isn't advisable except for interoperability.
/// 
/// The inputs are not considered confidential, and may leak through timing side
/// channels, or if an attacker has control of part of the inputs.
pub fn VerifyPKCS1v15(
  pub_: Ref<PublicKey>,
  hash: crypto.Hash,
  hashed: Slice<byte>,
  sig: Slice<byte>,
) -> Result<(), error>

/// VerifyPSS verifies a PSS signature.
/// 
/// A valid signature is indicated by returning a nil error. digest must be the
/// result of hashing the input message using the given hash function. The opts
/// argument may be nil, in which case sensible defaults are used. opts.Hash is
/// ignored.
/// 
/// The inputs are not considered confidential, and may leak through timing side
/// channels, or if an attacker has control of part of the inputs.
pub fn VerifyPSS(
  pub_: Ref<PublicKey>,
  hash: crypto.Hash,
  digest: Slice<byte>,
  sig: Slice<byte>,
  opts: Ref<PSSOptions>,
) -> Result<(), error>

/// CRTValue contains the precomputed Chinese remainder theorem values.
pub struct CRTValue {
  pub Exp: Option<Ref<big.Int>>,
  pub Coeff: Option<Ref<big.Int>>,
  pub R: Option<Ref<big.Int>>,
}

/// OAEPOptions is an interface for passing options to OAEP decryption using the
/// crypto.Decrypter interface.
pub struct OAEPOptions {
  pub Hash: crypto.Hash,
  pub MGFHash: crypto.Hash,
  pub Label: Slice<byte>,
}

/// PKCS1v15DecryptOptions is for passing options to PKCS #1 v1.5 decryption using
/// the [crypto.Decrypter] interface.
pub struct PKCS1v15DecryptOptions {
  pub SessionKeyLen: int,
}

/// PSSOptions contains options for creating and verifying PSS signatures.
pub struct PSSOptions {
  pub SaltLength: int,
  pub Hash: crypto.Hash,
}

pub struct PrecomputedValues {
  pub Dp: Option<Ref<big.Int>>,
  pub Dq: Option<Ref<big.Int>>,
  pub Qinv: Option<Ref<big.Int>>,
  pub CRTValues: Slice<CRTValue>,
}

/// A PrivateKey represents an RSA key
pub struct PrivateKey {
  pub PublicKey: PublicKey,
  pub D: Option<Ref<big.Int>>,
  pub Primes: Slice<Option<Ref<big.Int>>>,
  pub Precomputed: PrecomputedValues,
}

/// A PublicKey represents the public part of an RSA key.
/// 
/// The values of N and E are not considered confidential, and may leak through
/// side channels, or could be mathematically derived from other public values.
pub struct PublicKey {
  pub N: Option<Ref<big.Int>>,
  pub E: int,
}

pub const PSSSaltLengthAuto = 0

pub const PSSSaltLengthEqualsHash = -1

/// ErrDecryption represents a failure to decrypt a message.
/// It is deliberately vague to avoid adaptive attacks.
pub var ErrDecryption: error

/// ErrMessageTooLong is returned when attempting to encrypt or sign a message
/// which is too large for the size of the key. When using [SignPSS], this can also
/// be returned if the size of the salt is too large.
pub var ErrMessageTooLong: error

/// ErrVerification represents a failure to verify a signature.
/// It is deliberately vague to avoid adaptive attacks.
pub var ErrVerification: error

impl PSSOptions {
  /// HashFunc returns opts.Hash so that [PSSOptions] implements [crypto.SignerOpts].
  fn HashFunc(self: Ref<PSSOptions>) -> crypto.Hash
}

impl PrivateKey {
  /// Decrypt decrypts ciphertext with priv. If opts is nil or of type
  /// *[PKCS1v15DecryptOptions] then PKCS #1 v1.5 decryption is performed. Otherwise
  /// opts must have type *[OAEPOptions] and OAEP decryption is done.
  fn Decrypt(
    self: Ref<PrivateKey>,
    rand: io.Reader,
    ciphertext: Slice<byte>,
    opts: crypto.DecrypterOpts,
  ) -> Result<Slice<byte>, error>

  /// Equal reports whether priv and x have equivalent values. It ignores
  /// Precomputed values.
  fn Equal(self: Ref<PrivateKey>, x: crypto.PrivateKey) -> bool

  /// Precompute performs some calculations that speed up private key operations
  /// in the future. It is safe to run on non-validated private keys.
  fn Precompute(self: Ref<PrivateKey>)

  /// Public returns the public key corresponding to priv.
  fn Public(self: Ref<PrivateKey>) -> crypto.PublicKey

  /// Sign signs digest with priv, reading randomness from rand. If opts is a
  /// *[PSSOptions] then the PSS algorithm will be used, otherwise PKCS #1 v1.5 will
  /// be used. digest must be the result of hashing the input message using
  /// opts.HashFunc().
  /// 
  /// This method implements [crypto.Signer], which is an interface to support keys
  /// where the private part is kept in, for example, a hardware module. Common
  /// uses should use the Sign* functions in this package directly.
  fn Sign(
    self: Ref<PrivateKey>,
    rand: io.Reader,
    digest: Slice<byte>,
    opts: crypto.SignerOpts,
  ) -> Result<Slice<byte>, error>

  /// Size returns the modulus size in bytes. Raw signatures and ciphertexts
  /// for or by this public key will have the same size.
  fn Size(self: Ref<PrivateKey>) -> int

  /// Validate performs basic sanity checks on the key.
  /// It returns nil if the key is valid, or else an error describing a problem.
  /// 
  /// It runs faster on valid keys if run after [PrivateKey.Precompute].
  fn Validate(self: Ref<PrivateKey>) -> Result<(), error>
}

impl PublicKey {
  /// Equal reports whether pub and x have the same value.
  fn Equal(self: Ref<PublicKey>, x: crypto.PublicKey) -> bool

  /// Size returns the modulus size in bytes. Raw signatures and ciphertexts
  /// for or by this public key will have the same size.
  fn Size(self: Ref<PublicKey>) -> int
}
