ds.ov2.front
Class Signature

java.lang.Object
  extended by ds.ov2.util.Serializable_array
      extended by ds.ov2.front.Signature
All Implemented Interfaces:
APDU_Serializable

public class Signature
extends Serializable_array
implements APDU_Serializable

Signatures on blinded attribute expressions. This class only provides the storage for a signature. Any computation with the signature has to be done outside. During digest computation one should use hash_output_buf as output buffer. When digest computation is finished one has to call commit_hash(), which either does nothing or copies the restricted hash into hash.

Signature creation is done in RSA_squared_card.make_sig_hash() and RSA_squared_card.finish_signature and similar methods in RSA_plain_card and RSA_mont_card. Signature checking is done in Host_signature.check_signature.

This is a card data type. It is compatible with

A signature consists of a hash c and a number r such that c = H(A, r^v * (h * A) ^ -c), where H is a hash function, A is the blinded attribute expression, v is the public RSA exponent (see RSA_data.v and PTLS_rsa_parameters.v), and h is the public PTLS key (see RSA_data.ptls_key and PTLS_rsa_parameters.ptls_public_key). As you can see, the hash value c is considered as a number and takes part in the computation.

For simplicity the Montgomerizing applet does not demontgomerize the numbers in the resign protocol before feeding numbers to the hash function. This results in what I would call a montgomerized signature, that is a signature where one has to montgomerize the numbers before feeding them to the hash function in the signature check.

During resigning the applet needs to compute r * beta2 * beta1 ^ c * (h A)^ q. What is important here, is that the hash c is used as an exponent on the card. In the plain and the squared applets the power beta1 ^ c is computed with an RSA_exponent, that accepts a number of (almost) arbitrary size as exponent. In these two applets I use RSA_plain_card.double_small and, respectively, RSA_squared_card.double_small to hold the hash and pass it on to the RSA_exponent. Further, for the computation of q it is necessary to sum c + beta3, where beta3 is a random less than v. This sum is also computed in double_small.

Therefore in the plain and squareing applets the hash must fit into a number of twice the exponent size and there must further be enough room to add a number of exponent size. For the Java cards that we currently have the base size is restricted to 512 - 1952 bits, which, according to Lenstra (see Security_parameter), corresponds to an exponent size of 94 - 198 bits or 12 - 25 bytes. For the hash function H I use 160 bit SHA-1 (MessageDigest.ALG_SHA), which produces 20 byte hashes. Thus, if the exponent size is chosen according to Lenstra, the variable double_small is big enough.

For testing in the host test frames I however permit RSA key sizes below 512 bits. Then the double_small might not be big enough. In such cases (where security is broken anyways) I restrict the size of the hash to 2 * short_bignat_size -1 for the plain and the squaring applet, where short_bignat_size is the size of v. The restriction is done by using only the last bytes of the output of H. The computation of the hash size is done in Hash_size.hash_size. The hash of the required size is always stored in hash. For the output of H there is an additional byte array hash_output_buf. In the normal case, where the full output of H is used hash_output_buf is merely an alias of hash. If the hash size is restricted it is a separate array.

In the Montgomerizing applet I use two additional Vector's RSA_mont_card.temp_base_vec and RSA_mont_card.temp_exp_vec of size two to compute beta1 ^ c * (h A)^ q using simultaneous repeated squaring. Until now I have not found any hints on how big c and therefore q should be in relation with v. Therefore I decided to use the normal exponent size for the exponent vector for the computation of beta1 ^ c * (h A)^ q (which has the nice side effect that the two additional vectors are perfectly suited for computing beta2 ^ v * (h * A) ^ beta3 for the second hash input). Therefore, for the Montgomerizing applet the hash is restricted to the size of the exponent (the sum c + beta3 is still computed in double_small, so the hash can really be as long as the exponents). This means that for the Montgomerizing applet the full hash is only used for RSA key sizes greater than 1184 bits. For Java Card resigning takes already more than one hour for 512 bits in the Montgomerizing applet, so any secure RSA key sizes are out of reach any way. For smart phones this point might need to be reconsidered.

CPP Preprocessing
This class uses the following cpp defines: PACKAGE, PUBLIC, ASSERT, JAVACARD_APPLET
Execution Environment:
card
Author:
Hendrik Tews
Version:
$Revision: 1.11 $
Last Commit:
$Date: 2009-06-17 21:16:39 $ by $Author: tews $

Field Summary
(package private)  byte applet_id
          Value of the third constructor argument applet_id.
(package private)  APDU_byte_array hash
          The hash c.
(package private)  byte[] hash_output_buf
          Output buffer for the digest algorithm.
(package private)  Bignat number
          The number r.
private  APDU_Serializable[] serializable_contents
          Array of hash and number for get_array().
(package private)  short sig_long_size
          Value of the second constructor argument short_bignat_size.
(package private)  short sig_short_size
          Value of the first constructor argument short_bignat_size.
 
Constructor Summary
Signature(short short_bignat_size, short long_bignat_size, byte applet_id)
          Create a new Signature object.
 
Method Summary
(package private)  void commit_hash()
          Produce a properly sized hash value out of the data in hash_output_buf.
protected  APDU_Serializable[] get_array()
          Return serializable_contents in support for abstract Serializable_array.
 short get_length()
          Return 2 as effective size in support for abstract Serializable_array.
(package private)  void hash_into_bignat(Bignat b)
          Copies the hash value hash into a Bignat.
 boolean is_compatible_with(Object o)
          Compatibility check for the OV-chip protocol layer.
 
Methods inherited from class ds.ov2.util.Serializable_array
from_byte_array, size, to_byte_array
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface ds.ov2.util.APDU_Serializable
from_byte_array, size, to_byte_array
 

Field Detail

hash

APDU_byte_array hash
The hash c. Size is determined by Hash_size.hash_size.


number

Bignat number
The number r. Long bignat.


serializable_contents

private APDU_Serializable[] serializable_contents
Array of hash and number for get_array().


hash_output_buf

byte[] hash_output_buf
Output buffer for the digest algorithm. Either an alias of hash or a separate byte array. After filling it, commit_hash() must be called.


sig_short_size

final short sig_short_size
Value of the first constructor argument short_bignat_size. Available here for the stub code of the OV-chip protocol layer, to enable it to construct properly sized objects on the fly.


sig_long_size

final short sig_long_size
Value of the second constructor argument short_bignat_size. Available here for the stub code of the OV-chip protocol layer, to enable it to construct properly sized objects on the fly.


applet_id

final byte applet_id
Value of the third constructor argument applet_id. Available here for the stub code of the OV-chip protocol layer, to enable it to construct properly sized objects on the fly.

Constructor Detail

Signature

public Signature(short short_bignat_size,
                 short long_bignat_size,
                 byte applet_id)
Create a new Signature object. Sizes of internal numbers and buffers depend on the base and exponent size as well as on the applet (see discussion above and Hash_size).

Parameters:
short_bignat_size - size of the exponent bignats in bytes
long_bignat_size - size of the base bignats in bytes
applet_id - the applet ID
Method Detail

commit_hash

void commit_hash()
Produce a properly sized hash value out of the data in hash_output_buf. Does nothing if hash has size Hash_size.digest_output_size and hash_output_buf is an alias of hash. Otherwise copies the last bytes of hash_output_buf into hash.


hash_into_bignat

void hash_into_bignat(Bignat b)
Copies the hash value hash into a Bignat.

Asserts that the size of b is sufficient.

Parameters:
b - Bignat to copy the hash into

get_array

protected APDU_Serializable[] get_array()
Return serializable_contents in support for abstract Serializable_array.

Specified by:
get_array in class Serializable_array
Returns:
array of objects to (de-)serialize

get_length

public short get_length()
Return 2 as effective size in support for abstract Serializable_array.

Overrides:
get_length in class Serializable_array
Returns:
2

is_compatible_with

public boolean is_compatible_with(Object o)
Compatibility check for the OV-chip protocol layer. Signature is compatible with See the compatibility check explanations and also APDU_Serializable.is_compatible_with.

Specified by:
is_compatible_with in interface APDU_Serializable
Overrides:
is_compatible_with in class Serializable_array
Parameters:
o - actual argument or result
Returns:
true if this (the declared argument or result) is considered binary compatible with o.