ds.ov2.bignat
Class RSA_exponent

java.lang.Object
  extended by ds.ov2.bignat.RSA_exponent
All Implemented Interfaces:
RSA_exponent_interface

public class RSA_exponent
extends Object
implements RSA_exponent_interface

Compute modular powers on the crypto coprocessor of the Java Card. This class wraps an RSA_NOPAD cipher and uses its public key encryption to compute exponents.

For a number of general topics see also the package description.

The interface is tailored towards applications where the modulus stays constant and the exponent might stay constant. Therefore the modulus must and the exponent can be set before computing the power.

Further, for compatibility with Montgomery multiplication the methods here take an extra offset argument, that must be equal to the number of montgomery digits used, which is, at the same time, the number of bytes that the used Bignat's are longer than the configured key size. Digits at index less than offset are always ignored for arguments. For results they are set to zero.

There are several limitations for using the RSA cipher on the card. Some of them are general, some might be card specific:

key size
The cipher works on a certain key size that must be set with either the allocating constructor RSA_exponent(short) or init_key. The modulus, the base, the result and the temporary in the methods set_modulus, set_exponent, power and fixed_power must be precisely as long as given by the key size after subtracting the Montgomery digits, whose number is given in the offset argument of all those methods.
permitted key sizes
The cards that I have access to permit key sizes between 512 and 1952 bit, ie. between 64 and 244 bytes. (NXP likes to print ``RSA up to 2048 bit'' on the backside of their cards, but, the longest key they accept is nevertheless 1952 bits.) Further, only key sizes divisible by 4 bytes (or 32 bits) are permitted. So 544 bit keys are OK, but 520 bit ones are not.
permitted moduli
The first byte of the moduls must not be zero. Otherwise the card hangs. Together with the restrictions on key sizes this means that you cannot use this class, if your exponent is, for instance, 520 bits long.
I have not observed any restrictions on the values of the bases and the exponents. In particular, one can compute the modulus by setting the exponent to 1. The cipher behaves strange if the public key is zero, but the code here works around this problem by testing all exponents for zero and returning 1 in that case.

The code of this class runs only on the card. See Fake_rsa_exponent for a host equivalent.

See Also:
Fake_rsa_exponent
CPP Preprocessing
This class uses the following cpp defines: PACKAGE, PUBLIC, JAVACARD_APPLET, TESTFRAME, JAVADOC
Execution Environment:
card
Author:
Hendrik Tews
Version:
$Revision: 1.22 $
Last Commit:
$Date: 2009-05-18 15:06:45 $ by $Author: tews $

Field Summary
private  Cipher cipher
          Cipher used for computing the modular powers.
private  boolean exponent_is_zero
          My JCOP cards and the jcop emulator do not compute a power when the public exponent is zero (they always return zero then).
private  RSAPublicKey key
          Public RSA key object for the modulus and the exponent.
 
Constructor Summary
RSA_exponent()
          Non-allocating constructor.
RSA_exponent(short key_byte_size)
          Allocating constructor.
 
Method Summary
 void allocate(short key_byte_size)
          Allocte internal data.
 void fixed_power(Bignat base, Bignat result, short offset)
          Modular power with preconfigured modulus and exponent.
 void init_key(short key_byte_size)
          Initialize the internal public RSA key.
 void power(Bignat base, Bignat exp, Bignat result, short offset)
          Modular power.
 void set_exponent(Bignat exp, Bignat temp, short offset)
          Initialize the exponent for subsequent use of this object with fixed_power.
 void set_modulus(Bignat mod, short offset)
          Set modulus.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

cipher

private Cipher cipher
Cipher used for computing the modular powers.


key

private RSAPublicKey key
Public RSA key object for the modulus and the exponent. The modulus stays constant, the exponent is updated when using power(ds.ov2.bignat.Bignat, ds.ov2.bignat.Bignat, ds.ov2.bignat.Bignat, short).


exponent_is_zero

private boolean exponent_is_zero
My JCOP cards and the jcop emulator do not compute a power when the public exponent is zero (they always return zero then). Therefore we have to remember if an exponent of zero has been set.

Constructor Detail

RSA_exponent

public RSA_exponent()
Non-allocating constructor. If this constructor is used the internal data structure must later be explicitely allocated with allocate.


RSA_exponent

public RSA_exponent(short key_byte_size)
Allocating constructor. Allocates the internal cipher and initializes the key with a key size of key_byte_size bytes. This key size determines the size of the Bignat arguments for all the other methods.

The constructor calls allocate internally. On objects created with this constructor allocate should be avoided. Different from allocate and init_key this constructor will change the key size if it is not one of the known working key sizes. First, the key size is rounded upwards to the next number divisible by 4. Then it is changed to fit into the interval between 64 and 244.

Querying the key size is currently not supported. Therefore it is probably not so a good idea to rely on the key size adaption.

Note that for some key sizes key initialization works, but then exponent initialization does always throw an exception. So normal termination of this constructor does not mean that the possibly adapted key size is supported.

Parameters:
key_byte_size - key size in bytes,
Throws:
ISOException - with reason Response_status.OV_RSA_KEY_FAILURE if a suitable key of the possibly adopted key size cannot be created.
ISOException - with reason Response_status.OV_RSA_NOPAD_CIPHER_FAILURE if the ALG_RSA_NOPAD cipher is not available.
Method Detail

init_key

public void init_key(short key_byte_size)
Initialize the internal public RSA key. The key is needed together with the cipher for doing encryption. The key is initialized to size key_byte_size bytes. This key size determins the size of the Bignat arguments for all the other methods.

Normally only called from within allocate, which can either be called directly or indirectly via the allocating constructor RSA_exponent(short).

For changing the key size this method can be called directly. However, this should only be done for testing purposes, because the old key becomes garbage.

Note that for some key sizes key initialization works, but then exponent initialization does always throw an exception. So normal termination of this method does not mean that the key size key_byte_size is supported.

Specified by:
init_key in interface RSA_exponent_interface
Parameters:
key_byte_size - the key size in bytes.
Throws:
ISOException - with reason Response_status.OV_RSA_KEY_FAILURE if a suitable key of this size cannot be created.

allocate

public void allocate(short key_byte_size)
Allocte internal data. Allocate the cipher and the key objects. The key is initialized to size key_byte_size with init_key. This key size determins the size of the Bignat arguments for all the other methods.

This method should only used once and only if the non-allocating constructor RSA_exponent() has been used to create this object. (The allocating constructor RSA_exponent(short) calls this method itself.)

Note that for some key sizes key initialization works, but then exponent initialization does always throw an exception. So normal termination of this method does not mean that the key size key_byte_size is supported.

Specified by:
allocate in interface RSA_exponent_interface
Parameters:
key_byte_size - key size in bytes
Throws:
ISOException - with reason Response_status.OV_RSA_KEY_FAILURE if a suitable key of this size cannot be created.
ISOException - with reason Response_status.OV_RSA_NOPAD_CIPHER_FAILURE if the ALG_RSA_NOPAD cipher is not available.

set_modulus

public void set_modulus(Bignat mod,
                        short offset)
Set modulus. Must be called before power or before set_exponent. Once set, a modulus is used for all subsequently computed exponents until it is changed via this method. The offset argument specifies the number of ditits that mod is longer than the configured key size. If offset is different from 0 all digits left of offset are assumed to be zero. For a modulus that is used with Montgomery multiplication use an offset of 2.

Specified by:
set_modulus in interface RSA_exponent_interface
Parameters:
mod - modulus, 2 bytes longer than the key size
offset - starting index of the most significant digit of the modulus
Throws:
ISOException - with reason Response_status.OV_RSA_MOD_FAILURE if the modulus has the wrong size

set_exponent

public void set_exponent(Bignat exp,
                         Bignat temp,
                         short offset)
Initialize the exponent for subsequent use of this object with fixed_power. This is advantageous if more than one power is computed with the same exponent, because exponent initializtion amounts for about 60% (for short keys sizes) to 30% (for long key sizes) of the total computation time.

The modulus must have been set with set_modulus before calling this method.

The temporary is used here to permit exponents which are shorter than the configured key size of the underlying cipher. The offset argument specifies the number of digits that temp is larger then the configured key size. For a temporary that is used with Montgomery multiplication use an offset of 2.

Specified by:
set_exponent in interface RSA_exponent_interface
Parameters:
exp - exponent
temp - temporary
offset - number of digits temp is longer than the configured key size
Throws:
ISOException - with reason Response_status.OV_RSA_EXP_FAILURE if setting the exponent fails (which I believe happens for invalid key sizes that are not reported as such when initiliazing the key)

fixed_power

public void fixed_power(Bignat base,
                        Bignat result,
                        short offset)
Modular power with preconfigured modulus and exponent. Sets result to base^exp mod modulus, where the modulus and exp must have been configured before with set_modulus and set_exponent, respectively. Note that set_modulus must always be called before set_exponent.

Using this method makes sense when more than one power is computed with the same modulus and exponent. Measurements show that initializing the modulus and the exponent amounts for about 60% (for short keys sizes) to 30% (for long key sizes) of the total computation time. This method is merely a wrapper around doFinal.

The modulus and the exponent must have been set before calling this method with set_modulus and set exponent, respectively. Note that set_modulus must always be called before set_exponent.

The argument offset specifies the number of digits that the base and the result are longer than the configured key size. For bases and results that are used with Montgomery multiplication use an offset of 2.

base and result must not be the same reference, otherwise the cipher may produce incorrect results.

Specified by:
fixed_power in interface RSA_exponent_interface
Parameters:
base -
result - reference for storing the result
offset - number of digits base and result is longer than the configured key size

power

public void power(Bignat base,
                  Bignat exp,
                  Bignat result,
                  short offset)
Modular power. Sets result to base^exp mod modulus, where the modulus must have been configured before with set_modulus. Same as set_exponent followed by fixed_power

The argument offset specifies the index of the most significant digits of base and result. If base and result are used with Montgomery multiplication the offset should be 2.

The exponent must fit into key size many bytes but can otherwise be arbitrarily long.

base and result must not be the same reference, because result the exponent is first copied into result to permit exponents shorter than key size. Moreover the cipher on the card does not permit them to be the same reference.

Specified by:
power in interface RSA_exponent_interface
Parameters:
base -
exp - exponent
result - reference for storing the result