///|
/// Verifies an RSASSA-PKCS1-v1_5 signature over a SHA-256 digest.
///
/// `digest` is the 32-byte SHA-256 of the signed content; the caller hashes,
/// which lets a large artifact be streamed rather than held in memory.
/// `signature` is the raw big-endian signature, exactly `key.size()` bytes.
///
/// Returns `true` only for a signature that verifies. Every other outcome —
/// wrong length, out-of-range signature, malformed padding, wrong digest — is
/// `false`. Verification deliberately cannot raise: a caller that distinguished
/// "invalid" from "failed to check" would eventually treat one as the other,
/// and this function decides whether foreign code is allowed to run.
pub fn verify_pkcs1_sha256(
  key : PublicKey,
  digest : Bytes,
  signature : Bytes,
) -> Bool {
  if digest.length() != sha256_digest_length {
    return false
  }

  // RFC 8017 section 8.2.2 step 1: the signature is `k` bytes, always. A
  // shorter signature is not zero-extended, because accepting several encodings
  // of one value is how signature malleability starts.
  if signature.length() != key.size {
    return false
  }
  let representative = @bigint.BigInt::from_octets(signature[:])

  // RSAVP1 step 1: reject s outside [0, n-1]. `from_octets` cannot produce a
  // negative value, so only the upper bound needs a test.
  if representative.compare(key.modulus) >= 0 {
    return false
  }
  let encoded = representative.pow(key.exponent, modulus=key.modulus)

  // I2OSP with an explicit width check. `to_octets(length=)` left-pads a short
  // value but does not truncate a long one, so the returned length is the only
  // reliable evidence that the result fits in `k` bytes.
  let encoded_bytes = encoded.to_octets(length=key.size)
  if encoded_bytes.length() != key.size {
    return false
  }
  match encode_pkcs1_sha256(digest, key.size) {
    None => false
    Some(expected) => bytes_equal_no_early_exit(encoded_bytes, expected)
  }
}