NAME

Crypt::RSA::Blind - Blind RSA signatures

VERSION

$Revision: 1.029 $
$Date: Sun Jun  8 21:48:54 EST 2025 $

SYNOPSIS

use Crypt::RSA::Blind;
use Try::Tiny;

my $rsab = new Crypt::RSA::Blind;

my ($pubkey, $seckey) = $rsab->keygen(Size => 4096);

my $msg = "Hello, world!";

# RSABSSA-PSS interface (RFC 9474)

my $slen = 48; # Salt length (in bytes). 0 for no salt.

my ($blinded_msg, $blinding) = $rsab->ssa_blind ( { PublicKey => $pubkey,
                                                    Message => $msg,
                                                    sLen => $slen } );

my $blind_sig = $rsab->ssa_blind_sign( { SecretKey => $seckey,
                                         BlindedMessage => $blinded_msg } );

my $sig = $rsab->ssa_finalize( { PublicKey => $pubkey,
                                 BlindSig => $blind_sig,
                                 Blinding => $blinding,
                                 Message => $msg,
                                 sLen => $slen } );

print "OK\n" if try { $rsab->pss_verify( { PublicKey => $pubkey,
                                           Signature => $sig,
                                           Message => $msg,
                                           sLen => $slen } ) };

# Use old API methods as wrappers for RSABSSA-PSS methods

$rsab->set_oldapi(1);     # Enable old API wrappers (default)

# Alternately, use old API methods as originally implemented

$rsab->set_oldapi(0);     # Disable old API wrappers (deprecated)

# Old interface

my $init = $rsab->init;

my $req = $rsab->request( Key => $pubkey,
                          Init => $init,
                          Message => $msg );

my $blindsig = $rsab->sign( Key => $seckey, Message => $req );

my $sig = $rsab->unblind( Key => $pubkey, Init => $init,
                          Signature => $blindsig );

print "OK\n" if $rsab->verify( Key => $pubkey, Message => $msg,
                               Signature => $sig );

METHODS

new

Creates and returns a new Crypt::RSA::Blind object.

keygen

Generates and returns an RSA key-pair of specified bitsize. This is a synonym for Crypt::RSA::Key::generate(). Arguments and return values are described in the Crypt::RSA::Key(3) manpage.

init

Generates and returns an initialization vector.

The RSA blind signature protocol doesn't require the use of initialization vectors. However, this module can use them to keep track of the blinding factor for different signing requests, so it is convenient to use initialization vectors when creating multiple interlaved signing requests.

When using initialization vectors, the vector should be passed as the 'Init' named argument to the ssa_blind() and ssa_finalize() methods (in the old deprecated interface, to the req(), and unblind() methods).

Alternately, you can keep track of the blinding factor for each request in your own code. In this case, you can supply the blinding factor as the 'Blinding' named argument to the ssa_finalize() method, instead of providing an initialization vector as the 'Init' argument to ssa_blind() and ssa_finalize().

Initialization vectors are not persistent across different invocations of a script, so if you need to call ssa_blind() and ssa_finalize() in different processes, you will need to record and persist the blinding factor yourself.

ssa_blind

Generate a blinding factor and a blinded message for signing.

Returns a list of two binary strings. The first is a the blinded message for signing, the second is the blinding factor used. Raises an exception on error.

Expects a hashref containing named arguments. The following arguments are required:

    PublicKey - The public key of the signer

    Message - The message to be blind signed

    sLen - The length (in bytes) of the salt to be used in the RSABSSA-PSS protocol. This can be 0 for no salt.

The following optional arguments can be provided:

    Init - An initialization vector from init()

    R_inv - The r_inv value as an integer, for test vector verification.

    Salt - A salt as a hex string without a leading '0x', for test vector verification.

ssa_blind_sign

Generate a blind signature.

Returns the blind signature as a binary string. Raises an exception on error.

Expects a hashref containing named arguments. The following arguments are required:

    SecretKey - The private key of the signer

    BlindedMessage - The blinded message from ssa_blind()

ssa_finalize

Unblind a blind signature and generate an RSASSA-PSS compatible signature.

Returns the signature as a binary string. Raises an exception on error.

Expects a hashref containing named arguments. The following arguments are required:

    PublicKey - The public key of the signer

    BlindSig - The blind signature from ssa_blindsign()

    Message - The message that was provided to ssa_blind()

    sLen - The lengh in bytes of the salt. 0 for no salt.

In addition, one of the following arguments is required:

    Init - The initialization vector that was provided to ssa_blind()

    Blinding - The blinding factor that was returned by ssa_blind()

pss_verify

Verify an RSABSSA-PSS signature.

Returns a true value if the signature verifies successfully. Raises an exception on error.

Expects a hashref containing named arguments. The following named arguments are required:

    PublicKey - The public key of the signer

    Signature - The blind signature

    Message - The message that was signed

    sLen - The lengh in bytes of the salt. 0 for no salt.

ssa_randomize

Takes a single required argument, the message to be signed, and returns a prepared message with a random prefix.

errstr

Returns the error message from the last failed method call. See ERROR HANDLING below for more details.

OLD API MODES

The methods under OLD API METHODS below are the original interface for this module. They continue to be available in two modes for backwards compatibility.

The first, recommended, and default mode for these methods is "compatibility mode", which can be set with:

$rsab->set_oldapi(1);     # Enable old API wrappers

In this mode, the old methods are wrappers around the RSABSSA-PSS methods described above. Code written with the old methods should work in this mode, and will use the updated implementation.

In the second mode the old methods invoke their original implementation. This mode can be enabled with:

$rsab->set_oldapi(0);     # Disable old API wrappers

This mode is deprecated as the old implementation predates RFC 9474 and isn't compliant with it.

While these original methods continue to be available, versions 1.020 and higher of this module use different accessor names than previous versions. This change is incompatible with code that uses the old accessors. See ACCESSORS below.

OLD API METHODS

request

Generates and returns a blind-signing request. The following named arguments are required:

    Init - The initialization vector from init()

    Key - The public key of the signer

    Message - The message to be blind signed

sign

Generates and returns a blind signature. The following named arguments are required:

    Key - The private key of the signer

    Message - The blind-signing request

unblind

Unblinds a blind signature and returns a verifiable signature. The following named arguments are required:

    Init - The initialization vector from init()

    Key - The public key of the signer

    Signature - The blind signature

verify

Verify a signature. The following named arguments are required:

    Key - The public key of the signer

    Signature - The blind signature

    Message - The message that was signed

ACCESSORS

Accessors can be used to query or set the value of an object property. Readers are prefixed with "get_". Writers are prefixed with "set_" and take a single argument, to set the property to a specific value.

Version 1.012 and older of this module used different accessor names and didn't use the get_ and set_ prefixes. Code that uses the old accessors will need to be updated to use the new ones.

get_hash_algorithm / set_hash_algorithm

The name of the hashing algorithm to be used. Only SHA variants are supported. The default is 'SHA384'.

get_mgf_hash_algorithm / set_mgf_hash_algorithm

The name of the hashing algorithm to be used in the MGF1 function. Only SHA variants are supported. The default is 'SHA384'.

get_initsize / set_initsize

The bitsize of the init vector. Default is 128.

get_hashsize / set_hashsize

The bitsize of the full-domain hash that will be generated from the message to be blind-signed. Default is 768. This property is only relevant to the old deprecated implementation.

get_blindsize / set_blindsize

The bitsize of the blinding factor. Default is 512. This property is only relevant to the old deprecated implementation.

get_oldapi / set_oldapi

Enable / disable compatibility mode for the original Crypt::RSA::Blind API to wrap the RSABSSA-PSS methods. set_oldapi(1) enables wrapping RSABSSA-PSS in the old API methods. set_oldapi(0) disables wrapping and uses the original implementation for the original methods. This mode is deprecated.

ERROR HANDLING

Crypt::RSA::Blind relies on Crypt::RSA, which uses an error handling method implemented in Crypt::RSA::Errorhandler. When a method fails it returns undef and saves the error message. This error message is available to the caller through the errstr() method. For more details see the Crypt::RSA::Errorhandler(3) manpage.

Other than keygen(), only the "old API" methods of Crypt::RSA::Blind report errors this way, when operating with their original implementation. See OLD API MODES above.

The ssa_* methods and pss_verify() do not use the above error reporting method. They raise an exception on error. As do the "old API" methods when operating in compatibility mode (see OLD API MODES above).

AUTHOR

Ashish Gulhati, <crypt-rsab at hash.neo.email>

BUGS

Please report any bugs or feature requests to bug-crypt-rsa-blind at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Crypt-RSA-Blind. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

COPYRIGHT

Copyright (c) Ashish Gulhati.

LICENSE

This software package is Open Software; you can use, redistribute, and/or modify it under the terms of the Open Artistic License 4.0.

Please see the LICENSE file included with this package, or visit http://www.opensoftware.ca/oal40.txt, for the full license terms, and ensure that the license grant applies to you before using or modifying this software. By using or modifying this software, you indicate your agreement with the license terms.