Signatures
**********

This chapter describes the digital signature schemes implemented in GNU Crypto. The package for all signature and related classes is gnu.crypto.sig. The following signature schemes are implemented:

  * DSS, the Digital Signature Standard, was standardized in 1994 by the National Institute of Standards and Technology in the Federal Information Processing Standards (FIPS) Publication 186 [FIPS186]. DSS uses the secure hash algorithm (SHA-1) internally, and produces a 160 bit signature.

  * RSA-PSS. This is a digital signature scheme based on the combination of the RSA algorithm with the Probabilistic Signature Scheme (PSS) encoding scheme. RSA was invented by Ron Rivest, Adi Shamir, and Leonard Adleman; the PSS encoding was developed by Mihir Bellare and Phillip Rogaway. During efforts to adopt RSA-PSS into the IEEE P1363a standards effort, certain adaptations to the original version of RSA-PSS were made by Mihir Bellare and Phillip Rogaway and also by Burt Kaliski (the editor of IEEE P1363a) to facilitate implementation and integration into existing protocols. [JoK00]

The ISignature Interface
========================

Figure 14: Signature class diagram

All digital signature schemes implement the ISignature interface, and support the following methods:

 -- Variable: java.lang.String SIGNER_KEY
     A property name in the attributes map that is passed to instances being prepared for signing. The value mapped by this key must be a java.security.PrivateKey that is appropriate for the instance's algorithm (e.g. an instance of DSS would require a subclass of java.security.interfaces.DSAPrivateKey).

 -- Variable: java.lang.String VERIFIER_KEY
     A property name in the attributes map that is passed to instances being prepared for verifying a signature. The value mapped by this key must be a java.security.PublicKey that is appropriate for the instance's algorithm, just as is the case with the signing key.

 -- Variable: java.lang.String SOURCE_OF_RANDOMNESS
     A property name in the attributes map that is passed to instances being prepared for use as either signers or verifiers. The value mapped must be an already-initialized instance of gnu.crypto.prng.IRandom.

 -- Function: void setupSign (java.util.Map ATTRIBUTES) throws java.lang.IllegalArgumentException
     Initializes this instance for signing. The ATTRIBUTES parameter must be a java.util.Map that has, at least, a mapping between the SIGNER_KEY property and the appropriate private key.

 -- Function: void setupVerify (java.util.Map ATTRIBUTES) throws java.lang.IllegalArgumentException
     Initializes this instance for verifying a signature. The ATTRIBUTES parameter must be a java.util.Map that has, at least, a mapping between the VERIFIER_KEY property and the appropriate public key.

 -- Function: void update (byte B) throws java.lang.IllegalStateException
     Update either the signing or verifying operation with the next byte in the message. This method will throw a java.lang.IllegalStateException if this instance has not been initialized for either signing or verifying.

 -- Function: void update (byte[] BUF, int OFF, int LEN) throws java.lang.IllegalStateException
     Update either the signing or verifying operation with the next LEN bytes of BUF, starting at OFFSET. This method will throw a java.lang.IllegalStateException if this instance has not been initialized for either signing or verifying.

 -- Function: java.lang.Object sign () throws java.lang.IllegalStateException
     Finishes a signing operation and returns the final signature. This method will throw a java.lang.IllegalStateException if this instance has not been initialized for signing.

 -- Function: boolean verify (java.lang.Object SIGNATURE) throws java.lang.IllegalStateException
     Finishes a verifying operation by checking if the argument, a native signature object, matches the expected signature. This methods returns true if the signature is valid, false otherwise. This method will throw a java.lang.IllegalStateException if this instance has not been initialized for verifying.

 -- Function: java.lang.String name ()
     Returns the canonical name of this instance's signature algorithm.

 -- Function: java.lang.Object clone ()
     Returns a copy of this signature object.

The SignatureFactory Class
==========================

Instances of ISignature can be retrieved with the class methods of the SignatureFactory class:

 -- Function: ISignature getInstance (java.lang.String NAME)
     Creates an instance of the signature scheme for NAME, or null if there is no such algorithm.

 -- Function: java.util.Set getNames ()
     Returns a set of the names (java.lang.String) of all available signature schemes.

The ISignatureCodec Interface
=============================

The ISignatureCodec interface defines methods for externalizing and de-externalizing native signature results, as would be returned by the ISignature.sign() method, or passed to ISignature.verify() method. The only format currently supported is the ``RAW'' codec, which is specific to GNU Crypto.

Each signature scheme implements its own raw codec. There is no factory for codecs, but rather you should create instances of

  * gnu.crypto.sig.dss.DSSSignatureRawCodec if you are reading or writing DSS signatures, or

  * gnu.crypto.sig.rsa.RSAPSSSignatureRawCodec if you are reading or writing RSA-PSS signatures.

Each of these classes has a zero-argument constructor, needs no initialization, and defines these methods:

 -- Function: java.lang.Object decodeSignature (byte[] ENCODED)
     Decodes a signature from the byte represention ENCODED, and returns the signature in the signature algorithm's native form. Implementations may throw an unchecked exception (such as java.lang.IlligalArgumentException) if the argument is improperly formatted.

 -- Function: byte[] encodeSignature (java.lang.Object SIGNATURE)
     Encodes a native signature to an external byte representation. Implementations may throw an unchecked exception (such as java.lang.IlligalArgumentException) if the argument is not of the algorithm's native signature type.

 -- Function: int getFormatID ()
     Returns the format identifier for this codec, such as RAW_FORMAT.

 -- Variable: int RAW_FORMAT
     Format identifier for GNU's ``raw'' codec.

Signature Example
=================

     ISignature dss = SignatureFactory.getInstance("DSS");
     Map attrib = new HashMap();
     attrib.put(ISignature.SIGNER_KEY, privateDsaKey);
     dss.setupSign(attrib);

     dss.update(message, 0, message.length);
     Object sig = dss.sign();

     ISignatureCodec codec = new DSSSignatureRawCodec();
     byte[] encoded = codec.encodeSignature(sig);

     Object sig2 = codec.decodeSignature(encoded);

     attrib.clear();
     attrib.put(ISignature.VERIFIER_KEY, publicDsaKey);
     dss.setupVerify(attrib);

     dss.update(message, 0, message.length);
     boolean valid = dss.verify(sig);

Figure 15: Signature sequence diagram