proton_rsa

    RSASSA-PKCS1-v1_5 signature verification over SHA-256.

    rsa
    pkcs1
    signature
    verification
    Download zip
    Version
    0.3.4
    License
    Apache-2.0
    Last updated
    2 days ago
    Downloads
    16K

    #moonbit-community/proton_rsa

    RSASSA-PKCS1-v1_5 signature verification over SHA-256, in pure MoonBit.

    This package exists to verify Proton update manifests and artifacts.

    #Scope

    Verification only, using SHA-256. Key generation and signing are not provided.

    #Use

    let key = @rsa.PublicKey::parse("rsa-sha256:<modulus hex>:<exponent hex>")
    let digest = compute_sha256_of_the_artifact()
    if @rsa.verify_pkcs1_sha256(key, digest, signature) {
    // The signature is valid.
    }

    verify_pkcs1_sha256 takes a digest rather than the signed content, so a large artifact can be streamed through a hash instead of being held in memory.

    #Validation

    Verification returns false for invalid signatures. Signature length must equal the modulus length. Public keys require a modulus of at least 2048 bits without a leading zero byte and an odd exponent of at least 3, smaller than the modulus.

    #Trust

    It verifies a signature against a key it is given. It has nothing to say about where that key came from, whether the key is still trusted, or whether the signed version is newer than the running one. Key custody, rotation, and rollback protection belong to the caller.

    KeyError

    pub(all) suberror KeyError {
    UnknownAlgorithm(tag~ : String)
    Malformed(detail~ : String)
    NonCanonicalModulus
    ModulusTooSmall(bits~ : Int, minimum~ : Int)
    InvalidExponent(detail~ : String)
    } derive(Eq,
    Debug
    )

    A trusted public key could not be decoded.

    Every variant describes a defect in configuration, not in a signature. Signature verification itself never raises: it answers with a boolean, so that no caller can mistake an error path for a successful check.

    KeyError::equal

    fn KeyError::equal(KeyError, KeyError) -> Bool

    KeyError::message

    fn KeyError::message(self : KeyError) -> String

    KeyError::not_equal

    fn KeyError::not_equal(x : KeyError, y : KeyError) -> Bool

    KeyError::output

    fn KeyError::output(self : KeyError, logger : &Logger) -> Unit

    KeyError::to_repr

    KeyError::to_string

    fn KeyError::to_string(self : KeyError) -> String

    PublicKey

    pub struct PublicKey {
    modulus :
    BigInt

    exponent :
    BigInt

    size : Int
    }

    An RSA public key that verifies RSASSA-PKCS1-v1_5 signatures over SHA-256.

    PublicKey::bits

    fn PublicKey::bits(self : PublicKey) -> Int

    Returns the modulus length in bits.

    PublicKey::parse

    fn PublicKey::parse(text : String) -> PublicKey raise KeyError

    Parses a trusted public key.

    The encoding is rsa-sha256:<modulus hex>:<exponent hex>, big-endian and unsigned. The algorithm tag is part of the stored key so that migrating to a different scheme later does not require a release that existing installations are unable to accept.

    PublicKey::size

    fn PublicKey::size(self : PublicKey) -> Int

    Returns the modulus length in bytes.

    minimum_modulus_bits

    let minimum_modulus_bits : Int

    The smallest modulus this package will accept.

    1024-bit RSA is considered broken for signatures and 2048 is the current floor in every serious guideline. Refusing a short key is a security control in its own right: a key that is too small verifies signatures perfectly well and offers no protection.

    sha256_digest_length

    let sha256_digest_length : Int

    Length of a SHA-256 digest in bytes.

    verify_pkcs1_sha256

    fn verify_pkcs1_sha256(key : PublicKey, digest : Bytes, signature : Bytes) -> Bool

    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.