Imported GNU Classpath 0.90

Imported GNU Classpath 0.90
       * scripts/makemake.tcl: Set gnu/java/awt/peer/swing to ignore.
       * gnu/classpath/jdwp/VMFrame.java (SIZE): New constant.
       * java/lang/VMCompiler.java: Use gnu.java.security.hash.MD5.
       * java/lang/Math.java: New override file.
       * java/lang/Character.java: Merged from Classpath.
       (start, end): Now 'int's.
       (canonicalName): New field.
       (CANONICAL_NAME, NO_SPACES_NAME, CONSTANT_NAME): New constants.
       (UnicodeBlock): Added argument.
       (of): New overload.
       (forName): New method.
       Updated unicode blocks.
       (sets): Updated.
       * sources.am: Regenerated.
       * Makefile.in: Likewise.

From-SVN: r111942
This commit is contained in:
Mark Wielaard
2006-03-10 21:46:48 +00:00
parent 27079765d0
commit 8aa540d2f7
1367 changed files with 188789 additions and 22762 deletions
@@ -0,0 +1,374 @@
/* Properties.java -- run-time configuration properties.
Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.PropertyPermission;
/**
* <p>A global object containing build-specific properties that affect the
* behaviour of the generated binaries from this library.</p>
*/
public final class Properties
{
// Debugging methods and variables
// -------------------------------------------------------------------------
private static final String NAME = "Properties";
private static final boolean DEBUG = false;
// private static final int debuglevel = 9;
private static final PrintWriter err = new PrintWriter(System.out, true);
private static void debug(final String s)
{
err.println(">>> " + NAME + ": " + s);
}
// Constants and variables
// -------------------------------------------------------------------------
public static final String VERSION = "gnu.crypto.version";
public static final String PROPERTIES_FILE = "gnu.crypto.properties.file";
public static final String REPRODUCIBLE_PRNG = "gnu.crypto.with.reproducible.prng";
public static final String CHECK_WEAK_KEYS = "gnu.crypto.with.check.for.weak.keys";
public static final String DO_RSA_BLINDING = "gnu.crypto.with.rsa.blinding";
private static final String TRUE = Boolean.TRUE.toString();
private static final String FALSE = Boolean.FALSE.toString();
private static final HashMap props = new HashMap();
private static Properties singleton = null;
private boolean reproducible = false;
private boolean checkForWeakKeys = true;
private boolean doRSABlinding = true;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial constructor to enforce Singleton pattern. */
private Properties()
{
super();
init();
}
// Class methods
// -------------------------------------------------------------------------
/**
* <p>Returns the string representation of the library global configuration
* property with the designated <code>key</code>.</p>
*
* @param key the case-insensitive, non-null and non-empty name of a
* configuration property.
* @return the string representation of the designated property, or
* <code>null</code> if such property is not yet set, or <code>key</code> is
* empty.
*/
public static final synchronized String getProperty(String key)
{
if (key == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new PropertyPermission(key, "read"));
key = key.trim().toLowerCase();
if ("".equals(key))
return null;
return (String) props.get(key);
}
/**
* <p>Sets the value of a designated library global configuration property,
* to a string representation of what should be a legal value.</p>
*
* @param key the case-insensitive, non-null and non-empty name of a
* configuration property.
* @param value the non-null, non-empty string representation of a legal
* value of the configuration property named by <code>key</code>.
*/
public static final synchronized void setProperty(String key, String value)
{
if (key == null || value == null)
return;
key = key.trim().toLowerCase();
if ("".equals(key))
return;
if (key.equals(VERSION))
return;
value = value.trim();
if ("".equals(value))
return;
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new PropertyPermission(key, "write"));
if (key.equals(REPRODUCIBLE_PRNG)
&& (value.equalsIgnoreCase(TRUE) || value.equalsIgnoreCase(FALSE)))
setReproducible(Boolean.valueOf(value).booleanValue());
else if (key.equals(CHECK_WEAK_KEYS)
&& (value.equalsIgnoreCase(TRUE) || value.equalsIgnoreCase(FALSE)))
setCheckForWeakKeys(Boolean.valueOf(value).booleanValue());
else if (key.equals(DO_RSA_BLINDING)
&& (value.equalsIgnoreCase(TRUE) || value.equalsIgnoreCase(FALSE)))
setDoRSABlinding(Boolean.valueOf(value).booleanValue());
else
props.put(key, value);
}
/**
* <p>A convenience method that returns, as a boolean, the library global
* configuration property indicating if the default Pseudo Random Number
* Generator produces, or not, the same bit stream when instantiated.</p>
*
* @return <code>true</code> if the default PRNG produces the same bit stream
* with every VM instance. Returns <code>false</code> if the default PRNG is
* seeded with the time of day of its first invocation.
*/
public static final synchronized boolean isReproducible()
{
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new PropertyPermission(REPRODUCIBLE_PRNG, "read"));
return instance().reproducible;
}
/**
* <p>A convenience method that returns, as a boolean, the library global
* configuration property indicating if the implementations of symmetric
* key block ciphers check, or not, for possible/potential weak and semi-weak
* keys that may be produced in the course of generating round encryption
* and/or decryption keys.</p>
*
* @return <code>true</code> if the cipher implementations check for weak and
* semi-weak keys. Returns <code>false</code> if the cipher implementations
* do not check for weak or semi-weak keys.
*/
public static final synchronized boolean checkForWeakKeys()
{
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new PropertyPermission(CHECK_WEAK_KEYS, "read"));
return instance().checkForWeakKeys;
}
/**
* <p>A convenience method that returns, as a boolean, the library global
* configuration property indicating if RSA decryption (RSADP primitive),
* does, or not, blinding against timing attacks.</p>
*
* @return <code>true</code> if the RSA decryption primitive includes a
* blinding operation. Returns <code>false</code> if the RSA decryption
* primitive does not include the additional blinding operation.
*/
public static final synchronized boolean doRSABlinding()
{
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new PropertyPermission(DO_RSA_BLINDING, "read"));
return instance().doRSABlinding;
}
/**
* <p>A convenience method to set the global property for reproducibility of
* the default PRNG bit stream output.</p>
*
* @param value if <code>true</code> then the default PRNG bit stream output
* is the same with every invocation of the VM.
*/
public static final synchronized void setReproducible(final boolean value)
{
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new PropertyPermission(REPRODUCIBLE_PRNG, "write"));
instance().reproducible = value;
props.put(REPRODUCIBLE_PRNG, String.valueOf(value));
}
/**
* <p>A convenience method to set the global property for checking for weak
* and semi-weak cipher keys.</p>
*
* @param value if <code>true</code> then the cipher implementations will
* invoke additional checks for weak and semi-weak key values that may get
* generated.
*/
public static final synchronized void setCheckForWeakKeys(final boolean value)
{
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new PropertyPermission(CHECK_WEAK_KEYS, "write"));
instance().checkForWeakKeys = value;
props.put(CHECK_WEAK_KEYS, String.valueOf(value));
}
/**
* <p>A convenience method to set the global property fo adding a blinding
* operation when executing the RSA decryption primitive.</p>
*
* @param value if <code>true</code> then the code for performing the RSA
* decryption primitive will include a blinding operation.
*/
public static final synchronized void setDoRSABlinding(final boolean value)
{
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new PropertyPermission(DO_RSA_BLINDING, "write"));
instance().doRSABlinding = value;
props.put(DO_RSA_BLINDING, String.valueOf(value));
}
private static final synchronized Properties instance()
{
if (singleton == null)
singleton = new Properties();
return singleton;
}
// Instance methods
// -------------------------------------------------------------------------
private void init()
{
// default values
props.put(REPRODUCIBLE_PRNG, (reproducible ? "true" : "false"));
props.put(CHECK_WEAK_KEYS, (checkForWeakKeys ? "true" : "false"));
props.put(DO_RSA_BLINDING, (doRSABlinding ? "true" : "false"));
// 1. allow site-wide override by reading a properties file
String propFile = null;
try
{
propFile = (String) AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
return System.getProperty(PROPERTIES_FILE);
}
});
}
catch (SecurityException se)
{
if (DEBUG)
debug("Reading property " + PROPERTIES_FILE
+ " not allowed. Ignored.");
}
if (propFile != null)
{
try
{
final java.util.Properties temp = new java.util.Properties();
final FileInputStream fin = new FileInputStream(propFile);
temp.load(fin);
temp.list(System.out);
props.putAll(temp);
}
catch (IOException ioe)
{
if (DEBUG)
debug("IO error reading " + propFile + ": " + ioe.getMessage());
}
catch (SecurityException se)
{
if (DEBUG)
debug("Security error reading " + propFile + ": "
+ se.getMessage());
}
}
// 2. allow vm-specific override by allowing -D options in launcher
handleBooleanProperty(REPRODUCIBLE_PRNG);
handleBooleanProperty(CHECK_WEAK_KEYS);
handleBooleanProperty(DO_RSA_BLINDING);
// re-sync the 'known' properties
reproducible = new Boolean((String) props.get(REPRODUCIBLE_PRNG)).booleanValue();
checkForWeakKeys = new Boolean((String) props.get(CHECK_WEAK_KEYS)).booleanValue();
doRSABlinding = new Boolean((String) props.get(DO_RSA_BLINDING)).booleanValue();
// This does not change.
props.put(VERSION, Registry.VERSION_STRING);
}
private void handleBooleanProperty(final String name)
{
String s = null;
try
{
s = System.getProperty(name);
}
catch (SecurityException x)
{
if (DEBUG)
debug("SecurityManager forbids reading system properties. Ignored");
}
if (s != null)
{
s = s.trim().toLowerCase();
// we have to test for explicit "true" or "false". anything else may
// hide valid value set previously
if (s.equals(TRUE) || s.equals(FALSE))
{
if (DEBUG)
debug("Setting " + name + " to '" + s + "'");
props.put(name, s);
}
else
{
if (DEBUG)
debug("Invalid value for -D" + name + ": " + s + ". Ignored");
}
}
}
}
@@ -0,0 +1,455 @@
/* Registry.java --
Copyright (C) 2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security;
/**
* A placeholder for <i>names</i> and <i>literals</i> used throughout this
* library.
*/
public interface Registry
{
// Constants
// -------------------------------------------------------------------------
/** The name of our Providers. */
String GNU_SECURITY = "GNU";
String GNU_CRYPTO = "GNU-CRYPTO";
String GNU_SASL = "GNU-SASL";
/** Our version number. */
String VERSION_STRING = "2.1.0";
// Names of properties to use in Maps when initialising primitives .........
// Symmetric block cipher algorithms and synonyms...........................
String ANUBIS_CIPHER = "anubis";
String BLOWFISH_CIPHER = "blowfish";
String DES_CIPHER = "des";
String KHAZAD_CIPHER = "khazad";
String RIJNDAEL_CIPHER = "rijndael";
String SERPENT_CIPHER = "serpent";
String SQUARE_CIPHER = "square";
String TRIPLEDES_CIPHER = "tripledes";
String TWOFISH_CIPHER = "twofish";
String CAST5_CIPHER = "cast5";
String NULL_CIPHER = "null";
/** AES is synonymous to Rijndael for 128-bit block size only. */
String AES_CIPHER = "aes";
/** TripleDES is also known as DESede. */
String DESEDE_CIPHER = "desede";
/** CAST5 is also known as CAST-128. */
String CAST128_CIPHER = "cast128";
String CAST_128_CIPHER = "cast-128";
// Message digest algorithms and synonyms...................................
String WHIRLPOOL_HASH = "whirlpool";
String RIPEMD128_HASH = "ripemd128";
String RIPEMD160_HASH = "ripemd160";
String SHA160_HASH = "sha-160";
String SHA256_HASH = "sha-256";
String SHA384_HASH = "sha-384";
String SHA512_HASH = "sha-512";
String TIGER_HASH = "tiger";
String HAVAL_HASH = "haval";
String MD5_HASH = "md5";
String MD4_HASH = "md4";
String MD2_HASH = "md2";
/** RIPEMD-128 is synonymous to RIPEMD128. */
String RIPEMD_128_HASH = "ripemd-128";
/** RIPEMD-160 is synonymous to RIPEMD160. */
String RIPEMD_160_HASH = "ripemd-160";
/** SHA-1 is synonymous to SHA-160. */
String SHA_1_HASH = "sha-1";
/** SHA1 is synonymous to SHA-160. */
String SHA1_HASH = "sha1";
/** SHA is synonymous to SHA-160. */
String SHA_HASH = "sha";
// Symmetric block cipher modes of operations...............................
/** Electronic CodeBook mode. */
String ECB_MODE = "ecb";
/** Counter (NIST) mode. */
String CTR_MODE = "ctr";
/** Integer Counter Mode (David McGrew). */
String ICM_MODE = "icm";
/** Output Feedback Mode (NIST). */
String OFB_MODE = "ofb";
/** Cipher block chaining mode (NIST). */
String CBC_MODE = "cbc";
/** Cipher feedback mode (NIST). */
String CFB_MODE = "cfb";
/** Authenticated-Encrypted mode. */
String EAX_MODE = "eax";
// Padding scheme names and synonyms........................................
/** PKCS#7 padding scheme. */
String PKCS7_PAD = "pkcs7";
/** Trailing Bit Complement padding scheme. */
String TBC_PAD = "tbc";
/** EME-PKCS1-v1_5 padding as described in section 7.2 in RFC-3447. */
String EME_PKCS1_V1_5_PAD = "eme-pkcs1-v1.5";
/** SSLv3 padding scheme. */
String SSL3_PAD = "ssl3";
/** TLSv1 padding scheme. */
String TLS1_PAD = "tls1";
// Pseudo-random number generators..........................................
/** (Apparently) RC4 keystream PRNG. */
String ARCFOUR_PRNG = "arcfour";
/** We use "rc4" as an alias for "arcfour". */
String RC4_PRNG = "rc4";
/** PRNG based on David McGrew's Integer Counter Mode. */
String ICM_PRNG = "icm";
/** PRNG based on a designated hash function. */
String MD_PRNG = "md";
/** PRNG based on UMAC's Key Derivation Function. */
String UMAC_PRNG = "umac-kdf";
/**
* PRNG based on PBKDF2 from PKCS #5 v.2. This is suffixed with the name
* of a MAC to be used as a PRF.
*/
String PBKDF2_PRNG_PREFIX = "pbkdf2-";
/** The continuously-seeded pseudo-random number generator. */
String CSPRNG_PRNG = "csprng";
/** The Fortuna PRNG. */
String FORTUNA_PRNG = "fortuna";
/** The Fortuna generator PRNG. */
String FORTUNA_GENERATOR_PRNG = "fortuna-generator";
// Asymmetric keypair generators............................................
String DSS_KPG = "dss";
String RSA_KPG = "rsa";
String DH_KPG = "dh";
String SRP_KPG = "srp";
/** DSA is synonymous to DSS. */
String DSA_KPG = "dsa";
// Signature-with-appendix schemes..........................................
String DSS_SIG = "dss";
String RSA_SIG_PREFIX = "rsa-";
String RSA_PSS_ENCODING = "pss";
String RSA_PSS_SIG = RSA_SIG_PREFIX + RSA_PSS_ENCODING;
String RSA_PKCS1_V1_5_ENCODING = "pkcs1-v1.5";
String RSA_PKCS1_V1_5_SIG = RSA_SIG_PREFIX + RSA_PKCS1_V1_5_ENCODING;
/** DSA is synonymous to DSS. */
String DSA_SIG = "dsa";
// Key agreement protocols .................................................
String DH_KA = "dh";
String ELGAMAL_KA = "elgamal";
String SRP6_KA = "srp6";
String SRP_SASL_KA = "srp-sasl";
String SRP_TLS_KA = "srp-tls";
// Keyed-Hash Message Authentication Code ..................................
/** Name prefix of every HMAC implementation. */
String HMAC_NAME_PREFIX = "hmac-";
// Other MAC algorithms ....................................................
/** The One-key CBC MAC. */
String OMAC_PREFIX = "omac-";
/** Message Authentication Code using Universal Hashing (Ted Krovetz). */
String UHASH32 = "uhash32";
String UMAC32 = "umac32";
/** The Truncated Multi-Modular Hash Function -v1 (David McGrew). */
String TMMH16 = "tmmh16";
// String TMMH32 = "tmmh32";
// Format IDs used to identify how we externalise asymmetric keys ..........
// fully-qualified names of the supported codecs
String RAW_ENCODING = "gnu.crypto.raw.format";
String X509_ENCODING = "gnu.crypto.x509.format";
String PKCS8_ENCODING = "gnu.crypto.pkcs8.format";
String ASN1_ENCODING = "gnu.crypto.asn1.format";
// short names of the same. used by JCE adapters
String RAW_ENCODING_SHORT_NAME = "RAW";
String X509_ENCODING_SORT_NAME = "X.509";
String PKCS8_ENCODING_SHORT_NAME = "PKCS#8";
String ASN1_ENCODING_SHORT_NAME = "ASN.1";
// unique identifiers of the same
int RAW_ENCODING_ID = 1;
int X509_ENCODING_ID = 2;
int PKCS8_ENCODING_ID = 3;
int ASN1_ENCODING_ID = 4;
// OID strings used in encoding/decoding keys
String DSA_OID_STRING = "1.2.840.10040.4.1";
String RSA_OID_STRING = "1.2.840.113549.1.1.1";
String DH_OID_STRING = "1.2.840.10046.2.1";
// Magic bytes we generate/expect in externalised asymmetric keys ..........
// the four bytes represent G (0x47) for GNU, 1 (0x01) for Raw format,
// D (0x44) for DSS, R (0x52) for RSA, H (0x48) for Diffie-Hellman, or S
// (0x53) for SRP-6, and finally P (0x50) for Public, p (0x70) for private,
// or S (0x53) for signature.
byte[] MAGIC_RAW_DSS_PUBLIC_KEY = new byte[] { 0x47, RAW_ENCODING_ID, 0x44,
0x50 };
byte[] MAGIC_RAW_DSS_PRIVATE_KEY = new byte[] { 0x47, RAW_ENCODING_ID, 0x44,
0x70 };
byte[] MAGIC_RAW_DSS_SIGNATURE = new byte[] { 0x47, RAW_ENCODING_ID, 0x44,
0x53 };
byte[] MAGIC_RAW_RSA_PUBLIC_KEY = new byte[] { 0x47, RAW_ENCODING_ID, 0x52,
0x50 };
byte[] MAGIC_RAW_RSA_PRIVATE_KEY = new byte[] { 0x47, RAW_ENCODING_ID, 0x52,
0x70 };
byte[] MAGIC_RAW_RSA_PSS_SIGNATURE = new byte[] { 0x47, RAW_ENCODING_ID,
0x52, 0x53 };
byte[] MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE = new byte[] { 0x47, RAW_ENCODING_ID,
0x52, 0x54 };
byte[] MAGIC_RAW_DH_PUBLIC_KEY = new byte[] { 0x47, RAW_ENCODING_ID, 0x48,
0x50 };
byte[] MAGIC_RAW_DH_PRIVATE_KEY = new byte[] { 0x47, RAW_ENCODING_ID, 0x48,
0x70 };
byte[] MAGIC_RAW_SRP_PUBLIC_KEY = new byte[] { 0x47, RAW_ENCODING_ID, 0x53,
0x50 };
byte[] MAGIC_RAW_SRP_PRIVATE_KEY = new byte[] { 0x47, RAW_ENCODING_ID, 0x53,
0x70 };
// SASL Property names .....................................................
String SASL_PREFIX = "gnu.crypto.sasl";
/** Name of username property. */
String SASL_USERNAME = SASL_PREFIX + ".username";
/** Name of password property. */
String SASL_PASSWORD = SASL_PREFIX + ".password";
/** Name of authentication information provider packages. */
String SASL_AUTH_INFO_PROVIDER_PKGS = SASL_PREFIX
+ ".auth.info.provider.pkgs";
/** SASL authorization ID. */
String SASL_AUTHORISATION_ID = SASL_PREFIX + ".authorisation.ID";
/** SASL protocol. */
String SASL_PROTOCOL = SASL_PREFIX + ".protocol";
/** SASL Server name. */
String SASL_SERVER_NAME = SASL_PREFIX + ".server.name";
/** SASL Callback handler. */
String SASL_CALLBACK_HANDLER = SASL_PREFIX + ".callback.handler";
/** SASL channel binding. */
String SASL_CHANNEL_BINDING = SASL_PREFIX + ".channel.binding";
// SASL data element size limits ...........................................
/** The size limit, in bytes, of a SASL OS (Octet Sequence) element. */
int SASL_ONE_BYTE_MAX_LIMIT = 255;
/**
* The size limit, in bytes, of both a SASL MPI (Multi-Precision Integer)
* element and a SASL Text element.
*/
int SASL_TWO_BYTE_MAX_LIMIT = 65535;
/** The size limit, in bytes, of a SASL EOS (Extended Octet Sequence) element. */
int SASL_FOUR_BYTE_MAX_LIMIT = 2147483383;
/** The size limit, in bytes, of a SASL Buffer. */
int SASL_BUFFER_MAX_LIMIT = 2147483643;
// Canonical names of SASL mechanisms ......................................
String SASL_ANONYMOUS_MECHANISM = "ANONYMOUS";
String SASL_CRAM_MD5_MECHANISM = "CRAM-MD5";
String SASL_PLAIN_MECHANISM = "PLAIN";
String SASL_SRP_MECHANISM = "SRP";
// Canonical names of Integrity Protection algorithms ......................
String SASL_HMAC_MD5_IALG = "HMACwithMD5";
String SASL_HMAC_SHA_IALG = "HMACwithSHA";
// Quality Of Protection string representations ............................
/** authentication only. */
String QOP_AUTH = "auth";
/** authentication plus integrity protection. */
String QOP_AUTH_INT = "auth-int";
/** authentication plus integrity and confidentiality protection. */
String QOP_AUTH_CONF = "auth-conf";
// SASL mechanism strength string representation ...........................
String STRENGTH_HIGH = "high";
String STRENGTH_MEDIUM = "medium";
String STRENGTH_LOW = "low";
// SASL Server Authentication requirement ..................................
/** Server must authenticate to the client. */
String SERVER_AUTH_TRUE = "true";
/** Server does not need to, or cannot, authenticate to the client. */
String SERVER_AUTH_FALSE = "false";
// SASL mechanism reuse capability .........................................
String REUSE_TRUE = "true";
String REUSE_FALSE = "false";
// Keyrings ...............................................................
byte[] GKR_MAGIC = new byte[] { 0x47, 0x4b, 0x52, 0x01 };
// Ring usage fields.
int GKR_PRIVATE_KEYS = 1 << 0;
int GKR_PUBLIC_CREDENTIALS = 1 << 1;
int GKR_CERTIFICATES = 1 << 2;
// HMac types.
int GKR_HMAC_MD5_128 = 0;
int GKR_HMAC_SHA_160 = 1;
int GKR_HMAC_MD5_96 = 2;
int GKR_HMAC_SHA_96 = 3;
// Cipher types.
int GKR_CIPHER_AES_128_OFB = 0;
int GKR_CIPHER_AES_128_CBC = 1;
// Methods
// -------------------------------------------------------------------------
}
@@ -38,6 +38,8 @@ exception statement from your version. */
package gnu.java.security.der;
import gnu.java.security.x509.Util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -108,7 +110,9 @@ public class DERValue implements DER
}
catch (IOException ioe)
{
encoded = new byte[0];
IllegalArgumentException iae = new IllegalArgumentException ();
iae.initCause (ioe);
throw iae;
}
}
return length;
@@ -138,7 +142,9 @@ public class DERValue implements DER
}
catch (IOException ioe)
{
encoded = new byte[0];
IllegalArgumentException iae = new IllegalArgumentException ();
iae.initCause (ioe);
throw iae;
}
}
return (byte[]) encoded.clone();
@@ -156,7 +162,9 @@ public class DERValue implements DER
}
catch (IOException ioe)
{
encoded = new byte[0];
IllegalArgumentException iae = new IllegalArgumentException ();
iae.initCause (ioe);
throw iae;
}
}
return encoded.length;
@@ -164,7 +172,18 @@ public class DERValue implements DER
public String toString()
{
return "DERValue [ tag=" + tag + ", class=" + tagClass + ", constructed="
+ constructed + ", value=" + value + " ]";
String start = "DERValue ( [";
if (tagClass == DER.UNIVERSAL)
start = start + "UNIVERSAL ";
else if (tagClass == DER.PRIVATE)
start = start + "PRIVATE ";
else if (tagClass == DER.APPLICATION)
start = start + "APPLICATION ";
start = start + tag + "] constructed=" + constructed + ", value=";
if (constructed)
start = start + "\n" + Util.hexDump(getEncoded(), "\t");
else
start = start + value;
return start + " )";
}
}
@@ -84,6 +84,12 @@ public class DERWriter implements DER
public static int write(OutputStream out, DERValue object)
throws IOException
{
if (DER.CONSTRUCTED_VALUE.equals (object.getValue ()))
{
out.write (object.getEncoded ());
return object.getLength ();
}
out.write(object.getExternalTag());
Object value = object.getValue();
if (value == null)
@@ -216,10 +222,10 @@ public class DERWriter implements DER
throws IOException
{
byte[] buf = bs.getShiftedByteArray();
out.write(buf.length + 1);
writeLength(out, buf.length + 1);
out.write(bs.getIgnoredBits());
out.write(buf);
return buf.length;
return buf.length + 1;
}
private static int writeString(OutputStream out, int tag, String str)
@@ -0,0 +1,206 @@
/* BaseHash.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
/**
* <p>A base abstract class to facilitate hash implementations.</p>
*/
public abstract class BaseHash implements IMessageDigest
{
// Constants and variables
// -------------------------------------------------------------------------
/** The canonical name prefix of the hash. */
protected String name;
/** The hash (output) size in bytes. */
protected int hashSize;
/** The hash (inner) block size in bytes. */
protected int blockSize;
/** Number of bytes processed so far. */
protected long count;
/** Temporary input buffer. */
protected byte[] buffer;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* <p>Trivial constructor for use by concrete subclasses.</p>
*
* @param name the canonical name prefix of this instance.
* @param hashSize the block size of the output in bytes.
* @param blockSize the block size of the internal transform.
*/
protected BaseHash(String name, int hashSize, int blockSize)
{
super();
this.name = name;
this.hashSize = hashSize;
this.blockSize = blockSize;
this.buffer = new byte[blockSize];
resetContext();
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// IMessageDigest interface implementation ---------------------------------
public String name()
{
return name;
}
public int hashSize()
{
return hashSize;
}
public int blockSize()
{
return blockSize;
}
public void update(byte b)
{
// compute number of bytes still unhashed; ie. present in buffer
int i = (int) (count % blockSize);
count++;
buffer[i] = b;
if (i == (blockSize - 1))
{
transform(buffer, 0);
}
}
public void update(byte[] b)
{
update(b, 0, b.length);
}
public void update(byte[] b, int offset, int len)
{
int n = (int) (count % blockSize);
count += len;
int partLen = blockSize - n;
int i = 0;
if (len >= partLen)
{
System.arraycopy(b, offset, buffer, n, partLen);
transform(buffer, 0);
for (i = partLen; i + blockSize - 1 < len; i += blockSize)
{
transform(b, offset + i);
}
n = 0;
}
if (i < len)
{
System.arraycopy(b, offset + i, buffer, n, len - i);
}
}
public byte[] digest()
{
byte[] tail = padBuffer(); // pad remaining bytes in buffer
update(tail, 0, tail.length); // last transform of a message
byte[] result = getResult(); // make a result out of context
reset(); // reset this instance for future re-use
return result;
}
public void reset()
{ // reset this instance for future re-use
count = 0L;
for (int i = 0; i < blockSize;)
{
buffer[i++] = 0;
}
resetContext();
}
// methods to be implemented by concrete subclasses ------------------------
public abstract Object clone();
public abstract boolean selfTest();
/**
* <p>Returns the byte array to use as padding before completing a hash
* operation.</p>
*
* @return the bytes to pad the remaining bytes in the buffer before
* completing a hash operation.
*/
protected abstract byte[] padBuffer();
/**
* <p>Constructs the result from the contents of the current context.</p>
*
* @return the output of the completed hash operation.
*/
protected abstract byte[] getResult();
/** Resets the instance for future re-use. */
protected abstract void resetContext();
/**
* <p>The block digest transformation per se.</p>
*
* @param in the <i>blockSize</i> long block, as an array of bytes to digest.
* @param offset the index where the data to digest is located within the
* input buffer.
*/
protected abstract void transform(byte[] in, int offset);
}
@@ -0,0 +1,178 @@
/* HashFactory.java --
Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* <p>A <i>Factory</i> to instantiate message digest algorithm instances.</p>
*/
public class HashFactory
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial constructor to enforce <i>Singleton</i> pattern. */
private HashFactory()
{
super();
}
// Class methods
// -------------------------------------------------------------------------
/**
* <p>Return an instance of a hash algorithm given its name.</p>
*
* @param name the name of the hash algorithm.
* @return an instance of the hash algorithm, or null if none found.
* @exception InternalError if the implementation does not pass its self-
* test.
*/
public static IMessageDigest getInstance(String name)
{
if (name == null)
{
return null;
}
name = name.trim();
IMessageDigest result = null;
if (name.equalsIgnoreCase(Registry.WHIRLPOOL_HASH))
{
result = new Whirlpool();
}
else if (name.equalsIgnoreCase(Registry.RIPEMD128_HASH)
|| name.equalsIgnoreCase(Registry.RIPEMD_128_HASH))
{
result = new RipeMD128();
}
else if (name.equalsIgnoreCase(Registry.RIPEMD160_HASH)
|| name.equalsIgnoreCase(Registry.RIPEMD_160_HASH))
{
result = new RipeMD160();
}
else if (name.equalsIgnoreCase(Registry.SHA160_HASH)
|| name.equalsIgnoreCase(Registry.SHA_1_HASH)
|| name.equalsIgnoreCase(Registry.SHA1_HASH)
|| name.equalsIgnoreCase(Registry.SHA_HASH))
{
result = new Sha160();
}
else if (name.equalsIgnoreCase(Registry.SHA256_HASH))
{
result = new Sha256();
}
else if (name.equalsIgnoreCase(Registry.SHA384_HASH))
{
result = new Sha384();
}
else if (name.equalsIgnoreCase(Registry.SHA512_HASH))
{
result = new Sha512();
}
else if (name.equalsIgnoreCase(Registry.TIGER_HASH))
{
result = new Tiger();
}
else if (name.equalsIgnoreCase(Registry.HAVAL_HASH))
{
result = new Haval();
}
else if (name.equalsIgnoreCase(Registry.MD5_HASH))
{
result = new MD5();
}
else if (name.equalsIgnoreCase(Registry.MD4_HASH))
{
result = new MD4();
}
else if (name.equalsIgnoreCase(Registry.MD2_HASH))
{
result = new MD2();
}
else if (name.equalsIgnoreCase(Registry.HAVAL_HASH))
{
result = new Haval();
}
if (result != null && !result.selfTest())
{
throw new InternalError(result.name());
}
return result;
}
/**
* <p>Returns a {@link Set} of names of hash algorithms supported by this
* <i>Factory</i>.</p>
*
* @return a {@link Set} of hash names (Strings).
*/
public static final Set getNames()
{
HashSet hs = new HashSet();
hs.add(Registry.WHIRLPOOL_HASH);
hs.add(Registry.RIPEMD128_HASH);
hs.add(Registry.RIPEMD160_HASH);
hs.add(Registry.SHA160_HASH);
hs.add(Registry.SHA256_HASH);
hs.add(Registry.SHA384_HASH);
hs.add(Registry.SHA512_HASH);
hs.add(Registry.TIGER_HASH);
hs.add(Registry.HAVAL_HASH);
hs.add(Registry.MD5_HASH);
hs.add(Registry.MD4_HASH);
hs.add(Registry.MD2_HASH);
return Collections.unmodifiableSet(hs);
}
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,759 @@
/* Haval.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>The <i>HAVAL</i> message-digest algorithm is a variable output length,
* with variable number of rounds. By default, this implementation allows
* <i>HAVAL</i> to be used as a drop-in replacement for <i>MD5</i>.</p>
*
* <p>References:</p>
*
* <ol>
* <li>HAVAL - A One-Way Hashing Algorithm with Variable Length of Output<br>
* Advances in Cryptology - AUSCRYPT'92, Lecture Notes in Computer Science,<br>
* Springer-Verlag, 1993; <br>
* Y. Zheng, J. Pieprzyk and J. Seberry.</li>
* </ol>
*/
public class Haval extends BaseHash
{
// Constants and variables
// -------------------------------------------------------------------------
public static final int HAVAL_VERSION = 1;
public static final int HAVAL_128_BIT = 16;
public static final int HAVAL_160_BIT = 20;
public static final int HAVAL_192_BIT = 24;
public static final int HAVAL_224_BIT = 28;
public static final int HAVAL_256_BIT = 32;
public static final int HAVAL_3_ROUND = 3;
public static final int HAVAL_4_ROUND = 4;
public static final int HAVAL_5_ROUND = 5;
private static final int BLOCK_SIZE = 128; // inner block size in bytes
private static final String DIGEST0 = "C68F39913F901F3DDF44C707357A7D70";
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
/**
* Number of HAVAL rounds. Allowed values are integers in the range <code>3
* .. 5</code>. The default is <code>3</code>.
*/
private int rounds = HAVAL_3_ROUND;
/** 128-bit interim result. */
private int h0, h1, h2, h3, h4, h5, h6, h7;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* <p>Calls the constructor with two argument using {@link #HAVAL_128_BIT} as
* the value for the output size (i.e. <code>128</code> bits, and
* {@link #HAVAL_3_ROUND} for the value of number of rounds.</p>
*/
public Haval()
{
this(HAVAL_128_BIT, HAVAL_3_ROUND);
}
/**
* <p>Calls the constructor with two arguments using the designated output
* size, and {@link #HAVAL_3_ROUND} for the value of number of rounds.</p>
*
* @param size the output size in bytes of this instance.
* @throws IllegalArgumentException if the designated output size is invalid.
* @see #HAVAL_128_BIT
* @see #HAVAL_160_BIT
* @see #HAVAL_192_BIT
* @see #HAVAL_224_BIT
* @see #HAVAL_256_BIT
*/
public Haval(int size)
{
this(size, HAVAL_3_ROUND);
}
/**
* <p>Constructs a <code>Haval</code> instance with the designated output
* size (in bytes). Valid output <code>size</code> values are <code>16</code>,
* <code>20</code>, <code>24</code>, <code>28</code> and <code>32</code>.
* Valid values for <code>rounds</code> are in the range <code>3..5</code>
* inclusive.</p>
*
* @param size the output size in bytes of this instance.
* @param rounds the number of rounds to apply when transforming data.
* @throws IllegalArgumentException if the designated output size is invalid,
* or if the number of rounds is invalid.
* @see #HAVAL_128_BIT
* @see #HAVAL_160_BIT
* @see #HAVAL_192_BIT
* @see #HAVAL_224_BIT
* @see #HAVAL_256_BIT
* @see #HAVAL_3_ROUND
* @see #HAVAL_4_ROUND
* @see #HAVAL_5_ROUND
*/
public Haval(int size, int rounds)
{
super(Registry.HAVAL_HASH, size, BLOCK_SIZE);
if (size != HAVAL_128_BIT && size != HAVAL_160_BIT && size != HAVAL_192_BIT
&& size != HAVAL_224_BIT && size != HAVAL_256_BIT)
{
throw new IllegalArgumentException("Invalid HAVAL output size");
}
if (rounds != HAVAL_3_ROUND && rounds != HAVAL_4_ROUND
&& rounds != HAVAL_5_ROUND)
{
throw new IllegalArgumentException("Invalid HAVAL number of rounds");
}
this.rounds = rounds;
}
/**
* <p>Private constructor for cloning purposes.</p>
*
* @param md the instance to clone.
*/
private Haval(Haval md)
{
this(md.hashSize, md.rounds);
this.h0 = md.h0;
this.h1 = md.h1;
this.h2 = md.h2;
this.h3 = md.h3;
this.h4 = md.h4;
this.h5 = md.h5;
this.h6 = md.h6;
this.h7 = md.h7;
this.count = md.count;
this.buffer = (byte[]) md.buffer.clone();
}
// Constructor(s)
// -------------------------------------------------------------------------
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// java.lang.Cloneable interface implementation ----------------------------
public Object clone()
{
return new Haval(this);
}
// Implementation of concrete methods in BaseHash --------------------------
protected synchronized void transform(byte[] in, int i)
{
int X0 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X1 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X2 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X3 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X4 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X5 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X6 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X7 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X8 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X9 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X10 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X11 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X12 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X13 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X14 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X15 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X16 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X17 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X18 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X19 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X20 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X21 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X22 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X23 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X24 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X25 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X26 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X27 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X28 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X29 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X30 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int X31 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| (in[i++] & 0xFF) << 24;
int t0 = h0, t1 = h1, t2 = h2, t3 = h3, t4 = h4, t5 = h5, t6 = h6, t7 = h7;
// Pass 1
t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X0);
t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X1);
t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X2);
t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X3);
t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X4);
t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X5);
t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X6);
t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X7);
t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X8);
t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X9);
t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X10);
t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X11);
t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X12);
t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X13);
t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X14);
t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X15);
t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X16);
t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X17);
t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X18);
t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X19);
t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X20);
t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X21);
t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X22);
t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X23);
t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X24);
t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X25);
t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X26);
t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X27);
t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X28);
t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X29);
t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X30);
t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X31);
// Pass 2
t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X5, 0x452821E6);
t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X14, 0x38D01377);
t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X26, 0xBE5466CF);
t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X18, 0x34E90C6C);
t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X11, 0xC0AC29B7);
t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X28, 0xC97C50DD);
t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X7, 0x3F84D5B5);
t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X16, 0xB5470917);
t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X0, 0x9216D5D9);
t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X23, 0x8979FB1B);
t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X20, 0xD1310BA6);
t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X22, 0x98DFB5AC);
t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X1, 0x2FFD72DB);
t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X10, 0xD01ADFB7);
t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X4, 0xB8E1AFED);
t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X8, 0x6A267E96);
t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X30, 0xBA7C9045);
t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X3, 0xF12C7F99);
t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X21, 0x24A19947);
t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X9, 0xB3916CF7);
t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X17, 0x0801F2E2);
t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X24, 0x858EFC16);
t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X29, 0x636920D8);
t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X6, 0x71574E69);
t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X19, 0xA458FEA3);
t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X12, 0xF4933D7E);
t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X15, 0x0D95748F);
t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X13, 0x728EB658);
t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X2, 0x718BCD58);
t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X25, 0x82154AEE);
t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X31, 0x7B54A41D);
t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X27, 0xC25A59B5);
// Pass 3
t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X19, 0x9C30D539);
t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X9, 0x2AF26013);
t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X4, 0xC5D1B023);
t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X20, 0x286085F0);
t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X28, 0xCA417918);
t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X17, 0xB8DB38EF);
t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X8, 0x8E79DCB0);
t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X22, 0x603A180E);
t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X29, 0x6C9E0E8B);
t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X14, 0xB01E8A3E);
t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X25, 0xD71577C1);
t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X12, 0xBD314B27);
t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X24, 0x78AF2FDA);
t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X30, 0x55605C60);
t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X16, 0xE65525F3);
t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X26, 0xAA55AB94);
t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X31, 0x57489862);
t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X15, 0x63E81440);
t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X7, 0x55CA396A);
t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X3, 0x2AAB10B6);
t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X1, 0xB4CC5C34);
t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X0, 0x1141E8CE);
t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X18, 0xA15486AF);
t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X27, 0x7C72E993);
t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X13, 0xB3EE1411);
t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X6, 0x636FBC2A);
t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X21, 0x2BA9C55D);
t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X10, 0x741831F6);
t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X23, 0xCE5C3E16);
t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X11, 0x9B87931E);
t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X5, 0xAFD6BA33);
t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X2, 0x6C24CF5C);
if (rounds >= 4)
{
t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X24, 0x7A325381);
t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X4, 0x28958677);
t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X0, 0x3B8F4898);
t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X14, 0x6B4BB9AF);
t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X2, 0xC4BFE81B);
t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X7, 0x66282193);
t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X28, 0x61D809CC);
t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X23, 0xFB21A991);
t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X26, 0x487CAC60);
t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X6, 0x5DEC8032);
t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X30, 0xEF845D5D);
t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X20, 0xE98575B1);
t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X18, 0xDC262302);
t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X25, 0xEB651B88);
t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X19, 0x23893E81);
t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X3, 0xD396ACC5);
t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X22, 0x0F6D6FF3);
t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X11, 0x83F44239);
t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X31, 0x2E0B4482);
t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X21, 0xA4842004);
t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X8, 0x69C8F04A);
t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X27, 0x9E1F9B5E);
t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X12, 0x21C66842);
t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X9, 0xF6E96C9A);
t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X1, 0x670C9C61);
t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X29, 0xABD388F0);
t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X5, 0x6A51A0D2);
t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X15, 0xD8542F68);
t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X17, 0x960FA728);
t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X10, 0xAB5133A3);
t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X16, 0x6EEF0B6C);
t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X13, 0x137A3BE4);
if (rounds == 5)
{
t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X27, 0xBA3BF050);
t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X3, 0x7EFB2A98);
t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X21, 0xA1F1651D);
t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X26, 0x39AF0176);
t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X17, 0x66CA593E);
t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X11, 0x82430E88);
t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X20, 0x8CEE8619);
t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X29, 0x456F9FB4);
t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X19, 0x7D84A5C3);
t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X0, 0x3B8B5EBE);
t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X12, 0xE06F75D8);
t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X7, 0x85C12073);
t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X13, 0x401A449F);
t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X8, 0x56C16AA6);
t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X31, 0x4ED3AA62);
t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X10, 0x363F7706);
t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X5, 0x1BFEDF72);
t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X9, 0x429B023D);
t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X14, 0x37D0D724);
t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X30, 0xD00A1248);
t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X18, 0xDB0FEAD3);
t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X6, 0x49F1C09B);
t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X28, 0x075372C9);
t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X24, 0x80991B7B);
t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X2, 0x25D479D8);
t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X23, 0xF6E8DEF7);
t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X16, 0xE3FE501A);
t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X22, 0xB6794C3B);
t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X4, 0x976CE0BD);
t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X1, 0x04C006BA);
t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X25, 0xC1A94FB6);
t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X15, 0x409F60C4);
}
}
h7 += t7;
h6 += t6;
h5 += t5;
h4 += t4;
h3 += t3;
h2 += t2;
h1 += t1;
h0 += t0;
}
protected byte[] padBuffer()
{
// pad out to 118 mod 128. other 10 bytes have special use.
int n = (int) (count % BLOCK_SIZE);
int padding = (n < 118) ? (118 - n) : (246 - n);
byte[] result = new byte[padding + 10];
result[0] = (byte) 0x01;
// save the version number (LSB 3), the number of rounds (3 bits in the
// middle), the fingerprint length (MSB 2 bits and next byte) and the
// number of bits in the unpadded message.
int bl = hashSize * 8;
result[padding++] = (byte) (((bl & 0x03) << 6) | ((rounds & 0x07) << 3) | (HAVAL_VERSION & 0x07));
result[padding++] = (byte) (bl >>> 2);
// save number of bits, casting the long to an array of 8 bytes
long bits = count << 3;
result[padding++] = (byte) bits;
result[padding++] = (byte) (bits >>> 8);
result[padding++] = (byte) (bits >>> 16);
result[padding++] = (byte) (bits >>> 24);
result[padding++] = (byte) (bits >>> 32);
result[padding++] = (byte) (bits >>> 40);
result[padding++] = (byte) (bits >>> 48);
result[padding] = (byte) (bits >>> 56);
return result;
}
protected byte[] getResult()
{
tailorDigestBits(); // tailor context for the designated output size
// cast enough top context values into an array of hashSize bytes
byte[] result = new byte[hashSize];
if (hashSize >= HAVAL_256_BIT)
{
result[31] = (byte) (h7 >>> 24);
result[30] = (byte) (h7 >>> 16);
result[29] = (byte) (h7 >>> 8);
result[28] = (byte) h7;
}
if (hashSize >= HAVAL_224_BIT)
{
result[27] = (byte) (h6 >>> 24);
result[26] = (byte) (h6 >>> 16);
result[25] = (byte) (h6 >>> 8);
result[24] = (byte) h6;
}
if (hashSize >= HAVAL_192_BIT)
{
result[23] = (byte) (h5 >>> 24);
result[22] = (byte) (h5 >>> 16);
result[21] = (byte) (h5 >>> 8);
result[20] = (byte) h5;
}
if (hashSize >= HAVAL_160_BIT)
{
result[19] = (byte) (h4 >>> 24);
result[18] = (byte) (h4 >>> 16);
result[17] = (byte) (h4 >>> 8);
result[16] = (byte) h4;
}
result[15] = (byte) (h3 >>> 24);
result[14] = (byte) (h3 >>> 16);
result[13] = (byte) (h3 >>> 8);
result[12] = (byte) h3;
result[11] = (byte) (h2 >>> 24);
result[10] = (byte) (h2 >>> 16);
result[9] = (byte) (h2 >>> 8);
result[8] = (byte) h2;
result[7] = (byte) (h1 >>> 24);
result[6] = (byte) (h1 >>> 16);
result[5] = (byte) (h1 >>> 8);
result[4] = (byte) h1;
result[3] = (byte) (h0 >>> 24);
result[2] = (byte) (h0 >>> 16);
result[1] = (byte) (h0 >>> 8);
result[0] = (byte) h0;
return result;
}
protected void resetContext()
{
h0 = 0x243F6A88;
h1 = 0x85A308D3;
h2 = 0x13198A2E;
h3 = 0x03707344;
h4 = 0xA4093822;
h5 = 0x299F31D0;
h6 = 0x082EFA98;
h7 = 0xEC4E6C89;
}
public boolean selfTest()
{
if (valid == null)
{
valid = new Boolean(DIGEST0.equals(Util.toString(new Haval().digest())));
}
return valid.booleanValue();
}
// helper methods ----------------------------------------------------------
/** Tailors the last output. */
private void tailorDigestBits()
{
int t;
switch (hashSize)
{
case HAVAL_128_BIT:
t = (h7 & 0x000000FF) | (h6 & 0xFF000000) | (h5 & 0x00FF0000)
| (h4 & 0x0000FF00);
h0 += t >>> 8 | t << 24;
t = (h7 & 0x0000FF00) | (h6 & 0x000000FF) | (h5 & 0xFF000000)
| (h4 & 0x00FF0000);
h1 += t >>> 16 | t << 16;
t = (h7 & 0x00FF0000) | (h6 & 0x0000FF00) | (h5 & 0x000000FF)
| (h4 & 0xFF000000);
h2 += t >>> 24 | t << 8;
t = (h7 & 0xFF000000) | (h6 & 0x00FF0000) | (h5 & 0x0000FF00)
| (h4 & 0x000000FF);
h3 += t;
break;
case HAVAL_160_BIT:
t = (h7 & 0x3F) | (h6 & (0x7F << 25)) | (h5 & (0x3F << 19));
h0 += t >>> 19 | t << 13;
t = (h7 & (0x3F << 6)) | (h6 & 0x3F) | (h5 & (0x7F << 25));
h1 += t >>> 25 | t << 7;
t = (h7 & (0x7F << 12)) | (h6 & (0x3F << 6)) | (h5 & 0x3F);
h2 += t;
t = (h7 & (0x3F << 19)) | (h6 & (0x7F << 12)) | (h5 & (0x3F << 6));
h3 += (t >>> 6);
t = (h7 & (0x7F << 25)) | (h6 & (0x3F << 19)) | (h5 & (0x7F << 12));
h4 += (t >>> 12);
break;
case HAVAL_192_BIT:
t = (h7 & 0x1F) | (h6 & (0x3F << 26));
h0 += t >>> 26 | t << 6;
t = (h7 & (0x1F << 5)) | (h6 & 0x1F);
h1 += t;
t = (h7 & (0x3F << 10)) | (h6 & (0x1F << 5));
h2 += (t >>> 5);
t = (h7 & (0x1F << 16)) | (h6 & (0x3F << 10));
h3 += (t >>> 10);
t = (h7 & (0x1F << 21)) | (h6 & (0x1F << 16));
h4 += (t >>> 16);
t = (h7 & (0x3F << 26)) | (h6 & (0x1F << 21));
h5 += (t >>> 21);
break;
case HAVAL_224_BIT:
h0 += ((h7 >>> 27) & 0x1F);
h1 += ((h7 >>> 22) & 0x1F);
h2 += ((h7 >>> 18) & 0x0F);
h3 += ((h7 >>> 13) & 0x1F);
h4 += ((h7 >>> 9) & 0x0F);
h5 += ((h7 >>> 4) & 0x1F);
h6 += (h7 & 0x0F);
}
}
/**
* Permutations phi_{i,j}, i=3,4,5, j=1,...,i.
*
* rounds = 3: 6 5 4 3 2 1 0
* | | | | | | | (replaced by)
* phi_{3,1}: 1 0 3 5 6 2 4
* phi_{3,2}: 4 2 1 0 5 3 6
* phi_{3,3}: 6 1 2 3 4 5 0
*
* rounds = 4: 6 5 4 3 2 1 0
* | | | | | | | (replaced by)
* phi_{4,1}: 2 6 1 4 5 3 0
* phi_{4,2}: 3 5 2 0 1 6 4
* phi_{4,3}: 1 4 3 6 0 2 5
* phi_{4,4}: 6 4 0 5 2 1 3
*
* rounds = 5: 6 5 4 3 2 1 0
* | | | | | | | (replaced by)
* phi_{5,1}: 3 4 1 0 5 2 6
* phi_{5,2}: 6 2 1 0 3 4 5
* phi_{5,3}: 2 6 0 4 3 1 5
* phi_{5,4}: 1 5 3 2 0 4 6
* phi_{5,5}: 2 5 0 6 4 3 1
*/
private int FF1(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
int x0, int w)
{
int t;
switch (rounds)
{
case 3:
t = f1(x1, x0, x3, x5, x6, x2, x4);
break;
case 4:
t = f1(x2, x6, x1, x4, x5, x3, x0);
break;
default:
t = f1(x3, x4, x1, x0, x5, x2, x6);
}
return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w;
}
private int FF2(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
int x0, int w, int c)
{
int t;
switch (rounds)
{
case 3:
t = f2(x4, x2, x1, x0, x5, x3, x6);
break;
case 4:
t = f2(x3, x5, x2, x0, x1, x6, x4);
break;
default:
t = f2(x6, x2, x1, x0, x3, x4, x5);
}
return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c;
}
private int FF3(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
int x0, int w, int c)
{
int t;
switch (rounds)
{
case 3:
t = f3(x6, x1, x2, x3, x4, x5, x0);
break;
case 4:
t = f3(x1, x4, x3, x6, x0, x2, x5);
break;
default:
t = f3(x2, x6, x0, x4, x3, x1, x5);
}
return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c;
}
private int FF4(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
int x0, int w, int c)
{
int t;
switch (rounds)
{
case 4:
t = f4(x6, x4, x0, x5, x2, x1, x3);
break;
default:
t = f4(x1, x5, x3, x2, x0, x4, x6);
}
return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c;
}
private int FF5(int x7, int x6, int x5, int x4, int x3, int x2, int x1,
int x0, int w, int c)
{
int t = f5(x2, x5, x0, x6, x4, x3, x1);
return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c;
}
private int f1(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
{
return x1 & (x0 ^ x4) ^ x2 & x5 ^ x3 & x6 ^ x0;
}
private int f2(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
{
return x2 & (x1 & ~x3 ^ x4 & x5 ^ x6 ^ x0) ^ x4 & (x1 ^ x5) ^ x3 & x5 ^ x0;
}
private int f3(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
{
return x3 & (x1 & x2 ^ x6 ^ x0) ^ x1 & x4 ^ x2 & x5 ^ x0;
}
private int f4(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
{
return x4 & (x5 & ~x2 ^ x3 & ~x6 ^ x1 ^ x6 ^ x0) ^ x3 & (x1 & x2 ^ x5 ^ x6)
^ x2 & x6 ^ x0;
}
private int f5(int x6, int x5, int x4, int x3, int x2, int x1, int x0)
{
return x0 & (x1 & x2 & x3 ^ ~x5) ^ x1 & x4 ^ x2 & x5 ^ x3 & x6;
}
}
@@ -0,0 +1,135 @@
/* IMessageDigest.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
/**
* <p>The basic visible methods of any hash algorithm.</p>
*
* <p>A hash (or message digest) algorithm produces its output by iterating a
* basic compression function on blocks of data.</p>
*/
public interface IMessageDigest extends Cloneable
{
// Constants
// -------------------------------------------------------------------------
// Methods
// -------------------------------------------------------------------------
/**
* <p>Returns the canonical name of this algorithm.</p>
*
* @return the canonical name of this instance.
*/
String name();
/**
* <p>Returns the output length in bytes of this message digest algorithm.</p>
*
* @return the output length in bytes of this message digest algorithm.
*/
int hashSize();
/**
* <p>Returns the algorithm's (inner) block size in bytes.</p>
*
* @return the algorithm's inner block size in bytes.
*/
int blockSize();
/**
* <p>Continues a message digest operation using the input byte.</p>
*
* @param b the input byte to digest.
*/
void update(byte b);
/**
* <p>Continues a message digest operation, by filling the buffer, processing
* data in the algorithm's HASH_SIZE-bit block(s), updating the context and
* count, and buffering the remaining bytes in buffer for the next
* operation.</p>
*
* @param in the input block.
*/
void update(byte[] in);
/**
* <p>Continues a message digest operation, by filling the buffer, processing
* data in the algorithm's HASH_SIZE-bit block(s), updating the context and
* count, and buffering the remaining bytes in buffer for the next
* operation.</p>
*
* @param in the input block.
* @param offset start of meaningful bytes in input block.
* @param length number of bytes, in input block, to consider.
*/
void update(byte[] in, int offset, int length);
/**
* <p>Completes the message digest by performing final operations such as
* padding and resetting the instance.</p>
*
* @return the array of bytes representing the hash value.
*/
byte[] digest();
/**
* <p>Resets the current context of this instance clearing any eventually cached
* intermediary values.</p>
*/
void reset();
/**
* <p>A basic test. Ensures that the digest of a pre-determined message is equal
* to a known pre-computed value.</p>
*
* @return <tt>true</tt> if the implementation passes a basic self-test.
* Returns <tt>false</tt> otherwise.
*/
boolean selfTest();
/**
* <p>Returns a clone copy of this instance.</p>
*
* @return a clone copy of this instance.
*/
Object clone();
}
@@ -0,0 +1,301 @@
/* MD2.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>An implementation of the MD2 message digest algorithm.</p>
*
* <p>MD2 is not widely used. Unless it is needed for compatibility with
* existing systems, it is not recommended for use in new applications.</p>
*
* <p>References:</p>
*
* <ol>
* <li>The <a href="http://www.ietf.org/rfc/rfc1319.txt">MD2</a>
* Message-Digest Algorithm.<br>
* B. Kaliski.</li>
* <li>The <a href="http://www.rfc-editor.org/errata.html">RFC ERRATA PAGE</a>
* under section RFC 1319.</li>
* </ol>
*/
public class MD2 extends BaseHash
{
// Constants and variables
// -------------------------------------------------------------------------
/** An MD2 message digest is always 128-bits long, or 16 bytes. */
private static final int DIGEST_LENGTH = 16;
/** The MD2 algorithm operates on 128-bit blocks, or 16 bytes. */
private static final int BLOCK_LENGTH = 16;
/** 256 byte "random" permutation of the digits of pi. */
private static final byte[] PI = { 41, 46, 67, -55, -94, -40, 124, 1, 61, 54,
84, -95, -20, -16, 6, 19, 98, -89, 5, -13,
-64, -57, 115, -116, -104, -109, 43, -39,
-68, 76, -126, -54, 30, -101, 87, 60, -3,
-44, -32, 22, 103, 66, 111, 24, -118, 23,
-27, 18, -66, 78, -60, -42, -38, -98, -34,
73, -96, -5, -11, -114, -69, 47, -18, 122,
-87, 104, 121, -111, 21, -78, 7, 63, -108,
-62, 16, -119, 11, 34, 95, 33, -128, 127,
93, -102, 90, -112, 50, 39, 53, 62, -52,
-25, -65, -9, -105, 3, -1, 25, 48, -77, 72,
-91, -75, -47, -41, 94, -110, 42, -84, 86,
-86, -58, 79, -72, 56, -46, -106, -92, 125,
-74, 118, -4, 107, -30, -100, 116, 4, -15,
69, -99, 112, 89, 100, 113, -121, 32, -122,
91, -49, 101, -26, 45, -88, 2, 27, 96, 37,
-83, -82, -80, -71, -10, 28, 70, 97, 105,
52, 64, 126, 15, 85, 71, -93, 35, -35, 81,
-81, 58, -61, 92, -7, -50, -70, -59, -22,
38, 44, 83, 13, 110, -123, 40, -124, 9,
-45, -33, -51, -12, 65, -127, 77, 82, 106,
-36, 55, -56, 108, -63, -85, -6, 36, -31,
123, 8, 12, -67, -79, 74, 120, -120, -107,
-117, -29, 99, -24, 109, -23, -53, -43, -2,
59, 0, 29, 57, -14, -17, -73, 14, 102, 88,
-48, -28, -90, 119, 114, -8, -21, 117, 75,
10, 49, 68, 80, -76, -113, -19, 31, 26,
-37, -103, -115, 51, -97, 17, -125, 20 };
/** The output of this message digest when no data has been input. */
private static final String DIGEST0 = "8350E5A3E24C153DF2275C9F80692773";
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
/** The checksum computed so far. */
private byte[] checksum;
/**
* Work array needed by encrypt method. First <code>BLOCK_LENGTH</code> bytes
* are also used to store the running digest.
*/
private byte[] work;
// Constructor(s)
// -------------------------------------------------------------------------
/** Creates a new MD2 digest ready for use. */
public MD2()
{
super(Registry.MD2_HASH, DIGEST_LENGTH, BLOCK_LENGTH);
}
/**
* <p>Private constructor used for cloning.</p>
*
* @param md2 the instance to clone.
*/
private MD2(MD2 md2)
{
this();
// superclass field
this.count = md2.count;
this.buffer = (byte[]) md2.buffer.clone();
// private field
this.checksum = (byte[]) md2.checksum.clone();
this.work = (byte[]) md2.work.clone();
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// java.lang.Cloneable interface implementation ----------------------------
public Object clone()
{
return new MD2(this);
}
// Implementation of abstract methods in BaseHash --------------------------
protected byte[] getResult()
{
byte[] result = new byte[DIGEST_LENGTH];
// Encrypt checksum as last block.
encryptBlock(checksum, 0);
for (int i = 0; i < BLOCK_LENGTH; i++)
{
result[i] = work[i];
}
return result;
}
protected void resetContext()
{
checksum = new byte[BLOCK_LENGTH];
work = new byte[BLOCK_LENGTH * 3];
}
public boolean selfTest()
{
if (valid == null)
{
valid = new Boolean(DIGEST0.equals(Util.toString(new MD2().digest())));
}
return valid.booleanValue();
}
/**
* <p>Generates an array of padding bytes. The padding is defined as
* <code>i</code> bytes of value <code>i</code>, where <code>i</code> is the
* number of bytes to fill the last block of the message to
* <code>BLOCK_LENGTH</code> bytes (or <code>BLOCK_LENGTH</code> bytes when
* the last block was completely full).</p>
*
* @return the bytes to pad the remaining bytes in the buffer before
* completing a hash operation.
*/
protected byte[] padBuffer()
{
int length = BLOCK_LENGTH - (int) (count % BLOCK_LENGTH);
if (length == 0)
{
length = BLOCK_LENGTH;
}
byte[] pad = new byte[length];
for (int i = 0; i < length; i++)
{
pad[i] = (byte) length;
}
return pad;
}
/**
* <p>Adds <code>BLOCK_LENGTH</code> bytes to the running digest.</p>
*
* @param in the byte array to take the <code>BLOCK_LENGTH</code> bytes from.
* @param off the offset to start from in the given byte array.
*/
protected void transform(byte[] in, int off)
{
// encryptBlock(in, off);
// updateCheckSum(in, off);
updateCheckSumAndEncryptBlock(in, off);
}
// Private instance methods ------------------------------------------------
/**
* Updates the checksum with the <code>BLOCK_LENGTH</code> bytes from the
* given array starting at <code>off</code>.
*/
/*
private void updateCheckSum(byte[] in, int off) {
byte l = checksum[BLOCK_LENGTH-1];
for (int i = 0; i < BLOCK_LENGTH; i++) {
byte b = in[off+i];
// l = (byte)((checksum[i] & 0xFF) ^ (PI[((b & 0xFF) ^ (l & 0xFF))] & 0xFF));
l = (byte)(checksum[i] ^ PI[(b ^ l) & 0xFF]);
checksum[i] = l;
}
}
*/
/**
* Adds a new block (<code>BLOCK_LENGTH</code> bytes) to the running digest
* from the given byte array starting from the given offset.
*/
private void encryptBlock(byte[] in, int off)
{
for (int i = 0; i < BLOCK_LENGTH; i++)
{
byte b = in[off + i];
work[BLOCK_LENGTH + i] = b;
work[BLOCK_LENGTH * 2 + i] = (byte) (work[i] ^ b);
}
byte t = 0;
for (int i = 0; i < 18; i++)
{
for (int j = 0; j < 3 * BLOCK_LENGTH; j++)
{
// t = (byte)((work[j] & 0xFF) ^ (PI[t & 0xFF] & 0xFF));
t = (byte) (work[j] ^ PI[t & 0xFF]);
work[j] = t;
}
// t = (byte)((t + i) & 0xFF);
t = (byte) (t + i);
}
}
/**
* Optimized method that combines a checksum update and encrypt of a block.
*/
private void updateCheckSumAndEncryptBlock(byte[] in, int off)
{
byte l = checksum[BLOCK_LENGTH - 1];
for (int i = 0; i < BLOCK_LENGTH; i++)
{
byte b = in[off + i];
work[BLOCK_LENGTH + i] = b;
// work[BLOCK_LENGTH*2+i] = (byte)((work[i] & 0xFF) ^ (b & 0xFF));
work[BLOCK_LENGTH * 2 + i] = (byte) (work[i] ^ b);
// l = (byte)((checksum[i] & 0xFF) ^ (PI[((b & 0xFF) ^ (l & 0xFF))] & 0xFF));
l = (byte) (checksum[i] ^ PI[(b ^ l) & 0xFF]);
checksum[i] = l;
}
byte t = 0;
for (int i = 0; i < 18; i++)
{
for (int j = 0; j < 3 * BLOCK_LENGTH; j++)
{
// t = (byte)((work[j] & 0xFF) ^ (PI[t & 0xFF] & 0xFF));
t = (byte) (work[j] ^ PI[t & 0xFF]);
work[j] = t;
}
// t = (byte)((t + i) & 0xFF);
t = (byte) (t + i);
}
}
}
@@ -0,0 +1,328 @@
/* MD4.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>An implementation of Ron Rivest's MD4 message digest algorithm.</p>
*
* <p>MD4 was the precursor to the stronger {@link gnu.crypto.hash.MD5}
* algorithm, and while not considered cryptograpically secure itself, MD4 is
* in use in various applications. It is slightly faster than MD5.</p>
*
* <p>References:</p>
*
* <ol>
* <li>The <a href="http://www.ietf.org/rfc/rfc1320.txt">MD4</a>
* Message-Digest Algorithm.<br>
* R. Rivest.</li>
* </ol>
*
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class MD4 extends BaseHash
{
// Constants and variables
// -------------------------------------------------------------------------
/** An MD4 message digest is always 128-bits long, or 16 bytes. */
private static final int DIGEST_LENGTH = 16;
/** The MD4 algorithm operates on 512-bit blocks, or 64 bytes. */
private static final int BLOCK_LENGTH = 64;
private static final int A = 0x67452301;
private static final int B = 0xefcdab89;
private static final int C = 0x98badcfe;
private static final int D = 0x10325476;
/** The output of this message digest when no data has been input. */
private static final String DIGEST0 = "31D6CFE0D16AE931B73C59D7E0C089C0";
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
private int a, b, c, d;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* <p>Public constructor. Initializes the chaining variables, sets the byte
* count to <code>0</code>, and creates a new block of <code>512</code> bits.
* </p>
*/
public MD4()
{
super(Registry.MD4_HASH, DIGEST_LENGTH, BLOCK_LENGTH);
}
/**
* <p>Trivial private constructor for cloning purposes.</p>
*
* @param that the instance to clone.
*/
private MD4(MD4 that)
{
this();
this.a = that.a;
this.b = that.b;
this.c = that.c;
this.d = that.d;
this.count = that.count;
this.buffer = (byte[]) that.buffer.clone();
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// java.lang.Cloneable interface implementation ----------------------------
public Object clone()
{
return new MD4(this);
}
// Implementation of abstract methods in BashHash --------------------------
protected byte[] getResult()
{
byte[] digest = { (byte) a, (byte) (a >>> 8), (byte) (a >>> 16),
(byte) (a >>> 24), (byte) b, (byte) (b >>> 8),
(byte) (b >>> 16), (byte) (b >>> 24), (byte) c,
(byte) (c >>> 8), (byte) (c >>> 16), (byte) (c >>> 24),
(byte) d, (byte) (d >>> 8), (byte) (d >>> 16),
(byte) (d >>> 24) };
return digest;
}
protected void resetContext()
{
a = A;
b = B;
c = C;
d = D;
}
public boolean selfTest()
{
if (valid == null)
{
valid = new Boolean(DIGEST0.equals(Util.toString(new MD4().digest())));
}
return valid.booleanValue();
}
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_LENGTH);
int padding = (n < 56) ? (56 - n) : (120 - n);
byte[] pad = new byte[padding + 8];
pad[0] = (byte) 0x80;
long bits = count << 3;
pad[padding++] = (byte) bits;
pad[padding++] = (byte) (bits >>> 8);
pad[padding++] = (byte) (bits >>> 16);
pad[padding++] = (byte) (bits >>> 24);
pad[padding++] = (byte) (bits >>> 32);
pad[padding++] = (byte) (bits >>> 40);
pad[padding++] = (byte) (bits >>> 48);
pad[padding] = (byte) (bits >>> 56);
return pad;
}
protected void transform(byte[] in, int i)
{
int X0 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X1 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X2 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X3 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X4 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X5 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X6 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X7 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X8 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X9 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X10 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X11 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X12 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X13 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X14 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X15 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i] << 24;
int aa, bb, cc, dd;
aa = a;
bb = b;
cc = c;
dd = d;
aa += ((bb & cc) | ((~bb) & dd)) + X0;
aa = aa << 3 | aa >>> -3;
dd += ((aa & bb) | ((~aa) & cc)) + X1;
dd = dd << 7 | dd >>> -7;
cc += ((dd & aa) | ((~dd) & bb)) + X2;
cc = cc << 11 | cc >>> -11;
bb += ((cc & dd) | ((~cc) & aa)) + X3;
bb = bb << 19 | bb >>> -19;
aa += ((bb & cc) | ((~bb) & dd)) + X4;
aa = aa << 3 | aa >>> -3;
dd += ((aa & bb) | ((~aa) & cc)) + X5;
dd = dd << 7 | dd >>> -7;
cc += ((dd & aa) | ((~dd) & bb)) + X6;
cc = cc << 11 | cc >>> -11;
bb += ((cc & dd) | ((~cc) & aa)) + X7;
bb = bb << 19 | bb >>> -19;
aa += ((bb & cc) | ((~bb) & dd)) + X8;
aa = aa << 3 | aa >>> -3;
dd += ((aa & bb) | ((~aa) & cc)) + X9;
dd = dd << 7 | dd >>> -7;
cc += ((dd & aa) | ((~dd) & bb)) + X10;
cc = cc << 11 | cc >>> -11;
bb += ((cc & dd) | ((~cc) & aa)) + X11;
bb = bb << 19 | bb >>> -19;
aa += ((bb & cc) | ((~bb) & dd)) + X12;
aa = aa << 3 | aa >>> -3;
dd += ((aa & bb) | ((~aa) & cc)) + X13;
dd = dd << 7 | dd >>> -7;
cc += ((dd & aa) | ((~dd) & bb)) + X14;
cc = cc << 11 | cc >>> -11;
bb += ((cc & dd) | ((~cc) & aa)) + X15;
bb = bb << 19 | bb >>> -19;
aa += ((bb & (cc | dd)) | (cc & dd)) + X0 + 0x5a827999;
aa = aa << 3 | aa >>> -3;
dd += ((aa & (bb | cc)) | (bb & cc)) + X4 + 0x5a827999;
dd = dd << 5 | dd >>> -5;
cc += ((dd & (aa | bb)) | (aa & bb)) + X8 + 0x5a827999;
cc = cc << 9 | cc >>> -9;
bb += ((cc & (dd | aa)) | (dd & aa)) + X12 + 0x5a827999;
bb = bb << 13 | bb >>> -13;
aa += ((bb & (cc | dd)) | (cc & dd)) + X1 + 0x5a827999;
aa = aa << 3 | aa >>> -3;
dd += ((aa & (bb | cc)) | (bb & cc)) + X5 + 0x5a827999;
dd = dd << 5 | dd >>> -5;
cc += ((dd & (aa | bb)) | (aa & bb)) + X9 + 0x5a827999;
cc = cc << 9 | cc >>> -9;
bb += ((cc & (dd | aa)) | (dd & aa)) + X13 + 0x5a827999;
bb = bb << 13 | bb >>> -13;
aa += ((bb & (cc | dd)) | (cc & dd)) + X2 + 0x5a827999;
aa = aa << 3 | aa >>> -3;
dd += ((aa & (bb | cc)) | (bb & cc)) + X6 + 0x5a827999;
dd = dd << 5 | dd >>> -5;
cc += ((dd & (aa | bb)) | (aa & bb)) + X10 + 0x5a827999;
cc = cc << 9 | cc >>> -9;
bb += ((cc & (dd | aa)) | (dd & aa)) + X14 + 0x5a827999;
bb = bb << 13 | bb >>> -13;
aa += ((bb & (cc | dd)) | (cc & dd)) + X3 + 0x5a827999;
aa = aa << 3 | aa >>> -3;
dd += ((aa & (bb | cc)) | (bb & cc)) + X7 + 0x5a827999;
dd = dd << 5 | dd >>> -5;
cc += ((dd & (aa | bb)) | (aa & bb)) + X11 + 0x5a827999;
cc = cc << 9 | cc >>> -9;
bb += ((cc & (dd | aa)) | (dd & aa)) + X15 + 0x5a827999;
bb = bb << 13 | bb >>> -13;
aa += (bb ^ cc ^ dd) + X0 + 0x6ed9eba1;
aa = aa << 3 | aa >>> -3;
dd += (aa ^ bb ^ cc) + X8 + 0x6ed9eba1;
dd = dd << 9 | dd >>> -9;
cc += (dd ^ aa ^ bb) + X4 + 0x6ed9eba1;
cc = cc << 11 | cc >>> -11;
bb += (cc ^ dd ^ aa) + X12 + 0x6ed9eba1;
bb = bb << 15 | bb >>> -15;
aa += (bb ^ cc ^ dd) + X2 + 0x6ed9eba1;
aa = aa << 3 | aa >>> -3;
dd += (aa ^ bb ^ cc) + X10 + 0x6ed9eba1;
dd = dd << 9 | dd >>> -9;
cc += (dd ^ aa ^ bb) + X6 + 0x6ed9eba1;
cc = cc << 11 | cc >>> -11;
bb += (cc ^ dd ^ aa) + X14 + 0x6ed9eba1;
bb = bb << 15 | bb >>> -15;
aa += (bb ^ cc ^ dd) + X1 + 0x6ed9eba1;
aa = aa << 3 | aa >>> -3;
dd += (aa ^ bb ^ cc) + X9 + 0x6ed9eba1;
dd = dd << 9 | dd >>> -9;
cc += (dd ^ aa ^ bb) + X5 + 0x6ed9eba1;
cc = cc << 11 | cc >>> -11;
bb += (cc ^ dd ^ aa) + X13 + 0x6ed9eba1;
bb = bb << 15 | bb >>> -15;
aa += (bb ^ cc ^ dd) + X3 + 0x6ed9eba1;
aa = aa << 3 | aa >>> -3;
dd += (aa ^ bb ^ cc) + X11 + 0x6ed9eba1;
dd = dd << 9 | dd >>> -9;
cc += (dd ^ aa ^ bb) + X7 + 0x6ed9eba1;
cc = cc << 11 | cc >>> -11;
bb += (cc ^ dd ^ aa) + X15 + 0x6ed9eba1;
bb = bb << 15 | bb >>> -15;
a += aa;
b += bb;
c += cc;
d += dd;
}
}
@@ -0,0 +1,365 @@
/* MD5.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>The MD5 message-digest algorithm takes as input a message of arbitrary
* length and produces as output a 128-bit "fingerprint" or "message digest" of
* the input. It is conjectured that it is computationally infeasible to
* produce two messages having the same message digest, or to produce any
* message having a given prespecified target message digest.</p>
*
* <p>References:</p>
*
* <ol>
* <li>The <a href="http://www.ietf.org/rfc/rfc1321.txt">MD5</a> Message-
* Digest Algorithm.<br>
* R. Rivest.</li>
* </ol>
*/
public class MD5 extends BaseHash
{
// Constants and variables
// -------------------------------------------------------------------------
private static final int BLOCK_SIZE = 64; // inner block size in bytes
private static final String DIGEST0 = "D41D8CD98F00B204E9800998ECF8427E";
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
/** 128-bit interim result. */
private int h0, h1, h2, h3;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public MD5()
{
super(Registry.MD5_HASH, 16, BLOCK_SIZE);
}
/**
* <p>Private constructor for cloning purposes.</p>
*
* @param md the instance to clone.
*/
private MD5(MD5 md)
{
this();
this.h0 = md.h0;
this.h1 = md.h1;
this.h2 = md.h2;
this.h3 = md.h3;
this.count = md.count;
this.buffer = (byte[]) md.buffer.clone();
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// java.lang.Cloneable interface implementation ----------------------------
public Object clone()
{
return new MD5(this);
}
// Implementation of concrete methods in BaseHash --------------------------
protected synchronized void transform(byte[] in, int i)
{
int X0 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X1 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X2 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X3 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X4 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X5 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X6 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X7 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X8 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X9 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X10 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X11 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X12 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X13 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X14 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i++] << 24;
int X15 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16
| in[i] << 24;
int A = h0;
int B = h1;
int C = h2;
int D = h3;
// hex constants are from md5.c in FSF Gnu Privacy Guard 0.9.2
// round 1
A += ((B & C) | (~B & D)) + X0 + 0xD76AA478;
A = B + (A << 7 | A >>> -7);
D += ((A & B) | (~A & C)) + X1 + 0xE8C7B756;
D = A + (D << 12 | D >>> -12);
C += ((D & A) | (~D & B)) + X2 + 0x242070DB;
C = D + (C << 17 | C >>> -17);
B += ((C & D) | (~C & A)) + X3 + 0xC1BDCEEE;
B = C + (B << 22 | B >>> -22);
A += ((B & C) | (~B & D)) + X4 + 0xF57C0FAF;
A = B + (A << 7 | A >>> -7);
D += ((A & B) | (~A & C)) + X5 + 0x4787C62A;
D = A + (D << 12 | D >>> -12);
C += ((D & A) | (~D & B)) + X6 + 0xA8304613;
C = D + (C << 17 | C >>> -17);
B += ((C & D) | (~C & A)) + X7 + 0xFD469501;
B = C + (B << 22 | B >>> -22);
A += ((B & C) | (~B & D)) + X8 + 0x698098D8;
A = B + (A << 7 | A >>> -7);
D += ((A & B) | (~A & C)) + X9 + 0x8B44F7AF;
D = A + (D << 12 | D >>> -12);
C += ((D & A) | (~D & B)) + X10 + 0xFFFF5BB1;
C = D + (C << 17 | C >>> -17);
B += ((C & D) | (~C & A)) + X11 + 0x895CD7BE;
B = C + (B << 22 | B >>> -22);
A += ((B & C) | (~B & D)) + X12 + 0x6B901122;
A = B + (A << 7 | A >>> -7);
D += ((A & B) | (~A & C)) + X13 + 0xFD987193;
D = A + (D << 12 | D >>> -12);
C += ((D & A) | (~D & B)) + X14 + 0xA679438E;
C = D + (C << 17 | C >>> -17);
B += ((C & D) | (~C & A)) + X15 + 0x49B40821;
B = C + (B << 22 | B >>> -22);
// round 2
A += ((B & D) | (C & ~D)) + X1 + 0xF61E2562;
A = B + (A << 5 | A >>> -5);
D += ((A & C) | (B & ~C)) + X6 + 0xC040B340;
D = A + (D << 9 | D >>> -9);
C += ((D & B) | (A & ~B)) + X11 + 0x265E5A51;
C = D + (C << 14 | C >>> -14);
B += ((C & A) | (D & ~A)) + X0 + 0xE9B6C7AA;
B = C + (B << 20 | B >>> -20);
A += ((B & D) | (C & ~D)) + X5 + 0xD62F105D;
A = B + (A << 5 | A >>> -5);
D += ((A & C) | (B & ~C)) + X10 + 0x02441453;
D = A + (D << 9 | D >>> -9);
C += ((D & B) | (A & ~B)) + X15 + 0xD8A1E681;
C = D + (C << 14 | C >>> -14);
B += ((C & A) | (D & ~A)) + X4 + 0xE7D3FBC8;
B = C + (B << 20 | B >>> -20);
A += ((B & D) | (C & ~D)) + X9 + 0x21E1CDE6;
A = B + (A << 5 | A >>> -5);
D += ((A & C) | (B & ~C)) + X14 + 0xC33707D6;
D = A + (D << 9 | D >>> -9);
C += ((D & B) | (A & ~B)) + X3 + 0xF4D50D87;
C = D + (C << 14 | C >>> -14);
B += ((C & A) | (D & ~A)) + X8 + 0x455A14ED;
B = C + (B << 20 | B >>> -20);
A += ((B & D) | (C & ~D)) + X13 + 0xA9E3E905;
A = B + (A << 5 | A >>> -5);
D += ((A & C) | (B & ~C)) + X2 + 0xFCEFA3F8;
D = A + (D << 9 | D >>> -9);
C += ((D & B) | (A & ~B)) + X7 + 0x676F02D9;
C = D + (C << 14 | C >>> -14);
B += ((C & A) | (D & ~A)) + X12 + 0x8D2A4C8A;
B = C + (B << 20 | B >>> -20);
// round 3
A += (B ^ C ^ D) + X5 + 0xFFFA3942;
A = B + (A << 4 | A >>> -4);
D += (A ^ B ^ C) + X8 + 0x8771F681;
D = A + (D << 11 | D >>> -11);
C += (D ^ A ^ B) + X11 + 0x6D9D6122;
C = D + (C << 16 | C >>> -16);
B += (C ^ D ^ A) + X14 + 0xFDE5380C;
B = C + (B << 23 | B >>> -23);
A += (B ^ C ^ D) + X1 + 0xA4BEEA44;
A = B + (A << 4 | A >>> -4);
D += (A ^ B ^ C) + X4 + 0x4BDECFA9;
D = A + (D << 11 | D >>> -11);
C += (D ^ A ^ B) + X7 + 0xF6BB4B60;
C = D + (C << 16 | C >>> -16);
B += (C ^ D ^ A) + X10 + 0xBEBFBC70;
B = C + (B << 23 | B >>> -23);
A += (B ^ C ^ D) + X13 + 0x289B7EC6;
A = B + (A << 4 | A >>> -4);
D += (A ^ B ^ C) + X0 + 0xEAA127FA;
D = A + (D << 11 | D >>> -11);
C += (D ^ A ^ B) + X3 + 0xD4EF3085;
C = D + (C << 16 | C >>> -16);
B += (C ^ D ^ A) + X6 + 0x04881D05;
B = C + (B << 23 | B >>> -23);
A += (B ^ C ^ D) + X9 + 0xD9D4D039;
A = B + (A << 4 | A >>> -4);
D += (A ^ B ^ C) + X12 + 0xE6DB99E5;
D = A + (D << 11 | D >>> -11);
C += (D ^ A ^ B) + X15 + 0x1FA27CF8;
C = D + (C << 16 | C >>> -16);
B += (C ^ D ^ A) + X2 + 0xC4AC5665;
B = C + (B << 23 | B >>> -23);
// round 4
A += (C ^ (B | ~D)) + X0 + 0xF4292244;
A = B + (A << 6 | A >>> -6);
D += (B ^ (A | ~C)) + X7 + 0x432AFF97;
D = A + (D << 10 | D >>> -10);
C += (A ^ (D | ~B)) + X14 + 0xAB9423A7;
C = D + (C << 15 | C >>> -15);
B += (D ^ (C | ~A)) + X5 + 0xFC93A039;
B = C + (B << 21 | B >>> -21);
A += (C ^ (B | ~D)) + X12 + 0x655B59C3;
A = B + (A << 6 | A >>> -6);
D += (B ^ (A | ~C)) + X3 + 0x8F0CCC92;
D = A + (D << 10 | D >>> -10);
C += (A ^ (D | ~B)) + X10 + 0xFFEFF47D;
C = D + (C << 15 | C >>> -15);
B += (D ^ (C | ~A)) + X1 + 0x85845dd1;
B = C + (B << 21 | B >>> -21);
A += (C ^ (B | ~D)) + X8 + 0x6FA87E4F;
A = B + (A << 6 | A >>> -6);
D += (B ^ (A | ~C)) + X15 + 0xFE2CE6E0;
D = A + (D << 10 | D >>> -10);
C += (A ^ (D | ~B)) + X6 + 0xA3014314;
C = D + (C << 15 | C >>> -15);
B += (D ^ (C | ~A)) + X13 + 0x4E0811A1;
B = C + (B << 21 | B >>> -21);
A += (C ^ (B | ~D)) + X4 + 0xF7537E82;
A = B + (A << 6 | A >>> -6);
D += (B ^ (A | ~C)) + X11 + 0xBD3AF235;
D = A + (D << 10 | D >>> -10);
C += (A ^ (D | ~B)) + X2 + 0x2AD7D2BB;
C = D + (C << 15 | C >>> -15);
B += (D ^ (C | ~A)) + X9 + 0xEB86D391;
B = C + (B << 21 | B >>> -21);
h0 += A;
h1 += B;
h2 += C;
h3 += D;
}
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
int padding = (n < 56) ? (56 - n) : (120 - n);
byte[] result = new byte[padding + 8];
// padding is always binary 1 followed by binary 0s
result[0] = (byte) 0x80;
// save number of bits, casting the long to an array of 8 bytes
long bits = count << 3;
result[padding++] = (byte) bits;
result[padding++] = (byte) (bits >>> 8);
result[padding++] = (byte) (bits >>> 16);
result[padding++] = (byte) (bits >>> 24);
result[padding++] = (byte) (bits >>> 32);
result[padding++] = (byte) (bits >>> 40);
result[padding++] = (byte) (bits >>> 48);
result[padding] = (byte) (bits >>> 56);
return result;
}
protected byte[] getResult()
{
byte[] result = new byte[] { (byte) h0, (byte) (h0 >>> 8),
(byte) (h0 >>> 16), (byte) (h0 >>> 24),
(byte) h1, (byte) (h1 >>> 8),
(byte) (h1 >>> 16), (byte) (h1 >>> 24),
(byte) h2, (byte) (h2 >>> 8),
(byte) (h2 >>> 16), (byte) (h2 >>> 24),
(byte) h3, (byte) (h3 >>> 8),
(byte) (h3 >>> 16), (byte) (h3 >>> 24) };
return result;
}
protected void resetContext()
{
// magic MD5/RIPEMD128 initialisation constants
h0 = 0x67452301;
h1 = 0xEFCDAB89;
h2 = 0x98BADCFE;
h3 = 0x10325476;
}
public boolean selfTest()
{
if (valid == null)
{
valid = new Boolean(DIGEST0.equals(Util.toString(new MD5().digest())));
}
return valid.booleanValue();
}
}
@@ -0,0 +1,291 @@
/* RipeMD128.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>RIPEMD-128 is a 128-bit message digest.</p>
*
* <p>References:</p>
*
* <ol>
* <li><a href="http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html">
* RIPEMD160</a>: A Strengthened Version of RIPEMD.<br>
* Hans Dobbertin, Antoon Bosselaers and Bart Preneel.</li>
* </ol>
*/
public class RipeMD128 extends BaseHash
{
// Constants and variables
// -------------------------------------------------------------------------
private static final int BLOCK_SIZE = 64; // inner block size in bytes
private static final String DIGEST0 = "CDF26213A150DC3ECB610F18F6B38B46";
/** Constants for the transform method. */
// selection of message word
private static final int[] R = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0,
9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8,
1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10,
0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2 };
private static final int[] Rp = { 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1,
10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14,
15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14,
6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4,
1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14 };
// amount for rotate left (rol)
private static final int[] S = { 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15,
6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12,
15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9,
13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12,
14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5,
12 };
private static final int[] Sp = { 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11,
14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11,
7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8,
6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15,
5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5,
15, 8 };
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
/** 128-bit h0, h1, h2, h3 (interim result) */
private int h0, h1, h2, h3;
/** 512 bits work buffer = 16 x 32-bit words */
private int[] X = new int[16];
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public RipeMD128()
{
super(Registry.RIPEMD128_HASH, 16, BLOCK_SIZE);
}
/**
* <p>Private constructor for cloning purposes.</p>
*
* @param md the instance to clone.
*/
private RipeMD128(RipeMD128 md)
{
this();
this.h0 = md.h0;
this.h1 = md.h1;
this.h2 = md.h2;
this.h3 = md.h3;
this.count = md.count;
this.buffer = (byte[]) md.buffer.clone();
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// java.lang.Cloneable interface implementation ----------------------------
public Object clone()
{
return new RipeMD128(this);
}
// Implementation of concrete methods in BaseHash --------------------------
protected void transform(byte[] in, int offset)
{
int A, B, C, D, Ap, Bp, Cp, Dp, T, s, i;
// encode 64 bytes from input block into an array of 16 unsigned
// integers.
for (i = 0; i < 16; i++)
{
X[i] = (in[offset++] & 0xFF) | (in[offset++] & 0xFF) << 8
| (in[offset++] & 0xFF) << 16 | in[offset++] << 24;
}
A = Ap = h0;
B = Bp = h1;
C = Cp = h2;
D = Dp = h3;
for (i = 0; i < 16; i++)
{ // rounds 0...15
s = S[i];
T = A + (B ^ C ^ D) + X[i];
A = D;
D = C;
C = B;
B = T << s | T >>> (32 - s);
s = Sp[i];
T = Ap + ((Bp & Dp) | (Cp & ~Dp)) + X[Rp[i]] + 0x50A28BE6;
Ap = Dp;
Dp = Cp;
Cp = Bp;
Bp = T << s | T >>> (32 - s);
}
for (; i < 32; i++)
{ // rounds 16...31
s = S[i];
T = A + ((B & C) | (~B & D)) + X[R[i]] + 0x5A827999;
A = D;
D = C;
C = B;
B = T << s | T >>> (32 - s);
s = Sp[i];
T = Ap + ((Bp | ~Cp) ^ Dp) + X[Rp[i]] + 0x5C4DD124;
Ap = Dp;
Dp = Cp;
Cp = Bp;
Bp = T << s | T >>> (32 - s);
}
for (; i < 48; i++)
{ // rounds 32...47
s = S[i];
T = A + ((B | ~C) ^ D) + X[R[i]] + 0x6ED9EBA1;
A = D;
D = C;
C = B;
B = T << s | T >>> (32 - s);
s = Sp[i];
T = Ap + ((Bp & Cp) | (~Bp & Dp)) + X[Rp[i]] + 0x6D703EF3;
Ap = Dp;
Dp = Cp;
Cp = Bp;
Bp = T << s | T >>> (32 - s);
}
for (; i < 64; i++)
{ // rounds 48...63
s = S[i];
T = A + ((B & D) | (C & ~D)) + X[R[i]] + 0x8F1BBCDC;
A = D;
D = C;
C = B;
B = T << s | T >>> (32 - s);
s = Sp[i];
T = Ap + (Bp ^ Cp ^ Dp) + X[Rp[i]];
Ap = Dp;
Dp = Cp;
Cp = Bp;
Bp = T << s | T >>> (32 - s);
}
T = h1 + C + Dp;
h1 = h2 + D + Ap;
h2 = h3 + A + Bp;
h3 = h0 + B + Cp;
h0 = T;
}
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
int padding = (n < 56) ? (56 - n) : (120 - n);
byte[] result = new byte[padding + 8];
// padding is always binary 1 followed by binary 0s
result[0] = (byte) 0x80;
// save number of bits, casting the long to an array of 8 bytes
long bits = count << 3;
result[padding++] = (byte) bits;
result[padding++] = (byte) (bits >>> 8);
result[padding++] = (byte) (bits >>> 16);
result[padding++] = (byte) (bits >>> 24);
result[padding++] = (byte) (bits >>> 32);
result[padding++] = (byte) (bits >>> 40);
result[padding++] = (byte) (bits >>> 48);
result[padding] = (byte) (bits >>> 56);
return result;
}
protected byte[] getResult()
{
byte[] result = new byte[] { (byte) h0, (byte) (h0 >>> 8),
(byte) (h0 >>> 16), (byte) (h0 >>> 24),
(byte) h1, (byte) (h1 >>> 8),
(byte) (h1 >>> 16), (byte) (h1 >>> 24),
(byte) h2, (byte) (h2 >>> 8),
(byte) (h2 >>> 16), (byte) (h2 >>> 24),
(byte) h3, (byte) (h3 >>> 8),
(byte) (h3 >>> 16), (byte) (h3 >>> 24) };
return result;
}
protected void resetContext()
{
// magic RIPEMD128 initialisation constants
h0 = 0x67452301;
h1 = 0xEFCDAB89;
h2 = 0x98BADCFE;
h3 = 0x10325476;
}
public boolean selfTest()
{
if (valid == null)
{
valid = new Boolean
(DIGEST0.equals(Util.toString(new RipeMD128().digest())));
}
return valid.booleanValue();
}
}
@@ -0,0 +1,328 @@
/* RipeMD160.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>RIPEMD-160 is a 160-bit message digest.</p>
*
* <p>References:</p>
*
* <ol>
* <li><a href="http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html">
* RIPEMD160</a>: A Strengthened Version of RIPEMD.<br>
* Hans Dobbertin, Antoon Bosselaers and Bart Preneel.</li>
* </ol>
*/
public class RipeMD160 extends BaseHash
{
// Constants and variables
// -------------------------------------------------------------------------
private static final int BLOCK_SIZE = 64; // inner block size in bytes
private static final String DIGEST0 = "9C1185A5C5E9FC54612808977EE8F548B2258D31";
// selection of message word
private static final int[] R = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0,
9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8,
1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10,
0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0,
5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15,
13 };
private static final int[] Rp = { 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1,
10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14,
15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14,
6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4,
1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0,
3, 9, 11 };
// amount for rotate left (rol)
private static final int[] S = { 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15,
6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12,
15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9,
13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12,
14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5,
12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13,
14, 11, 8, 5, 6 };
private static final int[] Sp = { 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11,
14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11,
7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8,
6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15,
5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5,
15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6,
5, 15, 13, 11, 11 };
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
/** 160-bit h0, h1, h2, h3, h4 (interim result) */
private int h0, h1, h2, h3, h4;
/** 512 bits work buffer = 16 x 32-bit words */
private int[] X = new int[16];
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public RipeMD160()
{
super(Registry.RIPEMD160_HASH, 20, BLOCK_SIZE);
}
/**
* <p>Private constructor for cloning purposes.</p>
*
* @param md the instance to clone.
*/
private RipeMD160(RipeMD160 md)
{
this();
this.h0 = md.h0;
this.h1 = md.h1;
this.h2 = md.h2;
this.h3 = md.h3;
this.h4 = md.h4;
this.count = md.count;
this.buffer = (byte[]) md.buffer.clone();
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// java.lang.Cloneable interface implementation ----------------------------
public Object clone()
{
return (new RipeMD160(this));
}
// Implementation of concrete methods in BaseHash --------------------------
protected void transform(byte[] in, int offset)
{
int A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, T, s, i;
// encode 64 bytes from input block into an array of 16 unsigned integers
for (i = 0; i < 16; i++)
{
X[i] = (in[offset++] & 0xFF) | (in[offset++] & 0xFF) << 8
| (in[offset++] & 0xFF) << 16 | in[offset++] << 24;
}
A = Ap = h0;
B = Bp = h1;
C = Cp = h2;
D = Dp = h3;
E = Ep = h4;
for (i = 0; i < 16; i++)
{ // rounds 0...15
s = S[i];
T = A + (B ^ C ^ D) + X[i];
A = E;
E = D;
D = C << 10 | C >>> 22;
C = B;
B = (T << s | T >>> (32 - s)) + A;
s = Sp[i];
T = Ap + (Bp ^ (Cp | ~Dp)) + X[Rp[i]] + 0x50A28BE6;
Ap = Ep;
Ep = Dp;
Dp = Cp << 10 | Cp >>> 22;
Cp = Bp;
Bp = (T << s | T >>> (32 - s)) + Ap;
}
for (; i < 32; i++)
{ // rounds 16...31
s = S[i];
T = A + ((B & C) | (~B & D)) + X[R[i]] + 0x5A827999;
A = E;
E = D;
D = C << 10 | C >>> 22;
C = B;
B = (T << s | T >>> (32 - s)) + A;
s = Sp[i];
T = Ap + ((Bp & Dp) | (Cp & ~Dp)) + X[Rp[i]] + 0x5C4DD124;
Ap = Ep;
Ep = Dp;
Dp = Cp << 10 | Cp >>> 22;
Cp = Bp;
Bp = (T << s | T >>> (32 - s)) + Ap;
}
for (; i < 48; i++)
{ // rounds 32...47
s = S[i];
T = A + ((B | ~C) ^ D) + X[R[i]] + 0x6ED9EBA1;
A = E;
E = D;
D = C << 10 | C >>> 22;
C = B;
B = (T << s | T >>> (32 - s)) + A;
s = Sp[i];
T = Ap + ((Bp | ~Cp) ^ Dp) + X[Rp[i]] + 0x6D703EF3;
Ap = Ep;
Ep = Dp;
Dp = Cp << 10 | Cp >>> 22;
Cp = Bp;
Bp = (T << s | T >>> (32 - s)) + Ap;
}
for (; i < 64; i++)
{ // rounds 48...63
s = S[i];
T = A + ((B & D) | (C & ~D)) + X[R[i]] + 0x8F1BBCDC;
A = E;
E = D;
D = C << 10 | C >>> 22;
C = B;
B = (T << s | T >>> (32 - s)) + A;
s = Sp[i];
T = Ap + ((Bp & Cp) | (~Bp & Dp)) + X[Rp[i]] + 0x7A6D76E9;
Ap = Ep;
Ep = Dp;
Dp = Cp << 10 | Cp >>> 22;
Cp = Bp;
Bp = (T << s | T >>> (32 - s)) + Ap;
}
for (; i < 80; i++)
{ // rounds 64...79
s = S[i];
T = A + (B ^ (C | ~D)) + X[R[i]] + 0xA953FD4E;
A = E;
E = D;
D = C << 10 | C >>> 22;
C = B;
B = (T << s | T >>> (32 - s)) + A;
s = Sp[i];
T = Ap + (Bp ^ Cp ^ Dp) + X[Rp[i]];
Ap = Ep;
Ep = Dp;
Dp = Cp << 10 | Cp >>> 22;
Cp = Bp;
Bp = (T << s | T >>> (32 - s)) + Ap;
}
T = h1 + C + Dp;
h1 = h2 + D + Ep;
h2 = h3 + E + Ap;
h3 = h4 + A + Bp;
h4 = h0 + B + Cp;
h0 = T;
}
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
int padding = (n < 56) ? (56 - n) : (120 - n);
byte[] result = new byte[padding + 8];
// padding is always binary 1 followed by binary 0s
result[0] = (byte) 0x80;
// save number of bits, casting the long to an array of 8 bytes
long bits = count << 3;
result[padding++] = (byte) bits;
result[padding++] = (byte) (bits >>> 8);
result[padding++] = (byte) (bits >>> 16);
result[padding++] = (byte) (bits >>> 24);
result[padding++] = (byte) (bits >>> 32);
result[padding++] = (byte) (bits >>> 40);
result[padding++] = (byte) (bits >>> 48);
result[padding] = (byte) (bits >>> 56);
return result;
}
protected byte[] getResult()
{
byte[] result = new byte[] { (byte) h0, (byte) (h0 >>> 8),
(byte) (h0 >>> 16), (byte) (h0 >>> 24),
(byte) h1, (byte) (h1 >>> 8),
(byte) (h1 >>> 16), (byte) (h1 >>> 24),
(byte) h2, (byte) (h2 >>> 8),
(byte) (h2 >>> 16), (byte) (h2 >>> 24),
(byte) h3, (byte) (h3 >>> 8),
(byte) (h3 >>> 16), (byte) (h3 >>> 24),
(byte) h4, (byte) (h4 >>> 8),
(byte) (h4 >>> 16), (byte) (h4 >>> 24) };
return result;
}
protected void resetContext()
{
// magic RIPEMD160 initialisation constants
h0 = 0x67452301;
h1 = 0xEFCDAB89;
h2 = 0x98BADCFE;
h3 = 0x10325476;
h4 = 0xC3D2E1F0;
}
public boolean selfTest()
{
if (valid == null)
{
valid = new Boolean
(DIGEST0.equals(Util.toString(new RipeMD160().digest())));
}
return valid.booleanValue();
}
}
@@ -0,0 +1,308 @@
/* Sha160.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>The Secure Hash Algorithm (SHA-1) is required for use with the Digital
* Signature Algorithm (DSA) as specified in the Digital Signature Standard
* (DSS) and whenever a secure hash algorithm is required for federal
* applications. For a message of length less than 2^64 bits, the SHA-1
* produces a 160-bit condensed representation of the message called a message
* digest. The message digest is used during generation of a signature for the
* message. The SHA-1 is also used to compute a message digest for the received
* version of the message during the process of verifying the signature. Any
* change to the message in transit will, with very high probability, result in
* a different message digest, and the signature will fail to verify.</p>
*
* <p>The SHA-1 is designed to have the following properties: it is
* computationally infeasible to find a message which corresponds to a given
* message digest, or to find two different messages which produce the same
* message digest.</p>
*
* <p>References:</p>
*
* <ol>
* <li><a href="http://www.itl.nist.gov/fipspubs/fip180-1.htm">SECURE HASH
* STANDARD</a><br>
* Federal Information, Processing Standards Publication 180-1, 1995 April 17.
* </li>
* </ol>
*/
public class Sha160 extends BaseHash
{
// Constants and variables
// -------------------------------------------------------------------------
private static final int BLOCK_SIZE = 64; // inner block size in bytes
private static final String DIGEST0 = "A9993E364706816ABA3E25717850C26C9CD0D89D";
private static final int[] w = new int[80];
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
/** 160-bit interim result. */
private int h0, h1, h2, h3, h4;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public Sha160()
{
super(Registry.SHA160_HASH, 20, BLOCK_SIZE);
}
/**
* <p>Private constructor for cloning purposes.</p>
*
* @param md the instance to clone.
*/
private Sha160(Sha160 md)
{
this();
this.h0 = md.h0;
this.h1 = md.h1;
this.h2 = md.h2;
this.h3 = md.h3;
this.h4 = md.h4;
this.count = md.count;
this.buffer = (byte[]) md.buffer.clone();
}
// Class methods
// -------------------------------------------------------------------------
public static final int[] G(int hh0, int hh1, int hh2, int hh3, int hh4,
byte[] in, int offset)
{
// int[] w = new int[80];
// int i, T;
// for (i = 0; i < 16; i++) {
// w[i] = in[offset++] << 24 |
// (in[offset++] & 0xFF) << 16 |
// (in[offset++] & 0xFF) << 8 |
// (in[offset++] & 0xFF);
// }
// for (i = 16; i < 80; i++) {
// T = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
// w[i] = T << 1 | T >>> 31;
// }
// return sha(hh0, hh1, hh2, hh3, hh4, in, offset, w);
return sha(hh0, hh1, hh2, hh3, hh4, in, offset);
}
// Instance methods
// -------------------------------------------------------------------------
// java.lang.Cloneable interface implementation ----------------------------
public Object clone()
{
return new Sha160(this);
}
// Implementation of concrete methods in BaseHash --------------------------
protected void transform(byte[] in, int offset)
{
// int i, T;
// for (i = 0; i < 16; i++) {
// W[i] = in[offset++] << 24 |
// (in[offset++] & 0xFF) << 16 |
// (in[offset++] & 0xFF) << 8 |
// (in[offset++] & 0xFF);
// }
// for (i = 16; i < 80; i++) {
// T = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
// W[i] = T << 1 | T >>> 31;
// }
// int[] result = sha(h0, h1, h2, h3, h4, in, offset, W);
int[] result = sha(h0, h1, h2, h3, h4, in, offset);
h0 = result[0];
h1 = result[1];
h2 = result[2];
h3 = result[3];
h4 = result[4];
}
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
int padding = (n < 56) ? (56 - n) : (120 - n);
byte[] result = new byte[padding + 8];
// padding is always binary 1 followed by binary 0s
result[0] = (byte) 0x80;
// save number of bits, casting the long to an array of 8 bytes
long bits = count << 3;
result[padding++] = (byte) (bits >>> 56);
result[padding++] = (byte) (bits >>> 48);
result[padding++] = (byte) (bits >>> 40);
result[padding++] = (byte) (bits >>> 32);
result[padding++] = (byte) (bits >>> 24);
result[padding++] = (byte) (bits >>> 16);
result[padding++] = (byte) (bits >>> 8);
result[padding] = (byte) bits;
return result;
}
protected byte[] getResult()
{
byte[] result = new byte[] { (byte) (h0 >>> 24), (byte) (h0 >>> 16),
(byte) (h0 >>> 8), (byte) h0,
(byte) (h1 >>> 24), (byte) (h1 >>> 16),
(byte) (h1 >>> 8), (byte) h1,
(byte) (h2 >>> 24), (byte) (h2 >>> 16),
(byte) (h2 >>> 8), (byte) h2,
(byte) (h3 >>> 24), (byte) (h3 >>> 16),
(byte) (h3 >>> 8), (byte) h3,
(byte) (h4 >>> 24), (byte) (h4 >>> 16),
(byte) (h4 >>> 8), (byte) h4 };
return result;
}
protected void resetContext()
{
// magic SHA-1/RIPEMD160 initialisation constants
h0 = 0x67452301;
h1 = 0xEFCDAB89;
h2 = 0x98BADCFE;
h3 = 0x10325476;
h4 = 0xC3D2E1F0;
}
public boolean selfTest()
{
if (valid == null)
{
Sha160 md = new Sha160();
md.update((byte) 0x61); // a
md.update((byte) 0x62); // b
md.update((byte) 0x63); // c
String result = Util.toString(md.digest());
valid = new Boolean(DIGEST0.equals(result));
}
return valid.booleanValue();
}
// SHA specific methods ----------------------------------------------------
private static final synchronized int[]
// sha(int hh0, int hh1, int hh2, int hh3, int hh4, byte[] in, int offset, int[] w) {
sha(int hh0, int hh1, int hh2, int hh3, int hh4, byte[] in, int offset)
{
int A = hh0;
int B = hh1;
int C = hh2;
int D = hh3;
int E = hh4;
int r, T;
for (r = 0; r < 16; r++)
{
w[r] = in[offset++] << 24 | (in[offset++] & 0xFF) << 16
| (in[offset++] & 0xFF) << 8 | (in[offset++] & 0xFF);
}
for (r = 16; r < 80; r++)
{
T = w[r - 3] ^ w[r - 8] ^ w[r - 14] ^ w[r - 16];
w[r] = T << 1 | T >>> 31;
}
// rounds 0-19
for (r = 0; r < 20; r++)
{
T = (A << 5 | A >>> 27) + ((B & C) | (~B & D)) + E + w[r] + 0x5A827999;
E = D;
D = C;
C = B << 30 | B >>> 2;
B = A;
A = T;
}
// rounds 20-39
for (r = 20; r < 40; r++)
{
T = (A << 5 | A >>> 27) + (B ^ C ^ D) + E + w[r] + 0x6ED9EBA1;
E = D;
D = C;
C = B << 30 | B >>> 2;
B = A;
A = T;
}
// rounds 40-59
for (r = 40; r < 60; r++)
{
T = (A << 5 | A >>> 27) + (B & C | B & D | C & D) + E + w[r]
+ 0x8F1BBCDC;
E = D;
D = C;
C = B << 30 | B >>> 2;
B = A;
A = T;
}
// rounds 60-79
for (r = 60; r < 80; r++)
{
T = (A << 5 | A >>> 27) + (B ^ C ^ D) + E + w[r] + 0xCA62C1D6;
E = D;
D = C;
C = B << 30 | B >>> 2;
B = A;
A = T;
}
return new int[] { hh0 + A, hh1 + B, hh2 + C, hh3 + D, hh4 + E };
}
}
@@ -0,0 +1,278 @@
/* Sha256.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>Implementation of SHA2-1 [SHA-256] per the IETF Draft Specification.</p>
*
* <p>References:</p>
* <ol>
* <li><a href="http://ftp.ipv4.heanet.ie/pub/ietf/internet-drafts/draft-ietf-ipsec-ciph-aes-cbc-03.txt">
* Descriptions of SHA-256, SHA-384, and SHA-512</a>,</li>
* <li>http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf</li>
* </ol>
*/
public class Sha256 extends BaseHash
{
// Constants and variables
// -------------------------------------------------------------------------
private static final int[] k = { 0x428a2f98, 0x71374491, 0xb5c0fbcf,
0xe9b5dba5, 0x3956c25b, 0x59f111f1,
0x923f82a4, 0xab1c5ed5, 0xd807aa98,
0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
0xc19bf174, 0xe49b69c1, 0xefbe4786,
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8,
0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
0x06ca6351, 0x14292967, 0x27b70a85,
0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e,
0x92722c85, 0xa2bfe8a1, 0xa81a664b,
0xc24b8b70, 0xc76c51a3, 0xd192e819,
0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c,
0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
0x5b9cca4f, 0x682e6ff3, 0x748f82ee,
0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7,
0xc67178f2 };
private static final int BLOCK_SIZE = 64; // inner block size in bytes
private static final String DIGEST0 = "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD";
private static final int[] w = new int[64];
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
/** 256-bit interim result. */
private int h0, h1, h2, h3, h4, h5, h6, h7;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public Sha256()
{
super(Registry.SHA256_HASH, 32, BLOCK_SIZE);
}
/**
* <p>Private constructor for cloning purposes.</p>
*
* @param md the instance to clone.
*/
private Sha256(Sha256 md)
{
this();
this.h0 = md.h0;
this.h1 = md.h1;
this.h2 = md.h2;
this.h3 = md.h3;
this.h4 = md.h4;
this.h5 = md.h5;
this.h6 = md.h6;
this.h7 = md.h7;
this.count = md.count;
this.buffer = (byte[]) md.buffer.clone();
}
// Class methods
// -------------------------------------------------------------------------
public static final int[] G(int hh0, int hh1, int hh2, int hh3, int hh4,
int hh5, int hh6, int hh7, byte[] in, int offset)
{
return sha(hh0, hh1, hh2, hh3, hh4, hh5, hh6, hh7, in, offset);
}
// Instance methods
// -------------------------------------------------------------------------
// java.lang.Cloneable interface implementation ----------------------------
public Object clone()
{
return new Sha256(this);
}
// Implementation of concrete methods in BaseHash --------------------------
protected void transform(byte[] in, int offset)
{
int[] result = sha(h0, h1, h2, h3, h4, h5, h6, h7, in, offset);
h0 = result[0];
h1 = result[1];
h2 = result[2];
h3 = result[3];
h4 = result[4];
h5 = result[5];
h6 = result[6];
h7 = result[7];
}
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
int padding = (n < 56) ? (56 - n) : (120 - n);
byte[] result = new byte[padding + 8];
// padding is always binary 1 followed by binary 0s
result[0] = (byte) 0x80;
// save number of bits, casting the long to an array of 8 bytes
long bits = count << 3;
result[padding++] = (byte) (bits >>> 56);
result[padding++] = (byte) (bits >>> 48);
result[padding++] = (byte) (bits >>> 40);
result[padding++] = (byte) (bits >>> 32);
result[padding++] = (byte) (bits >>> 24);
result[padding++] = (byte) (bits >>> 16);
result[padding++] = (byte) (bits >>> 8);
result[padding] = (byte) bits;
return result;
}
protected byte[] getResult()
{
return new byte[] { (byte) (h0 >>> 24), (byte) (h0 >>> 16),
(byte) (h0 >>> 8), (byte) h0, (byte) (h1 >>> 24),
(byte) (h1 >>> 16), (byte) (h1 >>> 8), (byte) h1,
(byte) (h2 >>> 24), (byte) (h2 >>> 16),
(byte) (h2 >>> 8), (byte) h2, (byte) (h3 >>> 24),
(byte) (h3 >>> 16), (byte) (h3 >>> 8), (byte) h3,
(byte) (h4 >>> 24), (byte) (h4 >>> 16),
(byte) (h4 >>> 8), (byte) h4, (byte) (h5 >>> 24),
(byte) (h5 >>> 16), (byte) (h5 >>> 8), (byte) h5,
(byte) (h6 >>> 24), (byte) (h6 >>> 16),
(byte) (h6 >>> 8), (byte) h6, (byte) (h7 >>> 24),
(byte) (h7 >>> 16), (byte) (h7 >>> 8), (byte) h7 };
}
protected void resetContext()
{
// magic SHA-256 initialisation constants
h0 = 0x6a09e667;
h1 = 0xbb67ae85;
h2 = 0x3c6ef372;
h3 = 0xa54ff53a;
h4 = 0x510e527f;
h5 = 0x9b05688c;
h6 = 0x1f83d9ab;
h7 = 0x5be0cd19;
}
public boolean selfTest()
{
if (valid == null)
{
Sha256 md = new Sha256();
md.update((byte) 0x61); // a
md.update((byte) 0x62); // b
md.update((byte) 0x63); // c
String result = Util.toString(md.digest());
valid = new Boolean(DIGEST0.equals(result));
}
return valid.booleanValue();
}
// SHA specific methods ----------------------------------------------------
private static final synchronized int[] sha(int hh0, int hh1, int hh2,
int hh3, int hh4, int hh5,
int hh6, int hh7, byte[] in,
int offset)
{
int A = hh0;
int B = hh1;
int C = hh2;
int D = hh3;
int E = hh4;
int F = hh5;
int G = hh6;
int H = hh7;
int r, T, T2;
for (r = 0; r < 16; r++)
{
w[r] = (in[offset++] << 24 | (in[offset++] & 0xFF) << 16
| (in[offset++] & 0xFF) << 8 | (in[offset++] & 0xFF));
}
for (r = 16; r < 64; r++)
{
T = w[r - 2];
T2 = w[r - 15];
w[r] = ((((T >>> 17) | (T << 15)) ^ ((T >>> 19) | (T << 13)) ^ (T >>> 10))
+ w[r - 7]
+ (((T2 >>> 7) | (T2 << 25)) ^ ((T2 >>> 18) | (T2 << 14)) ^ (T2 >>> 3))
+ w[r - 16]);
}
for (r = 0; r < 64; r++)
{
T = (H
+ (((E >>> 6) | (E << 26)) ^ ((E >>> 11) | (E << 21)) ^ ((E >>> 25) | (E << 7)))
+ ((E & F) ^ (~E & G)) + k[r] + w[r]);
T2 = ((((A >>> 2) | (A << 30)) ^ ((A >>> 13) | (A << 19)) ^ ((A >>> 22) | (A << 10)))
+ ((A & B) ^ (A & C) ^ (B & C)));
H = G;
G = F;
F = E;
E = D + T;
D = C;
C = B;
B = A;
A = T + T2;
}
return new int[] { hh0 + A, hh1 + B, hh2 + C, hh3 + D, hh4 + E, hh5 + F,
hh6 + G, hh7 + H };
}
}
@@ -0,0 +1,322 @@
/* Sha384.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>Implementation of SHA2-2 [SHA-384] per the IETF Draft Specification.</p>
*
* <p>References:</p>
* <ol>
* <li><a href="http://ftp.ipv4.heanet.ie/pub/ietf/internet-drafts/draft-ietf-ipsec-ciph-aes-cbc-03.txt">
* Descriptions of SHA-256, SHA-384, and SHA-512</a>,</li>
* <li>http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf</li>
* </ol>
*/
public class Sha384 extends BaseHash
{
// Constants and variables
// -------------------------------------------------------------------------
private static final long[] k = { 0x428a2f98d728ae22L, 0x7137449123ef65cdL,
0xb5c0fbcfec4d3b2fL, 0xe9b5dba58189dbbcL,
0x3956c25bf348b538L, 0x59f111f1b605d019L,
0x923f82a4af194f9bL, 0xab1c5ed5da6d8118L,
0xd807aa98a3030242L, 0x12835b0145706fbeL,
0x243185be4ee4b28cL, 0x550c7dc3d5ffb4e2L,
0x72be5d74f27b896fL, 0x80deb1fe3b1696b1L,
0x9bdc06a725c71235L, 0xc19bf174cf692694L,
0xe49b69c19ef14ad2L, 0xefbe4786384f25e3L,
0x0fc19dc68b8cd5b5L, 0x240ca1cc77ac9c65L,
0x2de92c6f592b0275L, 0x4a7484aa6ea6e483L,
0x5cb0a9dcbd41fbd4L, 0x76f988da831153b5L,
0x983e5152ee66dfabL, 0xa831c66d2db43210L,
0xb00327c898fb213fL, 0xbf597fc7beef0ee4L,
0xc6e00bf33da88fc2L, 0xd5a79147930aa725L,
0x06ca6351e003826fL, 0x142929670a0e6e70L,
0x27b70a8546d22ffcL, 0x2e1b21385c26c926L,
0x4d2c6dfc5ac42aedL, 0x53380d139d95b3dfL,
0x650a73548baf63deL, 0x766a0abb3c77b2a8L,
0x81c2c92e47edaee6L, 0x92722c851482353bL,
0xa2bfe8a14cf10364L, 0xa81a664bbc423001L,
0xc24b8b70d0f89791L, 0xc76c51a30654be30L,
0xd192e819d6ef5218L, 0xd69906245565a910L,
0xf40e35855771202aL, 0x106aa07032bbd1b8L,
0x19a4c116b8d2d0c8L, 0x1e376c085141ab53L,
0x2748774cdf8eeb99L, 0x34b0bcb5e19b48a8L,
0x391c0cb3c5c95a63L, 0x4ed8aa4ae3418acbL,
0x5b9cca4f7763e373L, 0x682e6ff3d6b2b8a3L,
0x748f82ee5defb2fcL, 0x78a5636f43172f60L,
0x84c87814a1f0ab72L, 0x8cc702081a6439ecL,
0x90befffa23631e28L, 0xa4506cebde82bde9L,
0xbef9a3f7b2c67915L, 0xc67178f2e372532bL,
0xca273eceea26619cL, 0xd186b8c721c0c207L,
0xeada7dd6cde0eb1eL, 0xf57d4f7fee6ed178L,
0x06f067aa72176fbaL, 0x0a637dc5a2c898a6L,
0x113f9804bef90daeL, 0x1b710b35131c471bL,
0x28db77f523047d84L, 0x32caab7b40c72493L,
0x3c9ebe0a15c9bebcL, 0x431d67c49c100d4cL,
0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL,
0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L };
private static final int BLOCK_SIZE = 128; // inner block size in bytes
private static final String DIGEST0 = "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED"
+ "8086072BA1E7CC2358BAECA134C825A7";
private static final long[] w = new long[80];
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
/** 512-bit interim result. */
private long h0, h1, h2, h3, h4, h5, h6, h7;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public Sha384()
{
super(Registry.SHA384_HASH, 48, BLOCK_SIZE);
}
/**
* <p>Private constructor for cloning purposes.</p>
*
* @param md the instance to clone.
*/
private Sha384(Sha384 md)
{
this();
this.h0 = md.h0;
this.h1 = md.h1;
this.h2 = md.h2;
this.h3 = md.h3;
this.h4 = md.h4;
this.h5 = md.h5;
this.h6 = md.h6;
this.h7 = md.h7;
this.count = md.count;
this.buffer = (byte[]) md.buffer.clone();
}
// Class methods
// -------------------------------------------------------------------------
public static final long[] G(long hh0, long hh1, long hh2, long hh3,
long hh4, long hh5, long hh6, long hh7,
byte[] in, int offset)
{
return sha(hh0, hh1, hh2, hh3, hh4, hh5, hh6, hh7, in, offset);
}
// Instance methods
// -------------------------------------------------------------------------
// java.lang.Cloneable interface implementation ----------------------------
public Object clone()
{
return new Sha384(this);
}
// Implementation of concrete methods in BaseHash --------------------------
protected void transform(byte[] in, int offset)
{
long[] result = sha(h0, h1, h2, h3, h4, h5, h6, h7, in, offset);
h0 = result[0];
h1 = result[1];
h2 = result[2];
h3 = result[3];
h4 = result[4];
h5 = result[5];
h6 = result[6];
h7 = result[7];
}
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
int padding = (n < 112) ? (112 - n) : (240 - n);
byte[] result = new byte[padding + 16];
// padding is always binary 1 followed by binary 0s
result[0] = (byte) 0x80;
// save number of bits, casting the long to an array of 8 bytes
// TODO: FIX Only ~35 bits of 128 bit counter usable this way
long bits = count << 3;
padding += 8;
result[padding++] = (byte) (bits >>> 56);
result[padding++] = (byte) (bits >>> 48);
result[padding++] = (byte) (bits >>> 40);
result[padding++] = (byte) (bits >>> 32);
result[padding++] = (byte) (bits >>> 24);
result[padding++] = (byte) (bits >>> 16);
result[padding++] = (byte) (bits >>> 8);
result[padding] = (byte) bits;
return result;
}
protected byte[] getResult()
{
return new byte[] { (byte) (h0 >>> 56), (byte) (h0 >>> 48),
(byte) (h0 >>> 40), (byte) (h0 >>> 32),
(byte) (h0 >>> 24), (byte) (h0 >>> 16),
(byte) (h0 >>> 8), (byte) h0, (byte) (h1 >>> 56),
(byte) (h1 >>> 48), (byte) (h1 >>> 40),
(byte) (h1 >>> 32), (byte) (h1 >>> 24),
(byte) (h1 >>> 16), (byte) (h1 >>> 8), (byte) h1,
(byte) (h2 >>> 56), (byte) (h2 >>> 48),
(byte) (h2 >>> 40), (byte) (h2 >>> 32),
(byte) (h2 >>> 24), (byte) (h2 >>> 16),
(byte) (h2 >>> 8), (byte) h2, (byte) (h3 >>> 56),
(byte) (h3 >>> 48), (byte) (h3 >>> 40),
(byte) (h3 >>> 32), (byte) (h3 >>> 24),
(byte) (h3 >>> 16), (byte) (h3 >>> 8), (byte) h3,
(byte) (h4 >>> 56), (byte) (h4 >>> 48),
(byte) (h4 >>> 40), (byte) (h4 >>> 32),
(byte) (h4 >>> 24), (byte) (h4 >>> 16),
(byte) (h4 >>> 8), (byte) h4, (byte) (h5 >>> 56),
(byte) (h5 >>> 48), (byte) (h5 >>> 40),
(byte) (h5 >>> 32), (byte) (h5 >>> 24),
(byte) (h5 >>> 16), (byte) (h5 >>> 8), (byte) h5
// (byte)(h6 >>> 56), (byte)(h6 >>> 48), (byte)(h6 >>> 40), (byte)(h6 >>> 32),
// (byte)(h6 >>> 24), (byte)(h6 >>> 16), (byte)(h6 >>> 8), (byte) h6,
// (byte)(h7 >>> 56), (byte)(h7 >>> 48), (byte)(h7 >>> 40), (byte)(h7 >>> 32),
// (byte)(h7 >>> 24), (byte)(h7 >>> 16), (byte)(h7 >>> 8), (byte) h7
};
}
protected void resetContext()
{
// magic SHA-384 initialisation constants
h0 = 0xcbbb9d5dc1059ed8L;
h1 = 0x629a292a367cd507L;
h2 = 0x9159015a3070dd17L;
h3 = 0x152fecd8f70e5939L;
h4 = 0x67332667ffc00b31L;
h5 = 0x8eb44a8768581511L;
h6 = 0xdb0c2e0d64f98fa7L;
h7 = 0x47b5481dbefa4fa4L;
}
public boolean selfTest()
{
if (valid == null)
{
Sha384 md = new Sha384();
md.update((byte) 0x61); // a
md.update((byte) 0x62); // b
md.update((byte) 0x63); // c
String result = Util.toString(md.digest());
valid = new Boolean(DIGEST0.equals(result));
}
return valid.booleanValue();
}
// SHA specific methods ----------------------------------------------------
private static final synchronized long[] sha(long hh0, long hh1, long hh2,
long hh3, long hh4, long hh5,
long hh6, long hh7, byte[] in,
int offset)
{
long A = hh0;
long B = hh1;
long C = hh2;
long D = hh3;
long E = hh4;
long F = hh5;
long G = hh6;
long H = hh7;
long T, T2;
int r;
for (r = 0; r < 16; r++)
{
w[r] = (long) in[offset++] << 56 | ((long) in[offset++] & 0xFF) << 48
| ((long) in[offset++] & 0xFF) << 40
| ((long) in[offset++] & 0xFF) << 32
| ((long) in[offset++] & 0xFF) << 24
| ((long) in[offset++] & 0xFF) << 16
| ((long) in[offset++] & 0xFF) << 8
| ((long) in[offset++] & 0xFF);
}
for (r = 16; r < 80; r++)
{
T = w[r - 2];
T2 = w[r - 15];
w[r] = (((T >>> 19) | (T << 45)) ^ ((T >>> 61) | (T << 3)) ^ (T >>> 6))
+ w[r - 7]
+ (((T2 >>> 1) | (T2 << 63)) ^ ((T2 >>> 8) | (T2 << 56)) ^ (T2 >>> 7))
+ w[r - 16];
}
for (r = 0; r < 80; r++)
{
T = H
+ (((E >>> 14) | (E << 50)) ^ ((E >>> 18) | (E << 46)) ^ ((E >>> 41) | (E << 23)))
+ ((E & F) ^ ((~E) & G)) + k[r] + w[r];
// T IS INCORRECT SOMEHOW
T2 = (((A >>> 28) | (A << 36)) ^ ((A >>> 34) | (A << 30)) ^ ((A >>> 39) | (A << 25)))
+ ((A & B) ^ (A & C) ^ (B & C));
H = G;
G = F;
F = E;
E = D + T;
D = C;
C = B;
B = A;
A = T + T2;
}
return new long[] { hh0 + A, hh1 + B, hh2 + C, hh3 + D, hh4 + E, hh5 + F,
hh6 + G, hh7 + H };
}
}
@@ -0,0 +1,322 @@
/* Sha512.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>Implementation of SHA2-3 [SHA-512] per the IETF Draft Specification.</p>
*
* <p>References:</p>
* <ol>
* <li><a href="http://ftp.ipv4.heanet.ie/pub/ietf/internet-drafts/draft-ietf-ipsec-ciph-aes-cbc-03.txt">
* Descriptions of SHA-256, SHA-384, and SHA-512</a>,</li>
* <li>http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf</li>
* </ol>
*/
public class Sha512 extends BaseHash
{
// Constants and variables
// -------------------------------------------------------------------------
private static final long[] k = { 0x428a2f98d728ae22L, 0x7137449123ef65cdL,
0xb5c0fbcfec4d3b2fL, 0xe9b5dba58189dbbcL,
0x3956c25bf348b538L, 0x59f111f1b605d019L,
0x923f82a4af194f9bL, 0xab1c5ed5da6d8118L,
0xd807aa98a3030242L, 0x12835b0145706fbeL,
0x243185be4ee4b28cL, 0x550c7dc3d5ffb4e2L,
0x72be5d74f27b896fL, 0x80deb1fe3b1696b1L,
0x9bdc06a725c71235L, 0xc19bf174cf692694L,
0xe49b69c19ef14ad2L, 0xefbe4786384f25e3L,
0x0fc19dc68b8cd5b5L, 0x240ca1cc77ac9c65L,
0x2de92c6f592b0275L, 0x4a7484aa6ea6e483L,
0x5cb0a9dcbd41fbd4L, 0x76f988da831153b5L,
0x983e5152ee66dfabL, 0xa831c66d2db43210L,
0xb00327c898fb213fL, 0xbf597fc7beef0ee4L,
0xc6e00bf33da88fc2L, 0xd5a79147930aa725L,
0x06ca6351e003826fL, 0x142929670a0e6e70L,
0x27b70a8546d22ffcL, 0x2e1b21385c26c926L,
0x4d2c6dfc5ac42aedL, 0x53380d139d95b3dfL,
0x650a73548baf63deL, 0x766a0abb3c77b2a8L,
0x81c2c92e47edaee6L, 0x92722c851482353bL,
0xa2bfe8a14cf10364L, 0xa81a664bbc423001L,
0xc24b8b70d0f89791L, 0xc76c51a30654be30L,
0xd192e819d6ef5218L, 0xd69906245565a910L,
0xf40e35855771202aL, 0x106aa07032bbd1b8L,
0x19a4c116b8d2d0c8L, 0x1e376c085141ab53L,
0x2748774cdf8eeb99L, 0x34b0bcb5e19b48a8L,
0x391c0cb3c5c95a63L, 0x4ed8aa4ae3418acbL,
0x5b9cca4f7763e373L, 0x682e6ff3d6b2b8a3L,
0x748f82ee5defb2fcL, 0x78a5636f43172f60L,
0x84c87814a1f0ab72L, 0x8cc702081a6439ecL,
0x90befffa23631e28L, 0xa4506cebde82bde9L,
0xbef9a3f7b2c67915L, 0xc67178f2e372532bL,
0xca273eceea26619cL, 0xd186b8c721c0c207L,
0xeada7dd6cde0eb1eL, 0xf57d4f7fee6ed178L,
0x06f067aa72176fbaL, 0x0a637dc5a2c898a6L,
0x113f9804bef90daeL, 0x1b710b35131c471bL,
0x28db77f523047d84L, 0x32caab7b40c72493L,
0x3c9ebe0a15c9bebcL, 0x431d67c49c100d4cL,
0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL,
0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L };
private static final int BLOCK_SIZE = 128; // inner block size in bytes
private static final String DIGEST0 = "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A"
+ "2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F";
private static final long[] w = new long[80];
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
/** 512-bit interim result. */
private long h0, h1, h2, h3, h4, h5, h6, h7;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public Sha512()
{
super(Registry.SHA512_HASH, 64, BLOCK_SIZE);
}
/**
* <p>Private constructor for cloning purposes.</p>
*
* @param md the instance to clone.
*/
private Sha512(Sha512 md)
{
this();
this.h0 = md.h0;
this.h1 = md.h1;
this.h2 = md.h2;
this.h3 = md.h3;
this.h4 = md.h4;
this.h5 = md.h5;
this.h6 = md.h6;
this.h7 = md.h7;
this.count = md.count;
this.buffer = (byte[]) md.buffer.clone();
}
// Class methods
// -------------------------------------------------------------------------
public static final long[] G(long hh0, long hh1, long hh2, long hh3,
long hh4, long hh5, long hh6, long hh7,
byte[] in, int offset)
{
return sha(hh0, hh1, hh2, hh3, hh4, hh5, hh6, hh7, in, offset);
}
// Instance methods
// -------------------------------------------------------------------------
// java.lang.Cloneable interface implementation ----------------------------
public Object clone()
{
return new Sha512(this);
}
// Implementation of concrete methods in BaseHash --------------------------
protected void transform(byte[] in, int offset)
{
long[] result = sha(h0, h1, h2, h3, h4, h5, h6, h7, in, offset);
h0 = result[0];
h1 = result[1];
h2 = result[2];
h3 = result[3];
h4 = result[4];
h5 = result[5];
h6 = result[6];
h7 = result[7];
}
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
int padding = (n < 112) ? (112 - n) : (240 - n);
byte[] result = new byte[padding + 16];
// padding is always binary 1 followed by binary 0s
result[0] = (byte) 0x80;
// save number of bits, casting the long to an array of 8 bytes
// TODO: FIX Only ~35 bits of 128 bit counter usable this way
long bits = count << 3;
padding += 8;
result[padding++] = (byte) (bits >>> 56);
result[padding++] = (byte) (bits >>> 48);
result[padding++] = (byte) (bits >>> 40);
result[padding++] = (byte) (bits >>> 32);
result[padding++] = (byte) (bits >>> 24);
result[padding++] = (byte) (bits >>> 16);
result[padding++] = (byte) (bits >>> 8);
result[padding] = (byte) bits;
return result;
}
protected byte[] getResult()
{
return new byte[] { (byte) (h0 >>> 56), (byte) (h0 >>> 48),
(byte) (h0 >>> 40), (byte) (h0 >>> 32),
(byte) (h0 >>> 24), (byte) (h0 >>> 16),
(byte) (h0 >>> 8), (byte) h0, (byte) (h1 >>> 56),
(byte) (h1 >>> 48), (byte) (h1 >>> 40),
(byte) (h1 >>> 32), (byte) (h1 >>> 24),
(byte) (h1 >>> 16), (byte) (h1 >>> 8), (byte) h1,
(byte) (h2 >>> 56), (byte) (h2 >>> 48),
(byte) (h2 >>> 40), (byte) (h2 >>> 32),
(byte) (h2 >>> 24), (byte) (h2 >>> 16),
(byte) (h2 >>> 8), (byte) h2, (byte) (h3 >>> 56),
(byte) (h3 >>> 48), (byte) (h3 >>> 40),
(byte) (h3 >>> 32), (byte) (h3 >>> 24),
(byte) (h3 >>> 16), (byte) (h3 >>> 8), (byte) h3,
(byte) (h4 >>> 56), (byte) (h4 >>> 48),
(byte) (h4 >>> 40), (byte) (h4 >>> 32),
(byte) (h4 >>> 24), (byte) (h4 >>> 16),
(byte) (h4 >>> 8), (byte) h4, (byte) (h5 >>> 56),
(byte) (h5 >>> 48), (byte) (h5 >>> 40),
(byte) (h5 >>> 32), (byte) (h5 >>> 24),
(byte) (h5 >>> 16), (byte) (h5 >>> 8), (byte) h5,
(byte) (h6 >>> 56), (byte) (h6 >>> 48),
(byte) (h6 >>> 40), (byte) (h6 >>> 32),
(byte) (h6 >>> 24), (byte) (h6 >>> 16),
(byte) (h6 >>> 8), (byte) h6, (byte) (h7 >>> 56),
(byte) (h7 >>> 48), (byte) (h7 >>> 40),
(byte) (h7 >>> 32), (byte) (h7 >>> 24),
(byte) (h7 >>> 16), (byte) (h7 >>> 8), (byte) h7 };
}
protected void resetContext()
{
// magic SHA-512 initialisation constants
h0 = 0x6a09e667f3bcc908L;
h1 = 0xbb67ae8584caa73bL;
h2 = 0x3c6ef372fe94f82bL;
h3 = 0xa54ff53a5f1d36f1L;
h4 = 0x510e527fade682d1L;
h5 = 0x9b05688c2b3e6c1fL;
h6 = 0x1f83d9abfb41bd6bL;
h7 = 0x5be0cd19137e2179L;
}
public boolean selfTest()
{
if (valid == null)
{
Sha512 md = new Sha512();
md.update((byte) 0x61); // a
md.update((byte) 0x62); // b
md.update((byte) 0x63); // c
String result = Util.toString(md.digest());
valid = new Boolean(DIGEST0.equals(result));
}
return valid.booleanValue();
}
// SHA specific methods ----------------------------------------------------
private static final synchronized long[] sha(long hh0, long hh1, long hh2,
long hh3, long hh4, long hh5,
long hh6, long hh7, byte[] in,
int offset)
{
long A = hh0;
long B = hh1;
long C = hh2;
long D = hh3;
long E = hh4;
long F = hh5;
long G = hh6;
long H = hh7;
long T, T2;
int r;
for (r = 0; r < 16; r++)
{
w[r] = (long) in[offset++] << 56 | ((long) in[offset++] & 0xFF) << 48
| ((long) in[offset++] & 0xFF) << 40
| ((long) in[offset++] & 0xFF) << 32
| ((long) in[offset++] & 0xFF) << 24
| ((long) in[offset++] & 0xFF) << 16
| ((long) in[offset++] & 0xFF) << 8
| ((long) in[offset++] & 0xFF);
}
for (r = 16; r < 80; r++)
{
T = w[r - 2];
T2 = w[r - 15];
w[r] = (((T >>> 19) | (T << 45)) ^ ((T >>> 61) | (T << 3)) ^ (T >>> 6))
+ w[r - 7]
+ (((T2 >>> 1) | (T2 << 63)) ^ ((T2 >>> 8) | (T2 << 56)) ^ (T2 >>> 7))
+ w[r - 16];
}
for (r = 0; r < 80; r++)
{
T = H
+ (((E >>> 14) | (E << 50)) ^ ((E >>> 18) | (E << 46)) ^ ((E >>> 41) | (E << 23)))
+ ((E & F) ^ ((~E) & G)) + k[r] + w[r];
T2 = (((A >>> 28) | (A << 36)) ^ ((A >>> 34) | (A << 30)) ^ ((A >>> 39) | (A << 25)))
+ ((A & B) ^ (A & C) ^ (B & C));
H = G;
G = F;
F = E;
E = D + T;
D = C;
C = B;
B = A;
A = T + T2;
}
return new long[] { hh0 + A, hh1 + B, hh2 + C, hh3 + D, hh4 + E, hh5 + F,
hh6 + G, hh7 + H };
}
}
@@ -0,0 +1,943 @@
/* Tiger.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* The Tiger message digest. Tiger was designed by Ross Anderson and Eli
* Biham, with the goal of producing a secure, fast hash function that
* performs especially well on next-generation 64-bit architectures, but
* is still efficient on 32- and 16-bit architectures.
*
* <p>Tiger processes data in 512-bit blocks and produces a 192-bit
* digest.</p>
*
* <p>References:</p>
* <ol>
* <li><a
* href="http://www.cs.technion.ac.il/~biham/Reports/Tiger/">Tiger: A
* Fast New Hash Function</a>, Ross Anderson and Eli Biham.</a></li>
* </ol>
*/
public class Tiger extends BaseHash
{
// Constants and variables.
// -----------------------------------------------------------------------
private static final int HASH_SIZE = 24;
private static final int BLOCK_SIZE = 64;
/** Result when no data has been input. */
private static final String DIGEST0 = "3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3";
private static final long A = 0x0123456789ABCDEFL;
private static final long B = 0xFEDCBA9876543210L;
private static final long C = 0xF096A5B4C3B2E187L;
/** S-Box T1. */
private static final long[] T1 = { 0x02AAB17CF7E90C5EL, 0xAC424B03E243A8ECL,
0x72CD5BE30DD5FCD3L, 0x6D019B93F6F97F3AL,
0xCD9978FFD21F9193L, 0x7573A1C9708029E2L,
0xB164326B922A83C3L, 0x46883EEE04915870L,
0xEAACE3057103ECE6L, 0xC54169B808A3535CL,
0x4CE754918DDEC47CL, 0x0AA2F4DFDC0DF40CL,
0x10B76F18A74DBEFAL, 0xC6CCB6235AD1AB6AL,
0x13726121572FE2FFL, 0x1A488C6F199D921EL,
0x4BC9F9F4DA0007CAL, 0x26F5E6F6E85241C7L,
0x859079DBEA5947B6L, 0x4F1885C5C99E8C92L,
0xD78E761EA96F864BL, 0x8E36428C52B5C17DL,
0x69CF6827373063C1L, 0xB607C93D9BB4C56EL,
0x7D820E760E76B5EAL, 0x645C9CC6F07FDC42L,
0xBF38A078243342E0L, 0x5F6B343C9D2E7D04L,
0xF2C28AEB600B0EC6L, 0x6C0ED85F7254BCACL,
0x71592281A4DB4FE5L, 0x1967FA69CE0FED9FL,
0xFD5293F8B96545DBL, 0xC879E9D7F2A7600BL,
0x860248920193194EL, 0xA4F9533B2D9CC0B3L,
0x9053836C15957613L, 0xDB6DCF8AFC357BF1L,
0x18BEEA7A7A370F57L, 0x037117CA50B99066L,
0x6AB30A9774424A35L, 0xF4E92F02E325249BL,
0x7739DB07061CCAE1L, 0xD8F3B49CECA42A05L,
0xBD56BE3F51382F73L, 0x45FAED5843B0BB28L,
0x1C813D5C11BF1F83L, 0x8AF0E4B6D75FA169L,
0x33EE18A487AD9999L, 0x3C26E8EAB1C94410L,
0xB510102BC0A822F9L, 0x141EEF310CE6123BL,
0xFC65B90059DDB154L, 0xE0158640C5E0E607L,
0x884E079826C3A3CFL, 0x930D0D9523C535FDL,
0x35638D754E9A2B00L, 0x4085FCCF40469DD5L,
0xC4B17AD28BE23A4CL, 0xCAB2F0FC6A3E6A2EL,
0x2860971A6B943FCDL, 0x3DDE6EE212E30446L,
0x6222F32AE01765AEL, 0x5D550BB5478308FEL,
0xA9EFA98DA0EDA22AL, 0xC351A71686C40DA7L,
0x1105586D9C867C84L, 0xDCFFEE85FDA22853L,
0xCCFBD0262C5EEF76L, 0xBAF294CB8990D201L,
0xE69464F52AFAD975L, 0x94B013AFDF133E14L,
0x06A7D1A32823C958L, 0x6F95FE5130F61119L,
0xD92AB34E462C06C0L, 0xED7BDE33887C71D2L,
0x79746D6E6518393EL, 0x5BA419385D713329L,
0x7C1BA6B948A97564L, 0x31987C197BFDAC67L,
0xDE6C23C44B053D02L, 0x581C49FED002D64DL,
0xDD474D6338261571L, 0xAA4546C3E473D062L,
0x928FCE349455F860L, 0x48161BBACAAB94D9L,
0x63912430770E6F68L, 0x6EC8A5E602C6641CL,
0x87282515337DDD2BL, 0x2CDA6B42034B701BL,
0xB03D37C181CB096DL, 0xE108438266C71C6FL,
0x2B3180C7EB51B255L, 0xDF92B82F96C08BBCL,
0x5C68C8C0A632F3BAL, 0x5504CC861C3D0556L,
0xABBFA4E55FB26B8FL, 0x41848B0AB3BACEB4L,
0xB334A273AA445D32L, 0xBCA696F0A85AD881L,
0x24F6EC65B528D56CL, 0x0CE1512E90F4524AL,
0x4E9DD79D5506D35AL, 0x258905FAC6CE9779L,
0x2019295B3E109B33L, 0xF8A9478B73A054CCL,
0x2924F2F934417EB0L, 0x3993357D536D1BC4L,
0x38A81AC21DB6FF8BL, 0x47C4FBF17D6016BFL,
0x1E0FAADD7667E3F5L, 0x7ABCFF62938BEB96L,
0xA78DAD948FC179C9L, 0x8F1F98B72911E50DL,
0x61E48EAE27121A91L, 0x4D62F7AD31859808L,
0xECEBA345EF5CEAEBL, 0xF5CEB25EBC9684CEL,
0xF633E20CB7F76221L, 0xA32CDF06AB8293E4L,
0x985A202CA5EE2CA4L, 0xCF0B8447CC8A8FB1L,
0x9F765244979859A3L, 0xA8D516B1A1240017L,
0x0BD7BA3EBB5DC726L, 0xE54BCA55B86ADB39L,
0x1D7A3AFD6C478063L, 0x519EC608E7669EDDL,
0x0E5715A2D149AA23L, 0x177D4571848FF194L,
0xEEB55F3241014C22L, 0x0F5E5CA13A6E2EC2L,
0x8029927B75F5C361L, 0xAD139FABC3D6E436L,
0x0D5DF1A94CCF402FL, 0x3E8BD948BEA5DFC8L,
0xA5A0D357BD3FF77EL, 0xA2D12E251F74F645L,
0x66FD9E525E81A082L, 0x2E0C90CE7F687A49L,
0xC2E8BCBEBA973BC5L, 0x000001BCE509745FL,
0x423777BBE6DAB3D6L, 0xD1661C7EAEF06EB5L,
0xA1781F354DAACFD8L, 0x2D11284A2B16AFFCL,
0xF1FC4F67FA891D1FL, 0x73ECC25DCB920ADAL,
0xAE610C22C2A12651L, 0x96E0A810D356B78AL,
0x5A9A381F2FE7870FL, 0xD5AD62EDE94E5530L,
0xD225E5E8368D1427L, 0x65977B70C7AF4631L,
0x99F889B2DE39D74FL, 0x233F30BF54E1D143L,
0x9A9675D3D9A63C97L, 0x5470554FF334F9A8L,
0x166ACB744A4F5688L, 0x70C74CAAB2E4AEADL,
0xF0D091646F294D12L, 0x57B82A89684031D1L,
0xEFD95A5A61BE0B6BL, 0x2FBD12E969F2F29AL,
0x9BD37013FEFF9FE8L, 0x3F9B0404D6085A06L,
0x4940C1F3166CFE15L, 0x09542C4DCDF3DEFBL,
0xB4C5218385CD5CE3L, 0xC935B7DC4462A641L,
0x3417F8A68ED3B63FL, 0xB80959295B215B40L,
0xF99CDAEF3B8C8572L, 0x018C0614F8FCB95DL,
0x1B14ACCD1A3ACDF3L, 0x84D471F200BB732DL,
0xC1A3110E95E8DA16L, 0x430A7220BF1A82B8L,
0xB77E090D39DF210EL, 0x5EF4BD9F3CD05E9DL,
0x9D4FF6DA7E57A444L, 0xDA1D60E183D4A5F8L,
0xB287C38417998E47L, 0xFE3EDC121BB31886L,
0xC7FE3CCC980CCBEFL, 0xE46FB590189BFD03L,
0x3732FD469A4C57DCL, 0x7EF700A07CF1AD65L,
0x59C64468A31D8859L, 0x762FB0B4D45B61F6L,
0x155BAED099047718L, 0x68755E4C3D50BAA6L,
0xE9214E7F22D8B4DFL, 0x2ADDBF532EAC95F4L,
0x32AE3909B4BD0109L, 0x834DF537B08E3450L,
0xFA209DA84220728DL, 0x9E691D9B9EFE23F7L,
0x0446D288C4AE8D7FL, 0x7B4CC524E169785BL,
0x21D87F0135CA1385L, 0xCEBB400F137B8AA5L,
0x272E2B66580796BEL, 0x3612264125C2B0DEL,
0x057702BDAD1EFBB2L, 0xD4BABB8EACF84BE9L,
0x91583139641BC67BL, 0x8BDC2DE08036E024L,
0x603C8156F49F68EDL, 0xF7D236F7DBEF5111L,
0x9727C4598AD21E80L, 0xA08A0896670A5FD7L,
0xCB4A8F4309EBA9CBL, 0x81AF564B0F7036A1L,
0xC0B99AA778199ABDL, 0x959F1EC83FC8E952L,
0x8C505077794A81B9L, 0x3ACAAF8F056338F0L,
0x07B43F50627A6778L, 0x4A44AB49F5ECCC77L,
0x3BC3D6E4B679EE98L, 0x9CC0D4D1CF14108CL,
0x4406C00B206BC8A0L, 0x82A18854C8D72D89L,
0x67E366B35C3C432CL, 0xB923DD61102B37F2L,
0x56AB2779D884271DL, 0xBE83E1B0FF1525AFL,
0xFB7C65D4217E49A9L, 0x6BDBE0E76D48E7D4L,
0x08DF828745D9179EL, 0x22EA6A9ADD53BD34L,
0xE36E141C5622200AL, 0x7F805D1B8CB750EEL,
0xAFE5C7A59F58E837L, 0xE27F996A4FB1C23CL,
0xD3867DFB0775F0D0L, 0xD0E673DE6E88891AL,
0x123AEB9EAFB86C25L, 0x30F1D5D5C145B895L,
0xBB434A2DEE7269E7L, 0x78CB67ECF931FA38L,
0xF33B0372323BBF9CL, 0x52D66336FB279C74L,
0x505F33AC0AFB4EAAL, 0xE8A5CD99A2CCE187L,
0x534974801E2D30BBL, 0x8D2D5711D5876D90L,
0x1F1A412891BC038EL, 0xD6E2E71D82E56648L,
0x74036C3A497732B7L, 0x89B67ED96361F5ABL,
0xFFED95D8F1EA02A2L, 0xE72B3BD61464D43DL,
0xA6300F170BDC4820L, 0xEBC18760ED78A77AL };
/** S-Box T2. */
private static final long[] T2 = { 0xE6A6BE5A05A12138L, 0xB5A122A5B4F87C98L,
0x563C6089140B6990L, 0x4C46CB2E391F5DD5L,
0xD932ADDBC9B79434L, 0x08EA70E42015AFF5L,
0xD765A6673E478CF1L, 0xC4FB757EAB278D99L,
0xDF11C6862D6E0692L, 0xDDEB84F10D7F3B16L,
0x6F2EF604A665EA04L, 0x4A8E0F0FF0E0DFB3L,
0xA5EDEEF83DBCBA51L, 0xFC4F0A2A0EA4371EL,
0xE83E1DA85CB38429L, 0xDC8FF882BA1B1CE2L,
0xCD45505E8353E80DL, 0x18D19A00D4DB0717L,
0x34A0CFEDA5F38101L, 0x0BE77E518887CAF2L,
0x1E341438B3C45136L, 0xE05797F49089CCF9L,
0xFFD23F9DF2591D14L, 0x543DDA228595C5CDL,
0x661F81FD99052A33L, 0x8736E641DB0F7B76L,
0x15227725418E5307L, 0xE25F7F46162EB2FAL,
0x48A8B2126C13D9FEL, 0xAFDC541792E76EEAL,
0x03D912BFC6D1898FL, 0x31B1AAFA1B83F51BL,
0xF1AC2796E42AB7D9L, 0x40A3A7D7FCD2EBACL,
0x1056136D0AFBBCC5L, 0x7889E1DD9A6D0C85L,
0xD33525782A7974AAL, 0xA7E25D09078AC09BL,
0xBD4138B3EAC6EDD0L, 0x920ABFBE71EB9E70L,
0xA2A5D0F54FC2625CL, 0xC054E36B0B1290A3L,
0xF6DD59FF62FE932BL, 0x3537354511A8AC7DL,
0xCA845E9172FADCD4L, 0x84F82B60329D20DCL,
0x79C62CE1CD672F18L, 0x8B09A2ADD124642CL,
0xD0C1E96A19D9E726L, 0x5A786A9B4BA9500CL,
0x0E020336634C43F3L, 0xC17B474AEB66D822L,
0x6A731AE3EC9BAAC2L, 0x8226667AE0840258L,
0x67D4567691CAECA5L, 0x1D94155C4875ADB5L,
0x6D00FD985B813FDFL, 0x51286EFCB774CD06L,
0x5E8834471FA744AFL, 0xF72CA0AEE761AE2EL,
0xBE40E4CDAEE8E09AL, 0xE9970BBB5118F665L,
0x726E4BEB33DF1964L, 0x703B000729199762L,
0x4631D816F5EF30A7L, 0xB880B5B51504A6BEL,
0x641793C37ED84B6CL, 0x7B21ED77F6E97D96L,
0x776306312EF96B73L, 0xAE528948E86FF3F4L,
0x53DBD7F286A3F8F8L, 0x16CADCE74CFC1063L,
0x005C19BDFA52C6DDL, 0x68868F5D64D46AD3L,
0x3A9D512CCF1E186AL, 0x367E62C2385660AEL,
0xE359E7EA77DCB1D7L, 0x526C0773749ABE6EL,
0x735AE5F9D09F734BL, 0x493FC7CC8A558BA8L,
0xB0B9C1533041AB45L, 0x321958BA470A59BDL,
0x852DB00B5F46C393L, 0x91209B2BD336B0E5L,
0x6E604F7D659EF19FL, 0xB99A8AE2782CCB24L,
0xCCF52AB6C814C4C7L, 0x4727D9AFBE11727BL,
0x7E950D0C0121B34DL, 0x756F435670AD471FL,
0xF5ADD442615A6849L, 0x4E87E09980B9957AL,
0x2ACFA1DF50AEE355L, 0xD898263AFD2FD556L,
0xC8F4924DD80C8FD6L, 0xCF99CA3D754A173AL,
0xFE477BACAF91BF3CL, 0xED5371F6D690C12DL,
0x831A5C285E687094L, 0xC5D3C90A3708A0A4L,
0x0F7F903717D06580L, 0x19F9BB13B8FDF27FL,
0xB1BD6F1B4D502843L, 0x1C761BA38FFF4012L,
0x0D1530C4E2E21F3BL, 0x8943CE69A7372C8AL,
0xE5184E11FEB5CE66L, 0x618BDB80BD736621L,
0x7D29BAD68B574D0BL, 0x81BB613E25E6FE5BL,
0x071C9C10BC07913FL, 0xC7BEEB7909AC2D97L,
0xC3E58D353BC5D757L, 0xEB017892F38F61E8L,
0xD4EFFB9C9B1CC21AL, 0x99727D26F494F7ABL,
0xA3E063A2956B3E03L, 0x9D4A8B9A4AA09C30L,
0x3F6AB7D500090FB4L, 0x9CC0F2A057268AC0L,
0x3DEE9D2DEDBF42D1L, 0x330F49C87960A972L,
0xC6B2720287421B41L, 0x0AC59EC07C00369CL,
0xEF4EAC49CB353425L, 0xF450244EEF0129D8L,
0x8ACC46E5CAF4DEB6L, 0x2FFEAB63989263F7L,
0x8F7CB9FE5D7A4578L, 0x5BD8F7644E634635L,
0x427A7315BF2DC900L, 0x17D0C4AA2125261CL,
0x3992486C93518E50L, 0xB4CBFEE0A2D7D4C3L,
0x7C75D6202C5DDD8DL, 0xDBC295D8E35B6C61L,
0x60B369D302032B19L, 0xCE42685FDCE44132L,
0x06F3DDB9DDF65610L, 0x8EA4D21DB5E148F0L,
0x20B0FCE62FCD496FL, 0x2C1B912358B0EE31L,
0xB28317B818F5A308L, 0xA89C1E189CA6D2CFL,
0x0C6B18576AAADBC8L, 0xB65DEAA91299FAE3L,
0xFB2B794B7F1027E7L, 0x04E4317F443B5BEBL,
0x4B852D325939D0A6L, 0xD5AE6BEEFB207FFCL,
0x309682B281C7D374L, 0xBAE309A194C3B475L,
0x8CC3F97B13B49F05L, 0x98A9422FF8293967L,
0x244B16B01076FF7CL, 0xF8BF571C663D67EEL,
0x1F0D6758EEE30DA1L, 0xC9B611D97ADEB9B7L,
0xB7AFD5887B6C57A2L, 0x6290AE846B984FE1L,
0x94DF4CDEACC1A5FDL, 0x058A5BD1C5483AFFL,
0x63166CC142BA3C37L, 0x8DB8526EB2F76F40L,
0xE10880036F0D6D4EL, 0x9E0523C9971D311DL,
0x45EC2824CC7CD691L, 0x575B8359E62382C9L,
0xFA9E400DC4889995L, 0xD1823ECB45721568L,
0xDAFD983B8206082FL, 0xAA7D29082386A8CBL,
0x269FCD4403B87588L, 0x1B91F5F728BDD1E0L,
0xE4669F39040201F6L, 0x7A1D7C218CF04ADEL,
0x65623C29D79CE5CEL, 0x2368449096C00BB1L,
0xAB9BF1879DA503BAL, 0xBC23ECB1A458058EL,
0x9A58DF01BB401ECCL, 0xA070E868A85F143DL,
0x4FF188307DF2239EL, 0x14D565B41A641183L,
0xEE13337452701602L, 0x950E3DCF3F285E09L,
0x59930254B9C80953L, 0x3BF299408930DA6DL,
0xA955943F53691387L, 0xA15EDECAA9CB8784L,
0x29142127352BE9A0L, 0x76F0371FFF4E7AFBL,
0x0239F450274F2228L, 0xBB073AF01D5E868BL,
0xBFC80571C10E96C1L, 0xD267088568222E23L,
0x9671A3D48E80B5B0L, 0x55B5D38AE193BB81L,
0x693AE2D0A18B04B8L, 0x5C48B4ECADD5335FL,
0xFD743B194916A1CAL, 0x2577018134BE98C4L,
0xE77987E83C54A4ADL, 0x28E11014DA33E1B9L,
0x270CC59E226AA213L, 0x71495F756D1A5F60L,
0x9BE853FB60AFEF77L, 0xADC786A7F7443DBFL,
0x0904456173B29A82L, 0x58BC7A66C232BD5EL,
0xF306558C673AC8B2L, 0x41F639C6B6C9772AL,
0x216DEFE99FDA35DAL, 0x11640CC71C7BE615L,
0x93C43694565C5527L, 0xEA038E6246777839L,
0xF9ABF3CE5A3E2469L, 0x741E768D0FD312D2L,
0x0144B883CED652C6L, 0xC20B5A5BA33F8552L,
0x1AE69633C3435A9DL, 0x97A28CA4088CFDECL,
0x8824A43C1E96F420L, 0x37612FA66EEEA746L,
0x6B4CB165F9CF0E5AL, 0x43AA1C06A0ABFB4AL,
0x7F4DC26FF162796BL, 0x6CBACC8E54ED9B0FL,
0xA6B7FFEFD2BB253EL, 0x2E25BC95B0A29D4FL,
0x86D6A58BDEF1388CL, 0xDED74AC576B6F054L,
0x8030BDBC2B45805DL, 0x3C81AF70E94D9289L,
0x3EFF6DDA9E3100DBL, 0xB38DC39FDFCC8847L,
0x123885528D17B87EL, 0xF2DA0ED240B1B642L,
0x44CEFADCD54BF9A9L, 0x1312200E433C7EE6L,
0x9FFCC84F3A78C748L, 0xF0CD1F72248576BBL,
0xEC6974053638CFE4L, 0x2BA7B67C0CEC4E4CL,
0xAC2F4DF3E5CE32EDL, 0xCB33D14326EA4C11L,
0xA4E9044CC77E58BCL, 0x5F513293D934FCEFL,
0x5DC9645506E55444L, 0x50DE418F317DE40AL,
0x388CB31A69DDE259L, 0x2DB4A83455820A86L,
0x9010A91E84711AE9L, 0x4DF7F0B7B1498371L,
0xD62A2EABC0977179L, 0x22FAC097AA8D5C0EL };
/** S-Box T3. */
private static final long[] T3 = { 0xF49FCC2FF1DAF39BL, 0x487FD5C66FF29281L,
0xE8A30667FCDCA83FL, 0x2C9B4BE3D2FCCE63L,
0xDA3FF74B93FBBBC2L, 0x2FA165D2FE70BA66L,
0xA103E279970E93D4L, 0xBECDEC77B0E45E71L,
0xCFB41E723985E497L, 0xB70AAA025EF75017L,
0xD42309F03840B8E0L, 0x8EFC1AD035898579L,
0x96C6920BE2B2ABC5L, 0x66AF4163375A9172L,
0x2174ABDCCA7127FBL, 0xB33CCEA64A72FF41L,
0xF04A4933083066A5L, 0x8D970ACDD7289AF5L,
0x8F96E8E031C8C25EL, 0xF3FEC02276875D47L,
0xEC7BF310056190DDL, 0xF5ADB0AEBB0F1491L,
0x9B50F8850FD58892L, 0x4975488358B74DE8L,
0xA3354FF691531C61L, 0x0702BBE481D2C6EEL,
0x89FB24057DEDED98L, 0xAC3075138596E902L,
0x1D2D3580172772EDL, 0xEB738FC28E6BC30DL,
0x5854EF8F63044326L, 0x9E5C52325ADD3BBEL,
0x90AA53CF325C4623L, 0xC1D24D51349DD067L,
0x2051CFEEA69EA624L, 0x13220F0A862E7E4FL,
0xCE39399404E04864L, 0xD9C42CA47086FCB7L,
0x685AD2238A03E7CCL, 0x066484B2AB2FF1DBL,
0xFE9D5D70EFBF79ECL, 0x5B13B9DD9C481854L,
0x15F0D475ED1509ADL, 0x0BEBCD060EC79851L,
0xD58C6791183AB7F8L, 0xD1187C5052F3EEE4L,
0xC95D1192E54E82FFL, 0x86EEA14CB9AC6CA2L,
0x3485BEB153677D5DL, 0xDD191D781F8C492AL,
0xF60866BAA784EBF9L, 0x518F643BA2D08C74L,
0x8852E956E1087C22L, 0xA768CB8DC410AE8DL,
0x38047726BFEC8E1AL, 0xA67738B4CD3B45AAL,
0xAD16691CEC0DDE19L, 0xC6D4319380462E07L,
0xC5A5876D0BA61938L, 0x16B9FA1FA58FD840L,
0x188AB1173CA74F18L, 0xABDA2F98C99C021FL,
0x3E0580AB134AE816L, 0x5F3B05B773645ABBL,
0x2501A2BE5575F2F6L, 0x1B2F74004E7E8BA9L,
0x1CD7580371E8D953L, 0x7F6ED89562764E30L,
0xB15926FF596F003DL, 0x9F65293DA8C5D6B9L,
0x6ECEF04DD690F84CL, 0x4782275FFF33AF88L,
0xE41433083F820801L, 0xFD0DFE409A1AF9B5L,
0x4325A3342CDB396BL, 0x8AE77E62B301B252L,
0xC36F9E9F6655615AL, 0x85455A2D92D32C09L,
0xF2C7DEA949477485L, 0x63CFB4C133A39EBAL,
0x83B040CC6EBC5462L, 0x3B9454C8FDB326B0L,
0x56F56A9E87FFD78CL, 0x2DC2940D99F42BC6L,
0x98F7DF096B096E2DL, 0x19A6E01E3AD852BFL,
0x42A99CCBDBD4B40BL, 0xA59998AF45E9C559L,
0x366295E807D93186L, 0x6B48181BFAA1F773L,
0x1FEC57E2157A0A1DL, 0x4667446AF6201AD5L,
0xE615EBCACFB0F075L, 0xB8F31F4F68290778L,
0x22713ED6CE22D11EL, 0x3057C1A72EC3C93BL,
0xCB46ACC37C3F1F2FL, 0xDBB893FD02AAF50EL,
0x331FD92E600B9FCFL, 0xA498F96148EA3AD6L,
0xA8D8426E8B6A83EAL, 0xA089B274B7735CDCL,
0x87F6B3731E524A11L, 0x118808E5CBC96749L,
0x9906E4C7B19BD394L, 0xAFED7F7E9B24A20CL,
0x6509EADEEB3644A7L, 0x6C1EF1D3E8EF0EDEL,
0xB9C97D43E9798FB4L, 0xA2F2D784740C28A3L,
0x7B8496476197566FL, 0x7A5BE3E6B65F069DL,
0xF96330ED78BE6F10L, 0xEEE60DE77A076A15L,
0x2B4BEE4AA08B9BD0L, 0x6A56A63EC7B8894EL,
0x02121359BA34FEF4L, 0x4CBF99F8283703FCL,
0x398071350CAF30C8L, 0xD0A77A89F017687AL,
0xF1C1A9EB9E423569L, 0x8C7976282DEE8199L,
0x5D1737A5DD1F7ABDL, 0x4F53433C09A9FA80L,
0xFA8B0C53DF7CA1D9L, 0x3FD9DCBC886CCB77L,
0xC040917CA91B4720L, 0x7DD00142F9D1DCDFL,
0x8476FC1D4F387B58L, 0x23F8E7C5F3316503L,
0x032A2244E7E37339L, 0x5C87A5D750F5A74BL,
0x082B4CC43698992EL, 0xDF917BECB858F63CL,
0x3270B8FC5BF86DDAL, 0x10AE72BB29B5DD76L,
0x576AC94E7700362BL, 0x1AD112DAC61EFB8FL,
0x691BC30EC5FAA427L, 0xFF246311CC327143L,
0x3142368E30E53206L, 0x71380E31E02CA396L,
0x958D5C960AAD76F1L, 0xF8D6F430C16DA536L,
0xC8FFD13F1BE7E1D2L, 0x7578AE66004DDBE1L,
0x05833F01067BE646L, 0xBB34B5AD3BFE586DL,
0x095F34C9A12B97F0L, 0x247AB64525D60CA8L,
0xDCDBC6F3017477D1L, 0x4A2E14D4DECAD24DL,
0xBDB5E6D9BE0A1EEBL, 0x2A7E70F7794301ABL,
0xDEF42D8A270540FDL, 0x01078EC0A34C22C1L,
0xE5DE511AF4C16387L, 0x7EBB3A52BD9A330AL,
0x77697857AA7D6435L, 0x004E831603AE4C32L,
0xE7A21020AD78E312L, 0x9D41A70C6AB420F2L,
0x28E06C18EA1141E6L, 0xD2B28CBD984F6B28L,
0x26B75F6C446E9D83L, 0xBA47568C4D418D7FL,
0xD80BADBFE6183D8EL, 0x0E206D7F5F166044L,
0xE258A43911CBCA3EL, 0x723A1746B21DC0BCL,
0xC7CAA854F5D7CDD3L, 0x7CAC32883D261D9CL,
0x7690C26423BA942CL, 0x17E55524478042B8L,
0xE0BE477656A2389FL, 0x4D289B5E67AB2DA0L,
0x44862B9C8FBBFD31L, 0xB47CC8049D141365L,
0x822C1B362B91C793L, 0x4EB14655FB13DFD8L,
0x1ECBBA0714E2A97BL, 0x6143459D5CDE5F14L,
0x53A8FBF1D5F0AC89L, 0x97EA04D81C5E5B00L,
0x622181A8D4FDB3F3L, 0xE9BCD341572A1208L,
0x1411258643CCE58AL, 0x9144C5FEA4C6E0A4L,
0x0D33D06565CF620FL, 0x54A48D489F219CA1L,
0xC43E5EAC6D63C821L, 0xA9728B3A72770DAFL,
0xD7934E7B20DF87EFL, 0xE35503B61A3E86E5L,
0xCAE321FBC819D504L, 0x129A50B3AC60BFA6L,
0xCD5E68EA7E9FB6C3L, 0xB01C90199483B1C7L,
0x3DE93CD5C295376CL, 0xAED52EDF2AB9AD13L,
0x2E60F512C0A07884L, 0xBC3D86A3E36210C9L,
0x35269D9B163951CEL, 0x0C7D6E2AD0CDB5FAL,
0x59E86297D87F5733L, 0x298EF221898DB0E7L,
0x55000029D1A5AA7EL, 0x8BC08AE1B5061B45L,
0xC2C31C2B6C92703AL, 0x94CC596BAF25EF42L,
0x0A1D73DB22540456L, 0x04B6A0F9D9C4179AL,
0xEFFDAFA2AE3D3C60L, 0xF7C8075BB49496C4L,
0x9CC5C7141D1CD4E3L, 0x78BD1638218E5534L,
0xB2F11568F850246AL, 0xEDFABCFA9502BC29L,
0x796CE5F2DA23051BL, 0xAAE128B0DC93537CL,
0x3A493DA0EE4B29AEL, 0xB5DF6B2C416895D7L,
0xFCABBD25122D7F37L, 0x70810B58105DC4B1L,
0xE10FDD37F7882A90L, 0x524DCAB5518A3F5CL,
0x3C9E85878451255BL, 0x4029828119BD34E2L,
0x74A05B6F5D3CECCBL, 0xB610021542E13ECAL,
0x0FF979D12F59E2ACL, 0x6037DA27E4F9CC50L,
0x5E92975A0DF1847DL, 0xD66DE190D3E623FEL,
0x5032D6B87B568048L, 0x9A36B7CE8235216EL,
0x80272A7A24F64B4AL, 0x93EFED8B8C6916F7L,
0x37DDBFF44CCE1555L, 0x4B95DB5D4B99BD25L,
0x92D3FDA169812FC0L, 0xFB1A4A9A90660BB6L,
0x730C196946A4B9B2L, 0x81E289AA7F49DA68L,
0x64669A0F83B1A05FL, 0x27B3FF7D9644F48BL,
0xCC6B615C8DB675B3L, 0x674F20B9BCEBBE95L,
0x6F31238275655982L, 0x5AE488713E45CF05L,
0xBF619F9954C21157L, 0xEABAC46040A8EAE9L,
0x454C6FE9F2C0C1CDL, 0x419CF6496412691CL,
0xD3DC3BEF265B0F70L, 0x6D0E60F5C3578A9EL };
/** S-Box T4. */
private static final long[] T4 = { 0x5B0E608526323C55L, 0x1A46C1A9FA1B59F5L,
0xA9E245A17C4C8FFAL, 0x65CA5159DB2955D7L,
0x05DB0A76CE35AFC2L, 0x81EAC77EA9113D45L,
0x528EF88AB6AC0A0DL, 0xA09EA253597BE3FFL,
0x430DDFB3AC48CD56L, 0xC4B3A67AF45CE46FL,
0x4ECECFD8FBE2D05EL, 0x3EF56F10B39935F0L,
0x0B22D6829CD619C6L, 0x17FD460A74DF2069L,
0x6CF8CC8E8510ED40L, 0xD6C824BF3A6ECAA7L,
0x61243D581A817049L, 0x048BACB6BBC163A2L,
0xD9A38AC27D44CC32L, 0x7FDDFF5BAAF410ABL,
0xAD6D495AA804824BL, 0xE1A6A74F2D8C9F94L,
0xD4F7851235DEE8E3L, 0xFD4B7F886540D893L,
0x247C20042AA4BFDAL, 0x096EA1C517D1327CL,
0xD56966B4361A6685L, 0x277DA5C31221057DL,
0x94D59893A43ACFF7L, 0x64F0C51CCDC02281L,
0x3D33BCC4FF6189DBL, 0xE005CB184CE66AF1L,
0xFF5CCD1D1DB99BEAL, 0xB0B854A7FE42980FL,
0x7BD46A6A718D4B9FL, 0xD10FA8CC22A5FD8CL,
0xD31484952BE4BD31L, 0xC7FA975FCB243847L,
0x4886ED1E5846C407L, 0x28CDDB791EB70B04L,
0xC2B00BE2F573417FL, 0x5C9590452180F877L,
0x7A6BDDFFF370EB00L, 0xCE509E38D6D9D6A4L,
0xEBEB0F00647FA702L, 0x1DCC06CF76606F06L,
0xE4D9F28BA286FF0AL, 0xD85A305DC918C262L,
0x475B1D8732225F54L, 0x2D4FB51668CCB5FEL,
0xA679B9D9D72BBA20L, 0x53841C0D912D43A5L,
0x3B7EAA48BF12A4E8L, 0x781E0E47F22F1DDFL,
0xEFF20CE60AB50973L, 0x20D261D19DFFB742L,
0x16A12B03062A2E39L, 0x1960EB2239650495L,
0x251C16FED50EB8B8L, 0x9AC0C330F826016EL,
0xED152665953E7671L, 0x02D63194A6369570L,
0x5074F08394B1C987L, 0x70BA598C90B25CE1L,
0x794A15810B9742F6L, 0x0D5925E9FCAF8C6CL,
0x3067716CD868744EL, 0x910AB077E8D7731BL,
0x6A61BBDB5AC42F61L, 0x93513EFBF0851567L,
0xF494724B9E83E9D5L, 0xE887E1985C09648DL,
0x34B1D3C675370CFDL, 0xDC35E433BC0D255DL,
0xD0AAB84234131BE0L, 0x08042A50B48B7EAFL,
0x9997C4EE44A3AB35L, 0x829A7B49201799D0L,
0x263B8307B7C54441L, 0x752F95F4FD6A6CA6L,
0x927217402C08C6E5L, 0x2A8AB754A795D9EEL,
0xA442F7552F72943DL, 0x2C31334E19781208L,
0x4FA98D7CEAEE6291L, 0x55C3862F665DB309L,
0xBD0610175D53B1F3L, 0x46FE6CB840413F27L,
0x3FE03792DF0CFA59L, 0xCFE700372EB85E8FL,
0xA7BE29E7ADBCE118L, 0xE544EE5CDE8431DDL,
0x8A781B1B41F1873EL, 0xA5C94C78A0D2F0E7L,
0x39412E2877B60728L, 0xA1265EF3AFC9A62CL,
0xBCC2770C6A2506C5L, 0x3AB66DD5DCE1CE12L,
0xE65499D04A675B37L, 0x7D8F523481BFD216L,
0x0F6F64FCEC15F389L, 0x74EFBE618B5B13C8L,
0xACDC82B714273E1DL, 0xDD40BFE003199D17L,
0x37E99257E7E061F8L, 0xFA52626904775AAAL,
0x8BBBF63A463D56F9L, 0xF0013F1543A26E64L,
0xA8307E9F879EC898L, 0xCC4C27A4150177CCL,
0x1B432F2CCA1D3348L, 0xDE1D1F8F9F6FA013L,
0x606602A047A7DDD6L, 0xD237AB64CC1CB2C7L,
0x9B938E7225FCD1D3L, 0xEC4E03708E0FF476L,
0xFEB2FBDA3D03C12DL, 0xAE0BCED2EE43889AL,
0x22CB8923EBFB4F43L, 0x69360D013CF7396DL,
0x855E3602D2D4E022L, 0x073805BAD01F784CL,
0x33E17A133852F546L, 0xDF4874058AC7B638L,
0xBA92B29C678AA14AL, 0x0CE89FC76CFAADCDL,
0x5F9D4E0908339E34L, 0xF1AFE9291F5923B9L,
0x6E3480F60F4A265FL, 0xEEBF3A2AB29B841CL,
0xE21938A88F91B4ADL, 0x57DFEFF845C6D3C3L,
0x2F006B0BF62CAAF2L, 0x62F479EF6F75EE78L,
0x11A55AD41C8916A9L, 0xF229D29084FED453L,
0x42F1C27B16B000E6L, 0x2B1F76749823C074L,
0x4B76ECA3C2745360L, 0x8C98F463B91691BDL,
0x14BCC93CF1ADE66AL, 0x8885213E6D458397L,
0x8E177DF0274D4711L, 0xB49B73B5503F2951L,
0x10168168C3F96B6BL, 0x0E3D963B63CAB0AEL,
0x8DFC4B5655A1DB14L, 0xF789F1356E14DE5CL,
0x683E68AF4E51DAC1L, 0xC9A84F9D8D4B0FD9L,
0x3691E03F52A0F9D1L, 0x5ED86E46E1878E80L,
0x3C711A0E99D07150L, 0x5A0865B20C4E9310L,
0x56FBFC1FE4F0682EL, 0xEA8D5DE3105EDF9BL,
0x71ABFDB12379187AL, 0x2EB99DE1BEE77B9CL,
0x21ECC0EA33CF4523L, 0x59A4D7521805C7A1L,
0x3896F5EB56AE7C72L, 0xAA638F3DB18F75DCL,
0x9F39358DABE9808EL, 0xB7DEFA91C00B72ACL,
0x6B5541FD62492D92L, 0x6DC6DEE8F92E4D5BL,
0x353F57ABC4BEEA7EL, 0x735769D6DA5690CEL,
0x0A234AA642391484L, 0xF6F9508028F80D9DL,
0xB8E319A27AB3F215L, 0x31AD9C1151341A4DL,
0x773C22A57BEF5805L, 0x45C7561A07968633L,
0xF913DA9E249DBE36L, 0xDA652D9B78A64C68L,
0x4C27A97F3BC334EFL, 0x76621220E66B17F4L,
0x967743899ACD7D0BL, 0xF3EE5BCAE0ED6782L,
0x409F753600C879FCL, 0x06D09A39B5926DB6L,
0x6F83AEB0317AC588L, 0x01E6CA4A86381F21L,
0x66FF3462D19F3025L, 0x72207C24DDFD3BFBL,
0x4AF6B6D3E2ECE2EBL, 0x9C994DBEC7EA08DEL,
0x49ACE597B09A8BC4L, 0xB38C4766CF0797BAL,
0x131B9373C57C2A75L, 0xB1822CCE61931E58L,
0x9D7555B909BA1C0CL, 0x127FAFDD937D11D2L,
0x29DA3BADC66D92E4L, 0xA2C1D57154C2ECBCL,
0x58C5134D82F6FE24L, 0x1C3AE3515B62274FL,
0xE907C82E01CB8126L, 0xF8ED091913E37FCBL,
0x3249D8F9C80046C9L, 0x80CF9BEDE388FB63L,
0x1881539A116CF19EL, 0x5103F3F76BD52457L,
0x15B7E6F5AE47F7A8L, 0xDBD7C6DED47E9CCFL,
0x44E55C410228BB1AL, 0xB647D4255EDB4E99L,
0x5D11882BB8AAFC30L, 0xF5098BBB29D3212AL,
0x8FB5EA14E90296B3L, 0x677B942157DD025AL,
0xFB58E7C0A390ACB5L, 0x89D3674C83BD4A01L,
0x9E2DA4DF4BF3B93BL, 0xFCC41E328CAB4829L,
0x03F38C96BA582C52L, 0xCAD1BDBD7FD85DB2L,
0xBBB442C16082AE83L, 0xB95FE86BA5DA9AB0L,
0xB22E04673771A93FL, 0x845358C9493152D8L,
0xBE2A488697B4541EL, 0x95A2DC2DD38E6966L,
0xC02C11AC923C852BL, 0x2388B1990DF2A87BL,
0x7C8008FA1B4F37BEL, 0x1F70D0C84D54E503L,
0x5490ADEC7ECE57D4L, 0x002B3C27D9063A3AL,
0x7EAEA3848030A2BFL, 0xC602326DED2003C0L,
0x83A7287D69A94086L, 0xC57A5FCB30F57A8AL,
0xB56844E479EBE779L, 0xA373B40F05DCBCE9L,
0xD71A786E88570EE2L, 0x879CBACDBDE8F6A0L,
0x976AD1BCC164A32FL, 0xAB21E25E9666D78BL,
0x901063AAE5E5C33CL, 0x9818B34448698D90L,
0xE36487AE3E1E8ABBL, 0xAFBDF931893BDCB4L,
0x6345A0DC5FBBD519L, 0x8628FE269B9465CAL,
0x1E5D01603F9C51ECL, 0x4DE44006A15049B7L,
0xBF6C70E5F776CBB1L, 0x411218F2EF552BEDL,
0xCB0C0708705A36A3L, 0xE74D14754F986044L,
0xCD56D9430EA8280EL, 0xC12591D7535F5065L,
0xC83223F1720AEF96L, 0xC3A0396F7363A51FL };
// The cached self-test result.
private static Boolean valid;
// The context.
private long a, b, c;
// Constructors.
// -----------------------------------------------------------------------
/**
* Trivial 0-arguments constructor.
*/
public Tiger()
{
super(Registry.TIGER_HASH, HASH_SIZE, BLOCK_SIZE);
}
/**
* Private copying constructor for cloning.
*
* @param that The instance being cloned.
*/
private Tiger(Tiger that)
{
this();
this.a = that.a;
this.b = that.b;
this.c = that.c;
this.count = that.count;
this.buffer = (that.buffer != null) ? (byte[]) that.buffer.clone() : null;
}
// Instance methods implementing BaseHash.
// -----------------------------------------------------------------------
public Object clone()
{
return new Tiger(this);
}
public boolean selfTest()
{
if (valid == null)
{
valid = new Boolean(DIGEST0.equals(Util.toString(new Tiger().digest())));
}
return valid.booleanValue();
}
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
int padding = (n < 56) ? (56 - n) : (120 - n);
byte[] pad = new byte[padding + 8];
pad[0] = 1;
long bits = count << 3;
pad[padding++] = (byte) bits;
pad[padding++] = (byte) (bits >>> 8);
pad[padding++] = (byte) (bits >>> 16);
pad[padding++] = (byte) (bits >>> 24);
pad[padding++] = (byte) (bits >>> 32);
pad[padding++] = (byte) (bits >>> 40);
pad[padding++] = (byte) (bits >>> 48);
pad[padding] = (byte) (bits >>> 56);
return pad;
}
protected byte[] getResult()
{
return new byte[] { (byte) a, (byte) (a >>> 8), (byte) (a >>> 16),
(byte) (a >>> 24), (byte) (a >>> 32), (byte) (a >>> 40),
(byte) (a >>> 48), (byte) (a >>> 56), (byte) b,
(byte) (b >>> 8), (byte) (b >>> 16), (byte) (b >>> 24),
(byte) (b >>> 32), (byte) (b >>> 40), (byte) (b >>> 48),
(byte) (b >>> 56), (byte) c, (byte) (c >>> 8),
(byte) (c >>> 16), (byte) (c >>> 24), (byte) (c >>> 32),
(byte) (c >>> 40), (byte) (c >>> 48), (byte) (c >>> 56) };
}
protected void resetContext()
{
a = A;
b = B;
c = C;
}
protected void transform(byte[] in, int offset)
{
long x0, x1, x2, x3, x4, x5, x6, x7;
x0 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8)
| ((long) (in[offset++] & 0xFF) << 16)
| ((long) (in[offset++] & 0xFF) << 24)
| ((long) (in[offset++] & 0xFF) << 32)
| ((long) (in[offset++] & 0xFF) << 40)
| ((long) (in[offset++] & 0xFF) << 48)
| ((long) (in[offset++] & 0xFF) << 56);
x1 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8)
| ((long) (in[offset++] & 0xFF) << 16)
| ((long) (in[offset++] & 0xFF) << 24)
| ((long) (in[offset++] & 0xFF) << 32)
| ((long) (in[offset++] & 0xFF) << 40)
| ((long) (in[offset++] & 0xFF) << 48)
| ((long) (in[offset++] & 0xFF) << 56);
x2 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8)
| ((long) (in[offset++] & 0xFF) << 16)
| ((long) (in[offset++] & 0xFF) << 24)
| ((long) (in[offset++] & 0xFF) << 32)
| ((long) (in[offset++] & 0xFF) << 40)
| ((long) (in[offset++] & 0xFF) << 48)
| ((long) (in[offset++] & 0xFF) << 56);
x3 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8)
| ((long) (in[offset++] & 0xFF) << 16)
| ((long) (in[offset++] & 0xFF) << 24)
| ((long) (in[offset++] & 0xFF) << 32)
| ((long) (in[offset++] & 0xFF) << 40)
| ((long) (in[offset++] & 0xFF) << 48)
| ((long) (in[offset++] & 0xFF) << 56);
x4 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8)
| ((long) (in[offset++] & 0xFF) << 16)
| ((long) (in[offset++] & 0xFF) << 24)
| ((long) (in[offset++] & 0xFF) << 32)
| ((long) (in[offset++] & 0xFF) << 40)
| ((long) (in[offset++] & 0xFF) << 48)
| ((long) (in[offset++] & 0xFF) << 56);
x5 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8)
| ((long) (in[offset++] & 0xFF) << 16)
| ((long) (in[offset++] & 0xFF) << 24)
| ((long) (in[offset++] & 0xFF) << 32)
| ((long) (in[offset++] & 0xFF) << 40)
| ((long) (in[offset++] & 0xFF) << 48)
| ((long) (in[offset++] & 0xFF) << 56);
x6 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8)
| ((long) (in[offset++] & 0xFF) << 16)
| ((long) (in[offset++] & 0xFF) << 24)
| ((long) (in[offset++] & 0xFF) << 32)
| ((long) (in[offset++] & 0xFF) << 40)
| ((long) (in[offset++] & 0xFF) << 48)
| ((long) (in[offset++] & 0xFF) << 56);
x7 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8)
| ((long) (in[offset++] & 0xFF) << 16)
| ((long) (in[offset++] & 0xFF) << 24)
| ((long) (in[offset++] & 0xFF) << 32)
| ((long) (in[offset++] & 0xFF) << 40)
| ((long) (in[offset++] & 0xFF) << 48)
| ((long) (in[offset] & 0xFF) << 56);
// save_abc ::=
long aa = a, bb = b, cc = c;
// pass(aa, bb, cc, 5) ::=
cc ^= x0;
aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff]
^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff];
bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff]
^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff];
bb *= 5;
aa ^= x1;
bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff]
^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff];
cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff]
^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff];
cc *= 5;
bb ^= x2;
cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff]
^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff];
aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff]
^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff];
aa *= 5;
cc ^= x3;
aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff]
^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff];
bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff]
^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff];
bb *= 5;
aa ^= x4;
bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff]
^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff];
cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff]
^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff];
cc *= 5;
bb ^= x5;
cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff]
^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff];
aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff]
^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff];
aa *= 5;
cc ^= x6;
aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff]
^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff];
bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff]
^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff];
bb *= 5;
aa ^= x7;
bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff]
^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff];
cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff]
^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff];
cc *= 5;
// key_schedule ::=
x0 -= x7 ^ 0xA5A5A5A5A5A5A5A5L;
x1 ^= x0;
x2 += x1;
x3 -= x2 ^ ((~x1) << 19);
x4 ^= x3;
x5 += x4;
x6 -= x5 ^ ((~x4) >>> 23);
x7 ^= x6;
x0 += x7;
x1 -= x0 ^ ((~x7) << 19);
x2 ^= x1;
x3 += x2;
x4 -= x3 ^ ((~x2) >>> 23);
x5 ^= x4;
x6 += x5;
x7 -= x6 ^ 0x0123456789ABCDEFL;
// pass(cc, aa, bb, 7) ::=
bb ^= x0;
cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff]
^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff];
aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff]
^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff];
aa *= 7;
cc ^= x1;
aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff]
^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff];
bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff]
^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff];
bb *= 7;
aa ^= x2;
bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff]
^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff];
cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff]
^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff];
cc *= 7;
bb ^= x3;
cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff]
^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff];
aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff]
^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff];
aa *= 7;
cc ^= x4;
aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff]
^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff];
bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff]
^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff];
bb *= 7;
aa ^= x5;
bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff]
^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff];
cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff]
^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff];
cc *= 7;
bb ^= x6;
cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff]
^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff];
aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff]
^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff];
aa *= 7;
cc ^= x7;
aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff]
^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff];
bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff]
^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff];
bb *= 7;
// key_schedule ::=
x0 -= x7 ^ 0xA5A5A5A5A5A5A5A5L;
x1 ^= x0;
x2 += x1;
x3 -= x2 ^ ((~x1) << 19);
x4 ^= x3;
x5 += x4;
x6 -= x5 ^ ((~x4) >>> 23);
x7 ^= x6;
x0 += x7;
x1 -= x0 ^ ((~x7) << 19);
x2 ^= x1;
x3 += x2;
x4 -= x3 ^ ((~x2) >>> 23);
x5 ^= x4;
x6 += x5;
x7 -= x6 ^ 0x0123456789ABCDEFL;
// pass(bb,cc,aa,9) ::=
aa ^= x0;
bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff]
^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff];
cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff]
^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff];
cc *= 9;
bb ^= x1;
cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff]
^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff];
aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff]
^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff];
aa *= 9;
cc ^= x2;
aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff]
^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff];
bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff]
^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff];
bb *= 9;
aa ^= x3;
bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff]
^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff];
cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff]
^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff];
cc *= 9;
bb ^= x4;
cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff]
^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff];
aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff]
^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff];
aa *= 9;
cc ^= x5;
aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff]
^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff];
bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff]
^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff];
bb *= 9;
aa ^= x6;
bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff]
^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff];
cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff]
^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff];
cc *= 9;
bb ^= x7;
cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff]
^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff];
aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff]
^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff];
aa *= 9;
// feedforward ::=
a ^= aa;
b = bb - b;
c += cc;
}
}
@@ -0,0 +1,626 @@
/* Whirlpool.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>Whirlpool, a new 512-bit hashing function operating on messages less than
* 2 ** 256 bits in length. The function structure is designed according to the
* Wide Trail strategy and permits a wide variety of implementation trade-offs.
* </p>
*
* <p><b>IMPORTANT</b>: This implementation is not thread-safe.</p>
*
* <p>References:</p>
*
* <ol>
* <li><a href="http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html">
* The WHIRLPOOL Hashing Function</a>.<br>
* <a href="mailto:paulo.barreto@terra.com.br">Paulo S.L.M. Barreto</a> and
* <a href="mailto:vincent.rijmen@esat.kuleuven.ac.be">Vincent Rijmen</a>.</li>
* </ol>
*/
public final class Whirlpool extends BaseHash
{
// Debugging methods and variables
// -------------------------------------------------------------------------
private static final boolean DEBUG = false;
private static final int debuglevel = 3;
// Constants and variables
// -------------------------------------------------------------------------
private static final int BLOCK_SIZE = 64; // inner block size in bytes
/** The digest of the 0-bit long message. */
private static final String DIGEST0 = "470F0409ABAA446E49667D4EBE12A14387CEDBD10DD17B8243CAD550A089DC0F"
+ "EEA7AA40F6C2AAAB71C6EBD076E43C7CFCA0AD32567897DCB5969861049A0F5A";
private static final int R = 10; // default number of rounds
private static final String Sd = // p. 19 [WHIRLPOOL]
"\u1823\uc6E8\u87B8\u014F\u36A6\ud2F5\u796F\u9152"
+ "\u60Bc\u9B8E\uA30c\u7B35\u1dE0\ud7c2\u2E4B\uFE57"
+ "\u1577\u37E5\u9FF0\u4AdA\u58c9\u290A\uB1A0\u6B85"
+ "\uBd5d\u10F4\ucB3E\u0567\uE427\u418B\uA77d\u95d8"
+ "\uFBEE\u7c66\udd17\u479E\ucA2d\uBF07\uAd5A\u8333"
+ "\u6302\uAA71\uc819\u49d9\uF2E3\u5B88\u9A26\u32B0"
+ "\uE90F\ud580\uBEcd\u3448\uFF7A\u905F\u2068\u1AAE"
+ "\uB454\u9322\u64F1\u7312\u4008\uc3Ec\udBA1\u8d3d"
+ "\u9700\ucF2B\u7682\ud61B\uB5AF\u6A50\u45F3\u30EF"
+ "\u3F55\uA2EA\u65BA\u2Fc0\udE1c\uFd4d\u9275\u068A"
+ "\uB2E6\u0E1F\u62d4\uA896\uF9c5\u2559\u8472\u394c"
+ "\u5E78\u388c\ud1A5\uE261\uB321\u9c1E\u43c7\uFc04"
+ "\u5199\u6d0d\uFAdF\u7E24\u3BAB\ucE11\u8F4E\uB7EB"
+ "\u3c81\u94F7\uB913\u2cd3\uE76E\uc403\u5644\u7FA9"
+ "\u2ABB\uc153\udc0B\u9d6c\u3174\uF646\uAc89\u14E1"
+ "\u163A\u6909\u70B6\ud0Ed\ucc42\u98A4\u285c\uF886";
private static final long[] T0 = new long[256];
private static final long[] T1 = new long[256];
private static final long[] T2 = new long[256];
private static final long[] T3 = new long[256];
private static final long[] T4 = new long[256];
private static final long[] T5 = new long[256];
private static final long[] T6 = new long[256];
private static final long[] T7 = new long[256];
private static final long[] rc = new long[R];
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
/** The 512-bit context as 8 longs. */
private long H0, H1, H2, H3, H4, H5, H6, H7;
/** Work area for computing the round key schedule. */
private long k00, k01, k02, k03, k04, k05, k06, k07;
private long Kr0, Kr1, Kr2, Kr3, Kr4, Kr5, Kr6, Kr7;
/** work area for transforming the 512-bit buffer. */
private long n0, n1, n2, n3, n4, n5, n6, n7;
private long nn0, nn1, nn2, nn3, nn4, nn5, nn6, nn7;
/** work area for holding block cipher's intermediate values. */
private long w0, w1, w2, w3, w4, w5, w6, w7;
// Static code - to intialise lookup tables --------------------------------
static
{
long time = System.currentTimeMillis();
int ROOT = 0x11d; // para. 2.1 [WHIRLPOOL]
int i, r, j;
long s, s2, s3, s4, s5, s8, s9, t;
char c;
final byte[] S = new byte[256];
for (i = 0; i < 256; i++)
{
c = Sd.charAt(i >>> 1);
s = ((i & 1) == 0 ? c >>> 8 : c) & 0xFFL;
s2 = s << 1;
if (s2 > 0xFFL)
{
s2 ^= ROOT;
}
s3 = s2 ^ s;
s4 = s2 << 1;
if (s4 > 0xFFL)
{
s4 ^= ROOT;
}
s5 = s4 ^ s;
s8 = s4 << 1;
if (s8 > 0xFFL)
{
s8 ^= ROOT;
}
s9 = s8 ^ s;
S[i] = (byte) s;
T0[i] = t = s << 56 | s << 48 | s3 << 40 | s << 32 | s5 << 24
| s8 << 16 | s9 << 8 | s5;
T1[i] = t >>> 8 | t << 56;
T2[i] = t >>> 16 | t << 48;
T3[i] = t >>> 24 | t << 40;
T4[i] = t >>> 32 | t << 32;
T5[i] = t >>> 40 | t << 24;
T6[i] = t >>> 48 | t << 16;
T7[i] = t >>> 56 | t << 8;
}
for (r = 1, i = 0, j = 0; r < R + 1; r++)
{
rc[i++] = (S[j++] & 0xFFL) << 56 | (S[j++] & 0xFFL) << 48
| (S[j++] & 0xFFL) << 40 | (S[j++] & 0xFFL) << 32
| (S[j++] & 0xFFL) << 24 | (S[j++] & 0xFFL) << 16
| (S[j++] & 0xFFL) << 8 | (S[j++] & 0xFFL);
}
time = System.currentTimeMillis() - time;
if (DEBUG && debuglevel > 8)
{
System.out.println("==========");
System.out.println();
System.out.println("Static data");
System.out.println();
System.out.println();
System.out.println("T0[]:");
for (i = 0; i < 64; i++)
{
for (j = 0; j < 4; j++)
{
System.out.print("0x" + Util.toString(T0[i * 4 + j]) + ", ");
}
System.out.println();
}
System.out.println();
System.out.println("T1[]:");
for (i = 0; i < 64; i++)
{
for (j = 0; j < 4; j++)
{
System.out.print("0x" + Util.toString(T1[i * 4 + j]) + ", ");
}
System.out.println();
}
System.out.println();
System.out.println("T2[]:");
for (i = 0; i < 64; i++)
{
for (j = 0; j < 4; j++)
{
System.out.print("0x" + Util.toString(T2[i * 4 + j]) + ", ");
}
System.out.println();
}
System.out.println();
System.out.println("T3[]:");
for (i = 0; i < 64; i++)
{
for (j = 0; j < 4; j++)
{
System.out.print("0x" + Util.toString(T3[i * 4 + j]) + ", ");
}
System.out.println();
}
System.out.println();
System.out.println("T4[]:");
for (i = 0; i < 64; i++)
{
for (j = 0; j < 4; j++)
{
System.out.print("0x" + Util.toString(T4[i * 4 + j]) + ", ");
}
System.out.println();
}
System.out.println();
System.out.println("T5[]:");
for (i = 0; i < 64; i++)
{
for (j = 0; j < 4; j++)
{
System.out.print("0x" + Util.toString(T5[i * 4 + j]) + ", ");
}
System.out.println();
}
System.out.println();
System.out.println("T6[]:");
for (i = 0; i < 64; i++)
{
for (j = 0; j < 4; j++)
{
System.out.print("0x" + Util.toString(T5[i * 4 + j]) + ", ");
}
System.out.println();
}
System.out.println();
System.out.println("T7[]:");
for (i = 0; i < 64; i++)
{
for (j = 0; j < 4; j++)
{
System.out.print("0x" + Util.toString(T5[i * 4 + j]) + ", ");
}
System.out.println();
}
System.out.println();
System.out.println("rc[]:");
for (i = 0; i < R; i++)
{
System.out.println("0x" + Util.toString(rc[i]));
}
System.out.println();
System.out.println();
System.out.println("Total initialization time: " + time + " ms.");
System.out.println();
}
}
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public Whirlpool()
{
super(Registry.WHIRLPOOL_HASH, 20, BLOCK_SIZE);
}
/**
* <p>Private constructor for cloning purposes.</p>
*
* @param md the instance to clone.
*/
private Whirlpool(Whirlpool md)
{
this();
this.H0 = md.H0;
this.H1 = md.H1;
this.H2 = md.H2;
this.H3 = md.H3;
this.H4 = md.H4;
this.H5 = md.H5;
this.H6 = md.H6;
this.H7 = md.H7;
this.count = md.count;
this.buffer = (byte[]) md.buffer.clone();
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// java.lang.Cloneable interface implementation ----------------------------
public Object clone()
{
return (new Whirlpool(this));
}
// Implementation of concrete methods in BaseHash --------------------------
protected void transform(byte[] in, int offset)
{
// apply mu to the input
n0 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48
| (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32
| (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16
| (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL);
n1 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48
| (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32
| (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16
| (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL);
n2 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48
| (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32
| (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16
| (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL);
n3 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48
| (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32
| (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16
| (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL);
n4 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48
| (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32
| (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16
| (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL);
n5 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48
| (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32
| (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16
| (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL);
n6 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48
| (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32
| (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16
| (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL);
n7 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48
| (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32
| (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16
| (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL);
// transform K into the key schedule Kr; 0 <= r <= R
k00 = H0;
k01 = H1;
k02 = H2;
k03 = H3;
k04 = H4;
k05 = H5;
k06 = H6;
k07 = H7;
nn0 = n0 ^ k00;
nn1 = n1 ^ k01;
nn2 = n2 ^ k02;
nn3 = n3 ^ k03;
nn4 = n4 ^ k04;
nn5 = n5 ^ k05;
nn6 = n6 ^ k06;
nn7 = n7 ^ k07;
// intermediate cipher output
w0 = w1 = w2 = w3 = w4 = w5 = w6 = w7 = 0L;
for (int r = 0; r < R; r++)
{
// 1. compute intermediate round key schedule by applying ro[rc]
// to the previous round key schedule --rc being the round constant
Kr0 = T0[(int) ((k00 >> 56) & 0xFFL)] ^ T1[(int) ((k07 >> 48) & 0xFFL)]
^ T2[(int) ((k06 >> 40) & 0xFFL)]
^ T3[(int) ((k05 >> 32) & 0xFFL)]
^ T4[(int) ((k04 >> 24) & 0xFFL)]
^ T5[(int) ((k03 >> 16) & 0xFFL)]
^ T6[(int) ((k02 >> 8) & 0xFFL)] ^ T7[(int) (k01 & 0xFFL)]
^ rc[r];
Kr1 = T0[(int) ((k01 >> 56) & 0xFFL)] ^ T1[(int) ((k00 >> 48) & 0xFFL)]
^ T2[(int) ((k07 >> 40) & 0xFFL)]
^ T3[(int) ((k06 >> 32) & 0xFFL)]
^ T4[(int) ((k05 >> 24) & 0xFFL)]
^ T5[(int) ((k04 >> 16) & 0xFFL)]
^ T6[(int) ((k03 >> 8) & 0xFFL)] ^ T7[(int) (k02 & 0xFFL)];
Kr2 = T0[(int) ((k02 >> 56) & 0xFFL)] ^ T1[(int) ((k01 >> 48) & 0xFFL)]
^ T2[(int) ((k00 >> 40) & 0xFFL)]
^ T3[(int) ((k07 >> 32) & 0xFFL)]
^ T4[(int) ((k06 >> 24) & 0xFFL)]
^ T5[(int) ((k05 >> 16) & 0xFFL)]
^ T6[(int) ((k04 >> 8) & 0xFFL)] ^ T7[(int) (k03 & 0xFFL)];
Kr3 = T0[(int) ((k03 >> 56) & 0xFFL)] ^ T1[(int) ((k02 >> 48) & 0xFFL)]
^ T2[(int) ((k01 >> 40) & 0xFFL)]
^ T3[(int) ((k00 >> 32) & 0xFFL)]
^ T4[(int) ((k07 >> 24) & 0xFFL)]
^ T5[(int) ((k06 >> 16) & 0xFFL)]
^ T6[(int) ((k05 >> 8) & 0xFFL)] ^ T7[(int) (k04 & 0xFFL)];
Kr4 = T0[(int) ((k04 >> 56) & 0xFFL)] ^ T1[(int) ((k03 >> 48) & 0xFFL)]
^ T2[(int) ((k02 >> 40) & 0xFFL)]
^ T3[(int) ((k01 >> 32) & 0xFFL)]
^ T4[(int) ((k00 >> 24) & 0xFFL)]
^ T5[(int) ((k07 >> 16) & 0xFFL)]
^ T6[(int) ((k06 >> 8) & 0xFFL)] ^ T7[(int) (k05 & 0xFFL)];
Kr5 = T0[(int) ((k05 >> 56) & 0xFFL)] ^ T1[(int) ((k04 >> 48) & 0xFFL)]
^ T2[(int) ((k03 >> 40) & 0xFFL)]
^ T3[(int) ((k02 >> 32) & 0xFFL)]
^ T4[(int) ((k01 >> 24) & 0xFFL)]
^ T5[(int) ((k00 >> 16) & 0xFFL)]
^ T6[(int) ((k07 >> 8) & 0xFFL)] ^ T7[(int) (k06 & 0xFFL)];
Kr6 = T0[(int) ((k06 >> 56) & 0xFFL)] ^ T1[(int) ((k05 >> 48) & 0xFFL)]
^ T2[(int) ((k04 >> 40) & 0xFFL)]
^ T3[(int) ((k03 >> 32) & 0xFFL)]
^ T4[(int) ((k02 >> 24) & 0xFFL)]
^ T5[(int) ((k01 >> 16) & 0xFFL)]
^ T6[(int) ((k00 >> 8) & 0xFFL)] ^ T7[(int) (k07 & 0xFFL)];
Kr7 = T0[(int) ((k07 >> 56) & 0xFFL)] ^ T1[(int) ((k06 >> 48) & 0xFFL)]
^ T2[(int) ((k05 >> 40) & 0xFFL)]
^ T3[(int) ((k04 >> 32) & 0xFFL)]
^ T4[(int) ((k03 >> 24) & 0xFFL)]
^ T5[(int) ((k02 >> 16) & 0xFFL)]
^ T6[(int) ((k01 >> 8) & 0xFFL)] ^ T7[(int) (k00 & 0xFFL)];
k00 = Kr0;
k01 = Kr1;
k02 = Kr2;
k03 = Kr3;
k04 = Kr4;
k05 = Kr5;
k06 = Kr6;
k07 = Kr7;
// 2. incrementally compute the cipher output
w0 = T0[(int) ((nn0 >> 56) & 0xFFL)] ^ T1[(int) ((nn7 >> 48) & 0xFFL)]
^ T2[(int) ((nn6 >> 40) & 0xFFL)]
^ T3[(int) ((nn5 >> 32) & 0xFFL)]
^ T4[(int) ((nn4 >> 24) & 0xFFL)]
^ T5[(int) ((nn3 >> 16) & 0xFFL)] ^ T6[(int) ((nn2 >> 8) & 0xFFL)]
^ T7[(int) (nn1 & 0xFFL)] ^ Kr0;
w1 = T0[(int) ((nn1 >> 56) & 0xFFL)] ^ T1[(int) ((nn0 >> 48) & 0xFFL)]
^ T2[(int) ((nn7 >> 40) & 0xFFL)]
^ T3[(int) ((nn6 >> 32) & 0xFFL)]
^ T4[(int) ((nn5 >> 24) & 0xFFL)]
^ T5[(int) ((nn4 >> 16) & 0xFFL)] ^ T6[(int) ((nn3 >> 8) & 0xFFL)]
^ T7[(int) (nn2 & 0xFFL)] ^ Kr1;
w2 = T0[(int) ((nn2 >> 56) & 0xFFL)] ^ T1[(int) ((nn1 >> 48) & 0xFFL)]
^ T2[(int) ((nn0 >> 40) & 0xFFL)]
^ T3[(int) ((nn7 >> 32) & 0xFFL)]
^ T4[(int) ((nn6 >> 24) & 0xFFL)]
^ T5[(int) ((nn5 >> 16) & 0xFFL)] ^ T6[(int) ((nn4 >> 8) & 0xFFL)]
^ T7[(int) (nn3 & 0xFFL)] ^ Kr2;
w3 = T0[(int) ((nn3 >> 56) & 0xFFL)] ^ T1[(int) ((nn2 >> 48) & 0xFFL)]
^ T2[(int) ((nn1 >> 40) & 0xFFL)]
^ T3[(int) ((nn0 >> 32) & 0xFFL)]
^ T4[(int) ((nn7 >> 24) & 0xFFL)]
^ T5[(int) ((nn6 >> 16) & 0xFFL)] ^ T6[(int) ((nn5 >> 8) & 0xFFL)]
^ T7[(int) (nn4 & 0xFFL)] ^ Kr3;
w4 = T0[(int) ((nn4 >> 56) & 0xFFL)] ^ T1[(int) ((nn3 >> 48) & 0xFFL)]
^ T2[(int) ((nn2 >> 40) & 0xFFL)]
^ T3[(int) ((nn1 >> 32) & 0xFFL)]
^ T4[(int) ((nn0 >> 24) & 0xFFL)]
^ T5[(int) ((nn7 >> 16) & 0xFFL)] ^ T6[(int) ((nn6 >> 8) & 0xFFL)]
^ T7[(int) (nn5 & 0xFFL)] ^ Kr4;
w5 = T0[(int) ((nn5 >> 56) & 0xFFL)] ^ T1[(int) ((nn4 >> 48) & 0xFFL)]
^ T2[(int) ((nn3 >> 40) & 0xFFL)]
^ T3[(int) ((nn2 >> 32) & 0xFFL)]
^ T4[(int) ((nn1 >> 24) & 0xFFL)]
^ T5[(int) ((nn0 >> 16) & 0xFFL)] ^ T6[(int) ((nn7 >> 8) & 0xFFL)]
^ T7[(int) (nn6 & 0xFFL)] ^ Kr5;
w6 = T0[(int) ((nn6 >> 56) & 0xFFL)] ^ T1[(int) ((nn5 >> 48) & 0xFFL)]
^ T2[(int) ((nn4 >> 40) & 0xFFL)]
^ T3[(int) ((nn3 >> 32) & 0xFFL)]
^ T4[(int) ((nn2 >> 24) & 0xFFL)]
^ T5[(int) ((nn1 >> 16) & 0xFFL)] ^ T6[(int) ((nn0 >> 8) & 0xFFL)]
^ T7[(int) (nn7 & 0xFFL)] ^ Kr6;
w7 = T0[(int) ((nn7 >> 56) & 0xFFL)] ^ T1[(int) ((nn6 >> 48) & 0xFFL)]
^ T2[(int) ((nn5 >> 40) & 0xFFL)]
^ T3[(int) ((nn4 >> 32) & 0xFFL)]
^ T4[(int) ((nn3 >> 24) & 0xFFL)]
^ T5[(int) ((nn2 >> 16) & 0xFFL)] ^ T6[(int) ((nn1 >> 8) & 0xFFL)]
^ T7[(int) (nn0 & 0xFFL)] ^ Kr7;
nn0 = w0;
nn1 = w1;
nn2 = w2;
nn3 = w3;
nn4 = w4;
nn5 = w5;
nn6 = w6;
nn7 = w7;
}
// apply the Miyaguchi-Preneel hash scheme
H0 ^= w0 ^ n0;
H1 ^= w1 ^ n1;
H2 ^= w2 ^ n2;
H3 ^= w3 ^ n3;
H4 ^= w4 ^ n4;
H5 ^= w5 ^ n5;
H6 ^= w6 ^ n6;
H7 ^= w7 ^ n7;
}
protected byte[] padBuffer()
{
// [WHIRLPOOL] p. 6:
// "...padded with a 1-bit, then with as few 0-bits as necessary to
// obtain a bit string whose length is an odd multiple of 256, and
// finally with the 256-bit right-justified binary representation of L."
// in this implementation we use 'count' as the number of bytes hashed
// so far. hence the minimal number of bytes added to the message proper
// are 33 (1 for the 1-bit followed by the 0-bits and the encoding of
// the count framed in a 256-bit block). our formula is then:
// count + 33 + padding = 0 (mod BLOCK_SIZE)
int n = (int) ((count + 33) % BLOCK_SIZE);
int padding = n == 0 ? 33 : BLOCK_SIZE - n + 33;
byte[] result = new byte[padding];
// padding is always binary 1 followed by binary 0s
result[0] = (byte) 0x80;
// save (right justified) the number of bits hashed
long bits = count * 8;
int i = padding - 8;
result[i++] = (byte) (bits >>> 56);
result[i++] = (byte) (bits >>> 48);
result[i++] = (byte) (bits >>> 40);
result[i++] = (byte) (bits >>> 32);
result[i++] = (byte) (bits >>> 24);
result[i++] = (byte) (bits >>> 16);
result[i++] = (byte) (bits >>> 8);
result[i] = (byte) bits;
return result;
}
protected byte[] getResult()
{
// apply inverse mu to the context
byte[] result = new byte[] { (byte) (H0 >>> 56), (byte) (H0 >>> 48),
(byte) (H0 >>> 40), (byte) (H0 >>> 32),
(byte) (H0 >>> 24), (byte) (H0 >>> 16),
(byte) (H0 >>> 8), (byte) H0,
(byte) (H1 >>> 56), (byte) (H1 >>> 48),
(byte) (H1 >>> 40), (byte) (H1 >>> 32),
(byte) (H1 >>> 24), (byte) (H1 >>> 16),
(byte) (H1 >>> 8), (byte) H1,
(byte) (H2 >>> 56), (byte) (H2 >>> 48),
(byte) (H2 >>> 40), (byte) (H2 >>> 32),
(byte) (H2 >>> 24), (byte) (H2 >>> 16),
(byte) (H2 >>> 8), (byte) H2,
(byte) (H3 >>> 56), (byte) (H3 >>> 48),
(byte) (H3 >>> 40), (byte) (H3 >>> 32),
(byte) (H3 >>> 24), (byte) (H3 >>> 16),
(byte) (H3 >>> 8), (byte) H3,
(byte) (H4 >>> 56), (byte) (H4 >>> 48),
(byte) (H4 >>> 40), (byte) (H4 >>> 32),
(byte) (H4 >>> 24), (byte) (H4 >>> 16),
(byte) (H4 >>> 8), (byte) H4,
(byte) (H5 >>> 56), (byte) (H5 >>> 48),
(byte) (H5 >>> 40), (byte) (H5 >>> 32),
(byte) (H5 >>> 24), (byte) (H5 >>> 16),
(byte) (H5 >>> 8), (byte) H5,
(byte) (H6 >>> 56), (byte) (H6 >>> 48),
(byte) (H6 >>> 40), (byte) (H6 >>> 32),
(byte) (H6 >>> 24), (byte) (H6 >>> 16),
(byte) (H6 >>> 8), (byte) H6,
(byte) (H7 >>> 56), (byte) (H7 >>> 48),
(byte) (H7 >>> 40), (byte) (H7 >>> 32),
(byte) (H7 >>> 24), (byte) (H7 >>> 16),
(byte) (H7 >>> 8), (byte) H7 };
return result;
}
protected void resetContext()
{
H0 = H1 = H2 = H3 = H4 = H5 = H6 = H7 = 0L;
}
public boolean selfTest()
{
if (valid == null)
{
valid = new Boolean(
DIGEST0.equals(Util.toString(new Whirlpool().digest())));
}
return valid.booleanValue();
}
}
@@ -0,0 +1,68 @@
/* HavalSpi.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.Registry;
/**
* The implementation of the <code>HAVAL</code> <i>Service Provider Interface</i>
* (<b>SPI</b>) Adapter.<p>
*
* @version Revision: $
*/
public class HavalSpi extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public HavalSpi()
{
super(Registry.HAVAL_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,69 @@
/* MD2Spi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.Registry;
/**
* <p>The implementation of the MD2 <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.</p>
*
* @version $Revision: 1.1 $
*/
public class MD2Spi extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public MD2Spi()
{
super(Registry.MD2_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,69 @@
/* MD4Spi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.Registry;
/**
* <p>The implementation of the MD4 <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.</p>
*
* @version $Revision: 1.1 $
*/
public class MD4Spi extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public MD4Spi()
{
super(Registry.MD4_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,68 @@
/* MD5Spi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.Registry;
/**
* The implementation of the MD5 <i>Service Provider Interface</i> (<b>SPI</b>)
* adapter.<p>
*
* @version $Revision: 1.1 $
*/
public class MD5Spi extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public MD5Spi()
{
super(Registry.MD5_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,147 @@
/* MessageDigestAdapter.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.hash.IMessageDigest;
import gnu.java.security.hash.HashFactory;
import java.security.DigestException;
import java.security.MessageDigestSpi;
/**
* The implementation of a generic {@link java.security.MessageDigest} adapter
* class to wrap gnu.crypto hash instances.<p>
*
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) for the
* {@link java.security.MessageDigest} class, which provides the functionality
* of a message digest algorithm, such as MD5 or SHA. Message digests are secure
* one-way hash functions that take arbitrary-sized data and output a fixed-
* length hash value.<p>
*
* All the abstract methods in the {@link java.security.MessageDigestSpi} class
* are implemented by this class and all its sub-classes.<p>
*
* All the implementations which subclass this object, and which are serviced by
* the GNU Crypto provider implement the {@link java.lang.Cloneable} interface.<p>
*
* @version $Revision: 1.1 $
*/
class MessageDigestAdapter extends MessageDigestSpi implements Cloneable
{
// Constants and variables
// -------------------------------------------------------------------------
/** Our underlying hash instance. */
private IMessageDigest adaptee;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Trivial protected constructor.
*
* @param mdName the canonical name of the hash algorithm.
*/
protected MessageDigestAdapter(String mdName)
{
this(HashFactory.getInstance(mdName));
}
/**
* Private constructor for cloning purposes.
*
* @param adaptee a clone of the underlying hash algorithm instance.
*/
private MessageDigestAdapter(IMessageDigest adaptee)
{
super();
this.adaptee = adaptee;
}
// Class methods
// -------------------------------------------------------------------------
// java.security.MessageDigestSpi interface implementation
// -------------------------------------------------------------------------
public Object clone()
{
return new MessageDigestAdapter((IMessageDigest) adaptee.clone());
}
public int engineGetDigestLength()
{
return adaptee.hashSize();
}
public void engineUpdate(byte input)
{
adaptee.update(input);
}
public void engineUpdate(byte[] input, int offset, int len)
{
adaptee.update(input, offset, len);
}
public byte[] engineDigest()
{
return adaptee.digest();
}
public int engineDigest(byte[] buf, int offset, int len)
throws DigestException
{
int result = adaptee.hashSize();
if (len < result)
{
throw new DigestException();
}
byte[] md = adaptee.digest();
System.arraycopy(md, 0, buf, offset, result);
return result;
}
public void engineReset()
{
adaptee.reset();
}
}
@@ -0,0 +1,68 @@
/* RipeMD128Spi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.Registry;
/**
* The implementation of the RIPEMD-128 <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.<p>
*
* @version $Revision: 1.1 $
*/
public class RipeMD128Spi extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public RipeMD128Spi()
{
super(Registry.RIPEMD128_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,68 @@
/* RipeMD160Spi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.Registry;
/**
* The implementation of the RIPEMD-160 <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.<p>
*
* @version $Revision: 1.1 $
*/
public class RipeMD160Spi extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public RipeMD160Spi()
{
super(Registry.RIPEMD160_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,68 @@
/* Sha160Spi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.Registry;
/**
* The implementation of the SHA-1 (160-bit) <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.<p>
*
* @version $Revision: 1.1 $
*/
public class Sha160Spi extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha160Spi()
{
super(Registry.SHA160_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,68 @@
/* Sha256Spi.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.Registry;
/**
* <p>The implementation of the SHA-2-1 (256-bit) <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.</p>
*
* @version $Revision: 1.1 $
*/
public class Sha256Spi extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha256Spi()
{
super(Registry.SHA256_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,68 @@
/* Sha384Spi.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.Registry;
/**
* <p>The implementation of the SHA-2-2 (384-bit) <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.</p>
*
* @version $Revision: 1.1 $
*/
public class Sha384Spi extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha384Spi()
{
super(Registry.SHA384_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,68 @@
/* Sha512Spi.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.Registry;
/**
* <p>The implementation of the SHA-2-3 (512-bit) <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.</p>
*
* @version $Revision: 1.1 $
*/
public class Sha512Spi extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha512Spi()
{
super(Registry.SHA512_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,69 @@
/* TigerSpi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.Registry;
/**
* <p>The implementation of the Tiger <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.</p>
*
* @version $Revision: 1.1 $
*/
public class TigerSpi extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public TigerSpi()
{
super(Registry.TIGER_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,68 @@
/* WhirlpoolSpi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.hash;
import gnu.java.security.Registry;
/**
* The implementation of the Whirlpool <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.<p>
*
* @version $Revision: 1.1 $
*/
public class WhirlpoolSpi extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public WhirlpoolSpi()
{
super(Registry.WHIRLPOOL_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,66 @@
/* HavalRandomSpi.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.Registry;
/**
* The implementation of the HAVAL-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) Adapter.<p>
*/
public class HavalRandomSpi extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public HavalRandomSpi()
{
super(Registry.HAVAL_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,66 @@
/* MD2RandomSpi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.Registry;
/**
* The implementation of the MD2-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
*/
public class MD2RandomSpi extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public MD2RandomSpi()
{
super(Registry.MD2_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,66 @@
/* MD4RandomSpi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.Registry;
/**
* The implementation of the MD4-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
*/
public class MD4RandomSpi extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public MD4RandomSpi()
{
super(Registry.MD4_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,66 @@
/* MD5RandomSpi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.Registry;
/**
* The implementation of the MD5-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
*/
public class MD5RandomSpi extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public MD5RandomSpi()
{
super(Registry.MD5_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,66 @@
/* RipeMD128RandomSpi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.Registry;
/**
* <p>The implementation of the RIPEMD128-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
*/
public class RipeMD128RandomSpi extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public RipeMD128RandomSpi()
{
super(Registry.RIPEMD128_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,66 @@
/* RipeMD160RandomSpi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.Registry;
/**
* The implementation of the RIPEMD160-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
*/
public class RipeMD160RandomSpi extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public RipeMD160RandomSpi()
{
super(Registry.RIPEMD160_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,126 @@
/* SecureRandomAdapter.java --
Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.prng.LimitReachedException;
import gnu.java.security.prng.MDGenerator;
import java.security.SecureRandomSpi;
import java.util.HashMap;
/**
* <p>The implementation of a generic {@link java.security.SecureRandom} adapter
* class to wrap gnu.crypto prng instances based on Message Digest algorithms.</p>
*
* <p>This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) for
* the {@link java.security.SecureRandom} class, which provides the
* functionality of a cryptographically strong pseudo-random number generator.</p>
*
* <p>All the abstract methods in the {@link SecureRandomSpi} class are
* implemented by this class and all its sub-classes.</p>
*/
abstract class SecureRandomAdapter extends SecureRandomSpi
{
// Constants and variables
// -------------------------------------------------------------------------
/** Our underlying prng instance. */
private MDGenerator adaptee = new MDGenerator();
/** The name of the message digest algorithm used by the adaptee. */
private String mdName;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* <p>Trivial protected constructor.</p>
*
* @param mdName the canonical name of the underlying hash algorithm.
*/
protected SecureRandomAdapter(String mdName)
{
super();
this.mdName = mdName;
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// java.security.SecureRandomSpi interface implementation ------------------
public byte[] engineGenerateSeed(int numBytes)
{
if (numBytes < 1)
{
return new byte[0];
}
byte[] result = new byte[numBytes];
this.engineNextBytes(result);
return result;
}
public void engineNextBytes(byte[] bytes)
{
if (!adaptee.isInitialised())
{
this.engineSetSeed(new byte[0]);
}
try
{
adaptee.nextBytes(bytes, 0, bytes.length);
}
catch (LimitReachedException ignored)
{
}
}
public void engineSetSeed(byte[] seed)
{
HashMap attributes = new HashMap();
attributes.put(MDGenerator.MD_NAME, mdName);
attributes.put(MDGenerator.SEEED, seed);
adaptee.init(attributes);
}
}
@@ -0,0 +1,66 @@
/* Sha160RandomSpi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.Registry;
/**
* The implementation of the SHA1-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
*/
public class Sha160RandomSpi extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha160RandomSpi()
{
super(Registry.SHA160_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,66 @@
/* Sha256RandomSpi.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.Registry;
/**
* <p>The implementation of the SHA-256 based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.</p>
*/
public class Sha256RandomSpi extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha256RandomSpi()
{
super(Registry.SHA256_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,66 @@
/* Sha384RandomSpi.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.Registry;
/**
* <p>The implementation of the SHA-384 based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.</p>
*/
public class Sha384RandomSpi extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha384RandomSpi()
{
super(Registry.SHA384_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,66 @@
/* Sha512RandomSpi.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.Registry;
/**
* <p>The implementation of the SHA-512 based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.</p>
*/
public class Sha512RandomSpi extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha512RandomSpi()
{
super(Registry.SHA512_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,66 @@
/* TigerRandomSpi.java --
Copyright (C) 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.Registry;
/**
* The implementation of the Tiger based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
*/
public class TigerRandomSpi extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public TigerRandomSpi()
{
super(Registry.TIGER_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,66 @@
/* WhirlpoolRandomSpi.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.prng;
import gnu.java.security.Registry;
/**
* The implementation of the Whirlpool-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
*/
public class WhirlpoolRandomSpi extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public WhirlpoolRandomSpi()
{
super(Registry.WHIRLPOOL_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,238 @@
/* DSSKeyFactory.java -- JCE DSA key factory Adapter
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Registry;
import gnu.java.security.key.dss.DSSKeyPairPKCS8Codec;
import gnu.java.security.key.dss.DSSKeyPairX509Codec;
import gnu.java.security.key.dss.DSSPrivateKey;
import gnu.java.security.key.dss.DSSPublicKey;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactorySpi;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* DSA key factory.
*
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class DSSKeyFactory extends KeyFactorySpi
{
// implicit 0-arguments constructor
protected PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException
{
if (keySpec instanceof DSAPublicKeySpec)
{
DSAPublicKeySpec spec = (DSAPublicKeySpec) keySpec;
BigInteger p = spec.getP();
BigInteger q = spec.getQ();
BigInteger g = spec.getG();
BigInteger y = spec.getY();
return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y);
}
if (keySpec instanceof X509EncodedKeySpec)
{
X509EncodedKeySpec spec = (X509EncodedKeySpec) keySpec;
byte[] encoded = spec.getEncoded();
PublicKey result;
try
{
result = new DSSKeyPairX509Codec().decodePublicKey(encoded);
return result;
}
catch (RuntimeException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
}
}
throw new InvalidKeySpecException("Unsupported (public) key specification");
}
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException
{
if (keySpec instanceof DSAPrivateKeySpec)
{
DSAPrivateKeySpec spec = (DSAPrivateKeySpec) keySpec;
BigInteger p = spec.getP();
BigInteger q = spec.getQ();
BigInteger g = spec.getG();
BigInteger x = spec.getX();
return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x);
}
if (keySpec instanceof PKCS8EncodedKeySpec)
{
PKCS8EncodedKeySpec spec = (PKCS8EncodedKeySpec) keySpec;
byte[] encoded = spec.getEncoded();
PrivateKey result;
try
{
result = new DSSKeyPairPKCS8Codec().decodePrivateKey(encoded);
return result;
}
catch (RuntimeException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
}
}
throw new InvalidKeySpecException("Unsupported (private) key specification");
}
protected KeySpec engineGetKeySpec(Key key, Class keySpec)
throws InvalidKeySpecException
{
if (key instanceof DSAPublicKey)
{
if (keySpec.isAssignableFrom(DSAPublicKeySpec.class))
{
DSAPublicKey dsaKey = (DSAPublicKey) key;
BigInteger p = dsaKey.getParams().getP();
BigInteger q = dsaKey.getParams().getQ();
BigInteger g = dsaKey.getParams().getG();
BigInteger y = dsaKey.getY();
return new DSAPublicKeySpec(y, p, q, g);
}
if (keySpec.isAssignableFrom(X509EncodedKeySpec.class))
{
if (key instanceof DSSPublicKey)
{
DSSPublicKey dssKey = (DSSPublicKey) key;
byte[] encoded = dssKey.getEncoded(Registry.X509_ENCODING_ID);
return new X509EncodedKeySpec(encoded);
}
if (Registry.X509_ENCODING_SORT_NAME.equalsIgnoreCase(key.getFormat()))
{
byte[] encoded = key.getEncoded();
return new X509EncodedKeySpec(encoded);
}
throw new InvalidKeySpecException("Wrong key type or unsupported (public) key specification");
}
throw new InvalidKeySpecException("Unsupported (public) key specification");
}
if (key instanceof DSAPrivateKey)
{
if (keySpec.isAssignableFrom(DSAPrivateKeySpec.class))
{
DSAPrivateKey dsaKey = (DSAPrivateKey) key;
BigInteger p = dsaKey.getParams().getP();
BigInteger q = dsaKey.getParams().getQ();
BigInteger g = dsaKey.getParams().getG();
BigInteger x = dsaKey.getX();
return new DSAPrivateKeySpec(x, p, q, g);
}
if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class))
{
if (key instanceof DSSPrivateKey)
{
DSSPrivateKey dssKey = (DSSPrivateKey) key;
byte[] encoded = dssKey.getEncoded(Registry.PKCS8_ENCODING_ID);
return new PKCS8EncodedKeySpec(encoded);
}
if (Registry.PKCS8_ENCODING_SHORT_NAME.equalsIgnoreCase(key.getFormat()))
{
byte[] encoded = key.getEncoded();
return new PKCS8EncodedKeySpec(encoded);
}
throw new InvalidKeySpecException("Wrong key type or unsupported (private) key specification");
}
throw new InvalidKeySpecException("Unsupported (private) key specification");
}
throw new InvalidKeySpecException("Wrong key type or unsupported key specification");
}
protected Key engineTranslateKey(Key key) throws InvalidKeyException
{
if ((key instanceof DSSPublicKey) || (key instanceof DSSPrivateKey))
return key;
if (key instanceof DSAPublicKey)
{
DSAPublicKey dsaKey = (DSAPublicKey) key;
BigInteger p = dsaKey.getParams().getP();
BigInteger q = dsaKey.getParams().getQ();
BigInteger g = dsaKey.getParams().getG();
BigInteger y = dsaKey.getY();
return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y);
}
if (key instanceof DSAPrivateKey)
{
DSAPrivateKey dsaKey = (DSAPrivateKey) key;
BigInteger p = dsaKey.getParams().getP();
BigInteger q = dsaKey.getParams().getQ();
BigInteger g = dsaKey.getParams().getG();
BigInteger x = dsaKey.getX();
return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x);
}
throw new InvalidKeyException("Wrong key type");
}
}
@@ -0,0 +1,169 @@
/* DSSKeyPairGeneratorSpi.java --
Copyright 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Registry;
import gnu.java.security.key.dss.DSSKeyPairGenerator;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidParameterException;
import java.security.SecureRandom;
import java.security.interfaces.DSAKeyPairGenerator;
import java.security.interfaces.DSAParams;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.DSAParameterSpec;
import java.util.HashMap;
/**
* The implementation of a {@link java.security.KeyPairGenerator} adapter class
* to wrap gnu.crypto DSS keypair generator instances.<p>
*
* In case the client does not explicitly initialize the KeyPairGenerator (via
* a call to an <code>initialize()</code> method), the GNU Crypto provider
* uses a default <i>modulus</i> size (keysize) of 1024 bits.<p>
*
* @version $Revision: 1.3 $
*/
public class DSSKeyPairGeneratorSpi extends KeyPairGeneratorAdapter implements
DSAKeyPairGenerator
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public DSSKeyPairGeneratorSpi()
{
super(Registry.DSS_KPG);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
public void initialize(int keysize, SecureRandom random)
{
this.initialize(keysize, false, random);
}
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException
{
HashMap attributes = new HashMap();
if (params != null)
{
if (!(params instanceof DSAParameterSpec))
throw new InvalidAlgorithmParameterException(
"Parameters argument is not a non-null instance, or " +
"sub-instance, of java.security.spec.DSAParameterSpec");
attributes.put(DSSKeyPairGenerator.DSS_PARAMETERS, params);
}
if (random != null)
{
attributes.put(DSSKeyPairGenerator.SOURCE_OF_RANDOMNESS, random);
}
attributes.put(DSSKeyPairGenerator.PREFERRED_ENCODING_FORMAT,
new Integer(Registry.ASN1_ENCODING_ID));
try
{
adaptee.setup(attributes);
}
catch (IllegalArgumentException x)
{
InvalidAlgorithmParameterException y =
new InvalidAlgorithmParameterException();
y.initCause(x);
throw y;
}
}
// java.security.interfaces.DSAKeyPairGenerator interface implementation -----
public void initialize(DSAParams params, SecureRandom random)
throws InvalidParameterException
{
if (params == null || !(params instanceof DSAParameterSpec))
throw new InvalidParameterException(
"Parameters argument is either null or is not an instance, or " +
"sub-instance, of java.security.spec.DSAParameterSpec");
DSAParameterSpec spec = (DSAParameterSpec) params;
try
{
this.initialize((AlgorithmParameterSpec) spec, random);
}
catch (InvalidAlgorithmParameterException x)
{
InvalidParameterException y = new InvalidParameterException();
y.initCause(x);
throw y;
}
}
public void initialize(int modlen, boolean genParams, SecureRandom random)
throws InvalidParameterException
{
HashMap attributes = new HashMap();
attributes.put(DSSKeyPairGenerator.MODULUS_LENGTH, new Integer(modlen));
if (random != null)
attributes.put(DSSKeyPairGenerator.SOURCE_OF_RANDOMNESS, random);
attributes.put(DSSKeyPairGenerator.USE_DEFAULTS,
Boolean.valueOf(!genParams));
attributes.put(DSSKeyPairGenerator.STRICT_DEFAULTS, Boolean.TRUE);
attributes.put(DSSKeyPairGenerator.PREFERRED_ENCODING_FORMAT,
new Integer(Registry.ASN1_ENCODING_ID));
try
{
adaptee.setup(attributes);
}
catch (IllegalArgumentException x)
{
InvalidParameterException y = new InvalidParameterException();
y.initCause(x);
throw y;
}
}
}
@@ -0,0 +1,220 @@
/* DSSParameters.java -- DSS parameters DAO
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Registry;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import gnu.java.security.util.DerUtil;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.AlgorithmParametersSpi;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.DSAParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.util.ArrayList;
/**
* A JCE-specific Data Access Object (DAO) for DSS parameters.
*/
public class DSSParameters
extends AlgorithmParametersSpi
{
/**
* A prime modulus, where <code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup></code>
* for <code>512 &lt;= L &lt;= 1024</code> and <code>L</code> a multiple of
* <code>64</code>.
*/
private BigInteger p;
/**
* A prime divisor of <code>p - 1</code>, where <code>2<sup>159</sup> &lt; q
* &lt; 2<sup>160</sup></code>.
*/
private BigInteger q;
/**
* <code>g = h<sup>(p-1)</sup>/q mod p</code>, where <code>h</code> is any
* integer with <code>1 &lt; h &lt; p - 1</code> such that <code>h<sup>
* (p-1)</sup>/q mod p > 1</code> (<code>g</code> has order <code>q mod p
* </code>).
*/
private BigInteger g;
// default 0-arguments constructor
protected void engineInit(AlgorithmParameterSpec spec)
throws InvalidParameterSpecException
{
if (! (spec instanceof DSAParameterSpec))
throw new InvalidParameterSpecException("Wrong AlgorithmParameterSpec type: "
+ spec.getClass().getName());
DSAParameterSpec dsaSpec = (DSAParameterSpec) spec;
p = dsaSpec.getP();
q = dsaSpec.getQ();
g = dsaSpec.getG();
}
/**
* Decodes the set of DSS parameters as per RFC-2459; i.e. the DER-encoded
* form of the following ASN.1 construct:
*
* <pre>
* DssParams ::= SEQUENCE {
* p INTEGER,
* q INTEGER,
* g INTEGER
* }
* </pre>
*/
protected void engineInit(byte[] params) throws IOException
{
DERReader der = new DERReader(params);
DERValue derParams = der.read();
DerUtil.checkIsConstructed(derParams, "Wrong DSS Parameters field");
DERValue val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong P field");
p = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong Q field");
q = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong G field");
g = (BigInteger) val.getValue();
}
protected void engineInit(byte[] params, String format) throws IOException
{
if (format != null)
{
format = format.trim();
if (format.length() == 0)
throw new IOException("Format MUST NOT be an empty string");
if (! format.equalsIgnoreCase(Registry.ASN1_ENCODING_SHORT_NAME))
throw new IOException("Unknown or unsupported format: " + format);
}
engineInit(params);
}
protected AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec)
throws InvalidParameterSpecException
{
if (! paramSpec.isAssignableFrom(DSAParameterSpec.class))
throw new InvalidParameterSpecException("Wrong AlgorithmParameterSpec type: "
+ paramSpec.getName());
return new DSAParameterSpec(p, q, g);
}
/**
* Encodes the set of DSS parameters as per RFC-2459; i.e. as the DER-encoded
* form of the following ASN.1 construct:
*
* <pre>
* DssParams ::= SEQUENCE {
* p INTEGER,
* q INTEGER,
* g INTEGER
* }
* </pre>
*/
protected byte[] engineGetEncoded() throws IOException
{
DERValue derP = new DERValue(DER.INTEGER, p);
DERValue derQ = new DERValue(DER.INTEGER, q);
DERValue derG = new DERValue(DER.INTEGER, g);
ArrayList params = new ArrayList(3);
params.add(derP);
params.add(derQ);
params.add(derG);
DERValue derParams = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, params);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DERWriter.write(baos, derParams);
byte[] result = baos.toByteArray();
return result;
}
protected byte[] engineGetEncoded(String format) throws IOException
{
if (format != null)
{
format = format.trim();
if (format.length() == 0)
throw new IOException("Format MUST NOT be an empty string");
if (! format.equalsIgnoreCase(Registry.ASN1_ENCODING_SHORT_NAME))
throw new IOException("Unknown or unsupported format: " + format);
}
return engineGetEncoded();
}
protected String engineToString()
{
StringBuffer sb = new StringBuffer("p=");
if (p == null)
sb.append("???");
else
sb.append("0x").append(p.toString(16));
sb.append(", q=");
if (q == null)
sb.append("???");
else
sb.append("0x").append(q.toString(16));
sb.append(", g=");
if (g == null)
sb.append("???");
else
sb.append("0x").append(g.toString(16));
return sb.toString();
}
}
@@ -0,0 +1,125 @@
/* DSSParametersGenerator.java -- JCE Adapter for a generator of DSS parameters
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Registry;
import gnu.java.security.key.dss.DSSKeyPairGenerator;
import gnu.java.security.key.dss.FIPS186;
import gnu.java.security.provider.Gnu;
import java.math.BigInteger;
import java.security.AlgorithmParameterGeneratorSpi;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.DSAParameterSpec;
import java.security.spec.InvalidParameterSpecException;
/**
* A JCE Adapter for a generator of DSS parameters.
*/
public class DSSParametersGenerator
extends AlgorithmParameterGeneratorSpi
{
private static final Provider GNU = new Gnu();
/** Size of the public modulus in bits. */
private int modulusLength = -1;
/** User specified source of randomness. */
private SecureRandom rnd;
/** Our concrete DSS parameters generator. */
private FIPS186 fips;
// default 0-arguments constructor
protected void engineInit(int size, SecureRandom random)
{
if ((size % 64) != 0 || size < 512 || size > 1024)
throw new InvalidParameterException("Modulus size/length (in bits) MUST "
+ "be a multiple of 64, greater than "
+ "or equal to 512, and less than or "
+ "equal to 1024");
this.modulusLength = size;
this.rnd = random;
}
protected void engineInit(AlgorithmParameterSpec spec, SecureRandom random)
throws InvalidAlgorithmParameterException
{
if (! (spec instanceof DSAParameterSpec))
throw new InvalidAlgorithmParameterException("Wrong AlgorithmParameterSpec type: "
+ spec.getClass().getName());
DSAParameterSpec dsaSpec = (DSAParameterSpec) spec;
BigInteger p = dsaSpec.getP();
int size = p.bitLength();
this.engineInit(size, random);
}
protected AlgorithmParameters engineGenerateParameters()
{
if (modulusLength < 1)
modulusLength = DSSKeyPairGenerator.DEFAULT_MODULUS_LENGTH;
fips = new FIPS186(modulusLength, rnd);
BigInteger[] params = fips.generateParameters();
BigInteger p = params[3];
BigInteger q = params[2];
BigInteger g = params[5];
DSAParameterSpec spec = new DSAParameterSpec(p, q, g);
AlgorithmParameters result = null;
try
{
result = AlgorithmParameters.getInstance(Registry.DSS_KPG, GNU);
result.init(spec);
}
catch (NoSuchAlgorithmException ignore)
{
}
catch (InvalidParameterSpecException ignore)
{
}
return result;
}
}
@@ -0,0 +1,70 @@
/* DSSRawSignatureSpi.java --
Copyright 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Registry;
import gnu.java.security.sig.dss.DSSSignatureRawCodec;
/**
* The implementation of <i>Service Provider Interface</i> (<b>SPI</b>) adapter
* for the DSS (Digital Signature Standard) signature scheme, encoded and/or
* decoded in RAW format.<p>
*
* @version $Revision: 1.1 $
*/
public class DSSRawSignatureSpi extends SignatureAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public DSSRawSignatureSpi()
{
super(Registry.DSS_SIG, new DSSSignatureRawCodec());
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,453 @@
/* EncodedKeyFactory.java -- JCE Encoded key factory Adapter
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Registry;
import gnu.java.security.key.dss.DSSPrivateKey;
import gnu.java.security.key.dss.DSSPublicKey;
import gnu.java.security.key.rsa.GnuRSAPrivateKey;
import gnu.java.security.key.rsa.GnuRSAPublicKey;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.Key;
import java.security.KeyFactorySpi;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHPrivateKeySpec;
import javax.crypto.spec.DHPublicKeySpec;
/**
* A factory for keys encoded in either the X.509 format (for public keys) or
* the PKCS#8 format (for private keys).
*/
public class EncodedKeyFactory
extends KeyFactorySpi
{
private static final Logger log = Logger.getLogger(EncodedKeyFactory.class.getName());
// implicit 0-arguments constructor
// Class methods
// --------------------------------------------------------------------------
private static Object invokeConstructor(String className, Object[] params)
throws InvalidKeySpecException
{
Class clazz = getConcreteClass(className);
try
{
Constructor ctor = getConcreteCtor(clazz);
Object result = ctor.newInstance(params);
return result;
}
catch (InstantiationException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
}
catch (IllegalAccessException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(y);
throw y;
}
catch (InvocationTargetException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
}
}
private static Class getConcreteClass(String className)
throws InvalidKeySpecException
{
try
{
Class result = Class.forName(className);
return result;
}
catch (ClassNotFoundException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
}
}
private static Constructor getConcreteCtor(Class clazz)
throws InvalidKeySpecException
{
try
{
Constructor result = clazz.getConstructor(new Class[] {int.class,
BigInteger.class,
BigInteger.class,
BigInteger.class,
BigInteger.class});
return result;
}
catch (NoSuchMethodException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
}
}
private static Object invokeValueOf(String className, byte[] encoded)
throws InvalidKeySpecException
{
Class clazz = getConcreteClass(className);
try
{
Method valueOf = getValueOfMethod(clazz);
Object result = valueOf.invoke(null, new Object[] { encoded });
return result;
}
catch (IllegalAccessException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
}
catch (InvocationTargetException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
}
}
private static Method getValueOfMethod(Class clazz)
throws InvalidKeySpecException
{
try
{
Method result = clazz.getMethod("valueOf", new Class[] {byte[].class});
return result;
}
catch (NoSuchMethodException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
}
}
// Instance methods
// --------------------------------------------------------------------------
protected PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException
{
log.entering(this.getClass().getName(), "engineGeneratePublic()", keySpec);
PublicKey result = null;
if (keySpec instanceof DSAPublicKeySpec)
result = decodeDSSPublicKey((DSAPublicKeySpec) keySpec);
else if (keySpec instanceof RSAPublicKeySpec)
result = decodeRSAPublicKey((RSAPublicKeySpec) keySpec);
else if (keySpec instanceof DHPublicKeySpec)
result = decodeDHPublicKey((DHPublicKeySpec) keySpec);
else
{
if (! (keySpec instanceof X509EncodedKeySpec))
throw new InvalidKeySpecException("Unsupported key specification");
byte[] input = ((X509EncodedKeySpec) keySpec).getEncoded();
boolean ok = false;
// try DSS
try
{
result = DSSPublicKey.valueOf(input);
ok = true;
}
catch (InvalidParameterException ignored)
{
log.log(Level.FINE, "Exception in DSSPublicKey.valueOf(). Ignore",
ignored);
}
if (! ok) // try RSA
try
{
result = GnuRSAPublicKey.valueOf(input);
ok = true;
}
catch (InvalidParameterException ignored)
{
log.log(Level.FINE,
"Exception in GnuRSAPublicKey.valueOf(). Ignore",
ignored);
}
if (! ok) // try DH
result = decodeDHPublicKey(input);
}
log.exiting(this.getClass().getName(), "engineGeneratePublic()", result);
return result;
}
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException
{
log.entering(this.getClass().getName(), "engineGeneratePrivate()", keySpec);
PrivateKey result = null;
if (keySpec instanceof DSAPrivateKeySpec)
result = decodeDSSPrivateKey((DSAPrivateKeySpec) keySpec);
else if (keySpec instanceof RSAPrivateCrtKeySpec)
result = decodeRSAPrivateKey((RSAPrivateCrtKeySpec) keySpec);
else if (keySpec instanceof DHPrivateKeySpec)
result = decodeDHPrivateKey((DHPrivateKeySpec) keySpec);
else
{
if (! (keySpec instanceof PKCS8EncodedKeySpec))
throw new InvalidKeySpecException("Unsupported key specification");
byte[] input = ((PKCS8EncodedKeySpec) keySpec).getEncoded();
boolean ok = false;
// try DSS
try
{
result = DSSPrivateKey.valueOf(input);
ok = true;
}
catch (InvalidParameterException ignored)
{
log.log(Level.FINE, "Exception in DSSPrivateKey.valueOf(). Ignore",
ignored);
}
if (! ok) // try RSA
try
{
result = GnuRSAPrivateKey.valueOf(input);
ok = true;
}
catch (InvalidParameterException ignored)
{
log.log(Level.FINE,
"Exception in GnuRSAPrivateKey.valueOf(). Ignore",
ignored);
}
if (! ok) // try DH
result = decodeDHPrivateKey(input);
}
log.exiting(this.getClass().getName(), "engineGeneratePrivate()", result);
return result;
}
protected KeySpec engineGetKeySpec(Key key, Class keySpec)
throws InvalidKeySpecException
{
if (key instanceof PublicKey
&& Registry.X509_ENCODING_SORT_NAME.equalsIgnoreCase(key.getFormat())
&& keySpec.isAssignableFrom(X509EncodedKeySpec.class))
return new X509EncodedKeySpec(key.getEncoded());
if (key instanceof PrivateKey
&& Registry.PKCS8_ENCODING_SHORT_NAME.equalsIgnoreCase(key.getFormat())
&& keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class))
return new PKCS8EncodedKeySpec(key.getEncoded());
throw new InvalidKeySpecException("Unsupported format or invalid key spec class");
}
protected Key engineTranslateKey(Key key) throws InvalidKeyException
{
throw new InvalidKeyException("Key translation not supported");
}
/**
* @param spec an instance of {@link DSAPublicKeySpec} to decode.
* @return an instance of {@link DSSPublicKey} constructed from the
* information in the designated key-specification.
*/
private DSSPublicKey decodeDSSPublicKey(DSAPublicKeySpec spec)
{
BigInteger p = spec.getP();
BigInteger q = spec.getQ();
BigInteger g = spec.getG();
BigInteger y = spec.getY();
return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y);
}
/**
* @param spec an instance of {@link RSAPublicKeySpec} to decode.
* @return an instance of {@link GnuRSAPublicKey} constructed from the
* information in the designated key-specification.
*/
private GnuRSAPublicKey decodeRSAPublicKey(RSAPublicKeySpec spec)
{
BigInteger n = spec.getModulus();
BigInteger e = spec.getPublicExponent();
return new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e);
}
/**
* @param spec an instance of {@link DHPublicKeySpec} to decode.
* @return an instance of a {@link DHPublicKey} constructed from the
* information in the designated key-specification.
* @throws InvalidKeySpecException if no concrete implementation of the
* {@link DHPublicKey} interface exists at run-time, or if an
* exception occurs during its instantiation.
*/
private DHPublicKey decodeDHPublicKey(DHPublicKeySpec spec)
throws InvalidKeySpecException
{
BigInteger p = spec.getP();
BigInteger g = spec.getG();
BigInteger y = spec.getY();
Object[] params = new Object[] {new Integer(Registry.X509_ENCODING_ID),
null, p, g, y};
Object obj = invokeConstructor("gnu.javax.crypto.key.dh.GnuDHPublicKey",
params);
return (DHPublicKey) obj;
}
/**
* @param encoded the bytes to decode.
* @return an instance of a {@link DHPublicKey} constructed from the
* information in the designated key-specification.
* @throws InvalidKeySpecException if no concrete implementation of the
* {@link DHPublicKey} interface exists at run-time, or if an
* exception occurs during its instantiation.
*/
private DHPublicKey decodeDHPublicKey(byte[] encoded)
throws InvalidKeySpecException
{
Object obj = invokeValueOf("gnu.javax.crypto.key.dh.GnuDHPublicKey",
encoded);
return (DHPublicKey) obj;
}
/**
* @param spec an instance of {@link DSAPrivateKeySpec} to decode.
* @return an instance of {@link DSSPrivateKey} constructed from the
* information in the designated key-specification.
*/
private PrivateKey decodeDSSPrivateKey(DSAPrivateKeySpec spec)
{
BigInteger p = spec.getP();
BigInteger q = spec.getQ();
BigInteger g = spec.getG();
BigInteger x = spec.getX();
return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x);
}
/**
* @param spec an instance of {@link RSAPrivateCrtKeySpec} to decode.
* @return an instance of {@link GnuRSAPrivateKey} constructed from the
* information in the designated key-specification.
*/
private PrivateKey decodeRSAPrivateKey(RSAPrivateCrtKeySpec spec)
{
BigInteger n = spec.getModulus();
BigInteger e = spec.getPublicExponent();
BigInteger d = spec.getPrivateExponent();
BigInteger p = spec.getPrimeP();
BigInteger q = spec.getPrimeQ();
BigInteger dP = spec.getPrimeExponentP();
BigInteger dQ = spec.getPrimeExponentQ();
BigInteger qInv = spec.getCrtCoefficient();
return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID,
n, e, d, p, q, dP, dQ, qInv);
}
/**
* @param spec an instance of {@link DHPrivateKeySpec} to decode.
* @return an instance of a {@link DHPrivateKey} constructed from the
* information in the designated key-specification.
* @throws InvalidKeySpecException if no concrete implementation of the
* {@link DHPrivateKey} interface exists at run-time, or if an
* exception occurs during its instantiation.
*/
private DHPrivateKey decodeDHPrivateKey(DHPrivateKeySpec spec)
throws InvalidKeySpecException
{
BigInteger p = spec.getP();
BigInteger g = spec.getG();
BigInteger x = spec.getX();
Object[] params = new Object[] {new Integer(Registry.PKCS8_ENCODING_ID),
null, p, g, x};
Object obj = invokeConstructor("gnu.javax.crypto.key.dh.GnuDHPrivateKey",
params);
return (DHPrivateKey) obj;
}
/**
* @param encoded the bytes to decode.
* @return an instance of a {@link DHPrivateKey} constructed from the
* information in the designated key-specification.
* @throws InvalidKeySpecException if no concrete implementation of the
* {@link DHPrivateKey} interface exists at run-time, or if an
* exception occurs during its instantiation.
*/
private DHPrivateKey decodeDHPrivateKey(byte[] encoded)
throws InvalidKeySpecException
{
Object obj = invokeValueOf("gnu.javax.crypto.key.dh.GnuDHPrivateKey",
encoded);
return (DHPrivateKey) obj;
}
}
@@ -0,0 +1,109 @@
/* KeyPairGeneratorAdapter.java --
Copyright 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.key.IKeyPairGenerator;
import gnu.java.security.key.KeyPairGeneratorFactory;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
/**
* The implementation of a generic {@link java.security.KeyPairGenerator}
* adapter class to wrap gnu.crypto keypair generator instances.<p>
*
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) for the
* {@link java.security.KeyPairGenerator} class, which is used to generate pairs
* of public and private keys.<p>
*
* All the abstract methods in the {@link java.security.KeyPairGeneratorSpi}
* class are implemented by this class and all its sub-classes.<p>
*
* In case the client does not explicitly initialize the KeyPairGenerator (via
* a call to an <code>initialize()</code> method), the GNU Crypto provider
* supplies (and document) default values to be used. For example, the GNU
* Crypto provider uses a default <i>modulus</i> size (keysize) of 1024 bits for
* the DSS (Digital Signature Standard) a.k.a <i>DSA</i>.<p>
*
* @version $Revision: 1.3 $
*/
public abstract class KeyPairGeneratorAdapter extends KeyPairGenerator
{
// Constants and variables
// -------------------------------------------------------------------------
/** Our underlying keypair instance. */
protected IKeyPairGenerator adaptee;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Trivial protected constructor.
*
* @param kpgName the canonical name of the keypair generator algorithm.
*/
protected KeyPairGeneratorAdapter(String kpgName)
{
super(kpgName);
this.adaptee = KeyPairGeneratorFactory.getInstance(kpgName);
}
// Class methods
// -------------------------------------------------------------------------
// java.security.KeyPairGeneratorSpi interface implementation
// -------------------------------------------------------------------------
public abstract void initialize(int keysize, SecureRandom random);
public abstract void initialize(AlgorithmParameterSpec params,
SecureRandom random)
throws InvalidAlgorithmParameterException;
public KeyPair generateKeyPair()
{
return adaptee.generate();
}
}
@@ -1,5 +1,5 @@
/* MD2withRSA.java -- MD2 with RSA encryption signatures.
Copyright (C) 2004 Free Software Foundation, Inc.
/* MD2WithRSA.java -- RSA PKCS1 with MD2 JCE signature Adapter
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -36,19 +36,21 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
package gnu.java.security.jce.sig;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import gnu.java.security.Registry;
import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec;
public class MD2withRSA extends RSA
/**
* A JCE Adapter for the RSA PKCS1 (v1.5) signature with MD2 hash and X.509
* encoding format.
*/
public class MD2withRSA
extends SignatureAdapter
{
// Constructor.
// -------------------------------------------------------------------------
public MD2withRSA() throws NoSuchAlgorithmException
public MD2withRSA()
{
super(MessageDigest.getInstance("MD2"), DIGEST_ALGORITHM.getChild(2));
super(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.MD2_HASH,
new RSAPKCS1V1_5SignatureX509Codec());
}
}
@@ -1,5 +1,5 @@
/* MD5withRSA.java -- MD5 with RSA encryption signatures.
Copyright (C) 2004 Free Software Foundation, Inc.
/* MD5withRSA.java -- RSA PKCS1 with MD5 JCE signature Adapter
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -36,19 +36,21 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
package gnu.java.security.jce.sig;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import gnu.java.security.Registry;
import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec;
public class MD5withRSA extends RSA
/**
* A JCE Adapter for the RSA PKCS1 (v1.5) signature with MD5 hash and X.509
* encoding format.
*/
public class MD5withRSA
extends SignatureAdapter
{
// Constructor.
// -------------------------------------------------------------------------
public MD5withRSA() throws NoSuchAlgorithmException
public MD5withRSA()
{
super(MessageDigest.getInstance("MD5"), DIGEST_ALGORITHM.getChild(5));
super(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.MD5_HASH,
new RSAPKCS1V1_5SignatureX509Codec());
}
}
@@ -0,0 +1,265 @@
/* RSAKeyFactory.java -- RSA key-factory JCE Adapter
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Registry;
import gnu.java.security.key.rsa.GnuRSAPrivateKey;
import gnu.java.security.key.rsa.GnuRSAPublicKey;
import gnu.java.security.key.rsa.RSAKeyPairPKCS8Codec;
import gnu.java.security.key.rsa.RSAKeyPairX509Codec;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactorySpi;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RSAKeyFactory
extends KeyFactorySpi
{
// implicit 0-arguments constructor
protected PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException
{
if (keySpec instanceof RSAPublicKeySpec)
{
RSAPublicKeySpec spec = (RSAPublicKeySpec) keySpec;
BigInteger n = spec.getModulus();
BigInteger e = spec.getPublicExponent();
return new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e);
}
if (keySpec instanceof X509EncodedKeySpec)
{
X509EncodedKeySpec spec = (X509EncodedKeySpec) keySpec;
byte[] encoded = spec.getEncoded();
PublicKey result;
try
{
result = new RSAKeyPairX509Codec().decodePublicKey(encoded);
}
catch (RuntimeException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
}
}
throw new InvalidKeySpecException("Unsupported (public) key specification");
}
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException
{
if (keySpec instanceof RSAPrivateCrtKeySpec)
{
RSAPrivateCrtKeySpec spec = (RSAPrivateCrtKeySpec) keySpec;
BigInteger n = spec.getModulus();
BigInteger e = spec.getPublicExponent();
BigInteger d = spec.getPrivateExponent();
BigInteger p = spec.getPrimeP();
BigInteger q = spec.getPrimeQ();
BigInteger dP = spec.getPrimeExponentP();
BigInteger dQ = spec.getPrimeExponentQ();
BigInteger qInv = spec.getCrtCoefficient();
return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID,
n, e, d, p, q, dP, dQ, qInv);
}
// if (keySpec instanceof RSAPrivateKeySpec)
// {
// RSAPrivateKeySpec spec = (RSAPrivateKeySpec) keySpec;
// BigInteger n = spec.getModulus();
// BigInteger d = spec.getPrivateExponent();
// return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID,
// n, null, d, null, null, null, null, null);
// }
if (keySpec instanceof PKCS8EncodedKeySpec)
{
PKCS8EncodedKeySpec spec = (PKCS8EncodedKeySpec) keySpec;
byte[] encoded = spec.getEncoded();
PrivateKey result;
try
{
result = new RSAKeyPairPKCS8Codec().decodePrivateKey(encoded);
}
catch (RuntimeException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
}
}
throw new InvalidKeySpecException("Unsupported (private) key specification");
}
protected KeySpec engineGetKeySpec(Key key, Class keySpec)
throws InvalidKeySpecException
{
if (key instanceof RSAPublicKey)
{
if (keySpec.isAssignableFrom(RSAPublicKeySpec.class))
{
RSAPublicKey rsaKey = (RSAPublicKey) key;
BigInteger n = rsaKey.getModulus();
BigInteger e = rsaKey.getPublicExponent();
return new RSAPublicKeySpec(n, e);
}
if (keySpec.isAssignableFrom(X509EncodedKeySpec.class))
{
if (key instanceof GnuRSAPublicKey)
{
GnuRSAPublicKey rsaKey = (GnuRSAPublicKey) key;
byte[] encoded = rsaKey.getEncoded(Registry.X509_ENCODING_ID);
return new X509EncodedKeySpec(encoded);
}
if (Registry.X509_ENCODING_SORT_NAME.equalsIgnoreCase(key.getFormat()))
{
byte[] encoded = key.getEncoded();
return new X509EncodedKeySpec(encoded);
}
throw new InvalidKeySpecException("Wrong key type or unsupported (public) key specification");
}
throw new InvalidKeySpecException("Unsupported (public) key specification");
}
if ((key instanceof RSAPrivateCrtKey)
&& keySpec.isAssignableFrom(RSAPrivateCrtKeySpec.class))
{
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
BigInteger n = rsaKey.getModulus();
BigInteger e = rsaKey.getPublicExponent();
BigInteger d = rsaKey.getPrivateExponent();
BigInteger p = rsaKey.getPrimeP();
BigInteger q = rsaKey.getPrimeQ();
BigInteger dP = rsaKey.getPrimeExponentP();
BigInteger dQ = rsaKey.getPrimeExponentQ();
BigInteger qInv = rsaKey.getCrtCoefficient();
return new RSAPrivateCrtKeySpec(n, e, d, p, q, dP, dQ, qInv);
}
if ((key instanceof RSAPrivateKey)
&& keySpec.isAssignableFrom(RSAPrivateKeySpec.class))
{
RSAPrivateKey rsaKey = (RSAPrivateKey) key;
BigInteger n = rsaKey.getModulus();
BigInteger d = rsaKey.getPrivateExponent();
return new RSAPrivateKeySpec(n, d);
}
if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class))
{
if (key instanceof GnuRSAPrivateKey)
{
GnuRSAPrivateKey rsaKey = (GnuRSAPrivateKey) key;
byte[] encoded = rsaKey.getEncoded(Registry.PKCS8_ENCODING_ID);
return new PKCS8EncodedKeySpec(encoded);
}
if (Registry.PKCS8_ENCODING_SHORT_NAME.equalsIgnoreCase(key.getFormat()))
{
byte[] encoded = key.getEncoded();
return new PKCS8EncodedKeySpec(encoded);
}
throw new InvalidKeySpecException("Wrong key type or unsupported (private) key specification");
}
throw new InvalidKeySpecException("Wrong key type or unsupported key specification");
}
protected Key engineTranslateKey(Key key) throws InvalidKeyException
{
if ((key instanceof GnuRSAPublicKey) || (key instanceof GnuRSAPrivateKey))
return key;
if (key instanceof RSAPublicKey)
{
RSAPublicKey rsaKey = (RSAPublicKey) key;
BigInteger n = rsaKey.getModulus();
BigInteger e = rsaKey.getPublicExponent();
return new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e);
}
if (key instanceof RSAPrivateCrtKey)
{
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
BigInteger n = rsaKey.getModulus();
BigInteger e = rsaKey.getPublicExponent();
BigInteger d = rsaKey.getPrivateExponent();
BigInteger p = rsaKey.getPrimeP();
BigInteger q = rsaKey.getPrimeQ();
BigInteger dP = rsaKey.getPrimeExponentP();
BigInteger dQ = rsaKey.getPrimeExponentQ();
BigInteger qInv = rsaKey.getCrtCoefficient();
return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID,
n, e, d, p, q, dP, dQ, qInv);
}
// if (key instanceof RSAPrivateKey)
// {
// RSAPrivateKey rsaKey = (RSAPrivateKey) key;
// BigInteger n = rsaKey.getModulus();
// BigInteger d = rsaKey.getPrivateExponent();
// return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID,
// n, null, d, null, null, null, null, null);
// }
throw new InvalidKeyException("Unsupported key type");
}
}
@@ -0,0 +1,115 @@
/* RSAKeyPairGeneratorSpi.java -- JCE RSA KeyPairGenerator Adapter
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Registry;
import gnu.java.security.key.rsa.RSAKeyPairGenerator;
import java.security.InvalidAlgorithmParameterException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.HashMap;
/**
* The implementation of a {@link java.security.KeyPairGenerator} adapter class
* to wrap gnu.crypto RSA keypair generator instances.<p>
*
* In case the client does not explicitly initialize the KeyPairGenerator (via
* a call to an <code>initialize()</code> method), the GNU Crypto provider
* uses a default <i>modulus</i> size (keysize) of 1024 bits.<p>
*/
public class RSAKeyPairGeneratorSpi extends KeyPairGeneratorAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public RSAKeyPairGeneratorSpi()
{
super(Registry.RSA_KPG);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
public void initialize(int keysize, SecureRandom random)
{
HashMap attributes = new HashMap();
attributes.put(RSAKeyPairGenerator.MODULUS_LENGTH, new Integer(keysize));
if (random != null)
{
attributes.put(RSAKeyPairGenerator.SOURCE_OF_RANDOMNESS, random);
}
attributes.put(RSAKeyPairGenerator.PREFERRED_ENCODING_FORMAT,
new Integer(Registry.ASN1_ENCODING_ID));
adaptee.setup(attributes);
}
public void initialize(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException
{
HashMap attributes = new HashMap();
if (params != null)
{
if (!(params instanceof RSAKeyGenParameterSpec))
{
throw new InvalidAlgorithmParameterException("params");
}
attributes.put(RSAKeyPairGenerator.RSA_PARAMETERS, params);
}
if (random != null)
{
attributes.put(RSAKeyPairGenerator.SOURCE_OF_RANDOMNESS, random);
}
attributes.put(RSAKeyPairGenerator.PREFERRED_ENCODING_FORMAT,
new Integer(Registry.ASN1_ENCODING_ID));
adaptee.setup(attributes);
}
}
@@ -0,0 +1,69 @@
/* RSAPSSRawSignatureSpi.java --
Copyright 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Registry;
import gnu.java.security.sig.rsa.RSAPSSSignatureRawCodec;
/**
* The implementation of <i>Service Provider Interface</i> (<b>SPI</b>) adapter
* for the RSA-PSS signature scheme, encoded and/or decoded in RAW format.<p>
*
* @version $Revision: 1.1 $
*/
public class RSAPSSRawSignatureSpi extends SignatureAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public RSAPSSRawSignatureSpi()
{
super(Registry.RSA_PSS_SIG, new RSAPSSSignatureRawCodec());
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -1,5 +1,5 @@
/* MD4withRSA.java -- MD4 with RSA encryption signatures.
Copyright (C) 2004 Free Software Foundation, Inc.
/* SHA160withDSS.java -- JCE Adapter for DSS with SHA1 signatures
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -36,19 +36,19 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
package gnu.java.security.jce.sig;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import gnu.java.security.Registry;
import gnu.java.security.sig.dss.DSSSignatureX509Codec;
public class MD4withRSA extends RSA
/**
* A JCE Adapter for providing X.509 formatted DSS with SHA1 signatures.
*/
public class SHA160withDSS
extends SignatureAdapter
{
// Constructor.
// -------------------------------------------------------------------------
public MD4withRSA() throws NoSuchAlgorithmException
public SHA160withDSS()
{
super(MessageDigest.getInstance("MD4"), DIGEST_ALGORITHM.getChild(4));
super(Registry.DSS_SIG, new DSSSignatureX509Codec());
}
}
@@ -1,5 +1,5 @@
/* SHA1withRSA.java -- SHA-1 with RSA encryption signatures.
Copyright (C) 2004 Free Software Foundation, Inc.
/* SHA160withRSA.java -- RSA PKCS1 with SHA160 JCE signature Adapter
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -36,26 +36,21 @@ obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
package gnu.java.security.jce.sig;
import gnu.java.security.OID;
import gnu.java.security.Registry;
import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SHA1withRSA extends RSA
/**
* A JCE Adapter for the RSA PKCS1 (v1.5) signature with SHA160 hash and X.509
* encoding format.
*/
public class SHA160withRSA
extends SignatureAdapter
{
// Constant.
// -------------------------------------------------------------------------
private static final OID SHA1 = new OID("1.3.14.3.2.26");
// Constructor.
// -------------------------------------------------------------------------
public SHA1withRSA() throws NoSuchAlgorithmException
public SHA160withRSA()
{
super(MessageDigest.getInstance("SHA-160"), SHA1);
super(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.SHA160_HASH,
new RSAPKCS1V1_5SignatureX509Codec());
}
}
@@ -0,0 +1,56 @@
/* SHA256withRSA.java -- RSA PKCS1 with SHA256 JCE signature Adapter
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Registry;
import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec;
/**
* A JCE Adapter for the RSA PKCS1 (v1.5) signature with SHA256 hash and X.509
* encoding format.
*/
public class SHA256withRSA
extends SignatureAdapter
{
public SHA256withRSA()
{
super(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.SHA256_HASH,
new RSAPKCS1V1_5SignatureX509Codec());
}
}
@@ -0,0 +1,56 @@
/* SHA384withRSA.java -- RSA PKCS1 with SHA384 JCE signature Adapter
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Registry;
import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec;
/**
* A JCE Adapter for the RSA PKCS1 (v1.5) signature with SHA384 hash and X.509
* encoding format.
*/
public class SHA384withRSA
extends SignatureAdapter
{
public SHA384withRSA()
{
super(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.SHA384_HASH,
new RSAPKCS1V1_5SignatureX509Codec());
}
}
@@ -0,0 +1,56 @@
/* SHA512withRSA.java -- RSA PKCS1 with SHA512 JCE signature Adapter
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Registry;
import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec;
/**
* A JCE Adapter for the RSA PKCS1 (v1.5) signature with SHA512 hash and X.509
* encoding format.
*/
public class SHA512withRSA
extends SignatureAdapter
{
public SHA512withRSA()
{
super(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.SHA512_HASH,
new RSAPKCS1V1_5SignatureX509Codec());
}
}
@@ -0,0 +1,263 @@
/* SignatureAdapter.java --
Copyright 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.sig.BaseSignature;
import gnu.java.security.sig.ISignature;
import gnu.java.security.sig.ISignatureCodec;
import gnu.java.security.sig.SignatureFactory;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.SignatureSpi;
import java.security.spec.AlgorithmParameterSpec;
import java.util.HashMap;
import java.util.logging.Logger;
/**
* The implementation of a generic {@link java.security.Signature} adapter class
* to wrap gnu.crypto signature instances.<p>
*
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) for the
* {@link java.security.Signature} class, which provides the functionality of a
* digital signature algorithm. Digital signatures are used for authentication
* and integrity assurance of digital data.<p>
*
* All the abstract methods in the {@link java.security.SignatureSpi} class are
* implemented by this class and all its sub-classes.<p>
*
* All the implementations which subclass this object, and which are serviced by
* the GNU Crypto provider implement the {@link java.lang.Cloneable} interface.<p>
*
* @version $Revision: 1.2 $
*/
class SignatureAdapter extends SignatureSpi implements Cloneable
{
private static final Logger log = Logger.getLogger(SignatureAdapter.class.getName());
// Constants and variables
// -------------------------------------------------------------------------
/** Our underlying signature instance. */
private ISignature adaptee;
/** Our underlying signature encoder/decoder engine. */
private ISignatureCodec codec;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Trivial protected constructor.<p>
*
* @param sigName the canonical name of the signature scheme.
* @param codec the signature codec engine to use with this scheme.
*/
protected SignatureAdapter(String sigName, ISignatureCodec codec)
{
this(SignatureFactory.getInstance(sigName), codec);
}
/**
* Private constructor for cloning purposes.<p>
*
* @param adaptee a clone of the underlying signature scheme instance.
* @param codec the signature codec engine to use with this scheme.
*/
private SignatureAdapter(ISignature adaptee, ISignatureCodec codec)
{
super();
this.adaptee = adaptee;
this.codec = codec;
}
// Class methods
// -------------------------------------------------------------------------
// java.security.SignatureSpi interface implementation
// -------------------------------------------------------------------------
public Object clone()
{
return new SignatureAdapter((ISignature) adaptee.clone(), codec);
}
public void engineInitVerify(PublicKey publicKey) throws InvalidKeyException
{
HashMap attributes = new HashMap();
attributes.put(BaseSignature.VERIFIER_KEY, publicKey);
try
{
adaptee.setupVerify(attributes);
}
catch (IllegalArgumentException x)
{
throw new InvalidKeyException(String.valueOf(x));
}
}
public void engineInitSign(PrivateKey privateKey) throws InvalidKeyException
{
HashMap attributes = new HashMap();
attributes.put(BaseSignature.SIGNER_KEY, privateKey);
try
{
adaptee.setupSign(attributes);
}
catch (IllegalArgumentException x)
{
throw new InvalidKeyException(String.valueOf(x));
}
}
public void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException
{
HashMap attributes = new HashMap();
attributes.put(BaseSignature.SIGNER_KEY, privateKey);
attributes.put(BaseSignature.SOURCE_OF_RANDOMNESS, random);
try
{
adaptee.setupSign(attributes);
}
catch (IllegalArgumentException x)
{
throw new InvalidKeyException(String.valueOf(x));
}
}
public void engineUpdate(byte b) throws SignatureException
{
try
{
adaptee.update(b);
}
catch (IllegalStateException x)
{
throw new SignatureException(String.valueOf(x));
}
}
public void engineUpdate(byte[] b, int off, int len)
throws SignatureException
{
try
{
adaptee.update(b, off, len);
}
catch (IllegalStateException x)
{
throw new SignatureException(String.valueOf(x));
}
}
public byte[] engineSign() throws SignatureException
{
Object signature = null;
try
{
signature = adaptee.sign();
}
catch (IllegalStateException x)
{
throw new SignatureException(String.valueOf(x));
}
byte[] result = codec.encodeSignature(signature);
return result;
}
public int engineSign(byte[] outbuf, int offset, int len)
throws SignatureException
{
byte[] signature = this.engineSign();
int result = signature.length;
if (result > len)
{
throw new SignatureException("len");
}
System.arraycopy(signature, 0, outbuf, offset, result);
return result;
}
public boolean engineVerify(byte[] sigBytes) throws SignatureException
{
log.entering("SignatureAdapter", "engineVerify");
Object signature = codec.decodeSignature(sigBytes);
boolean result = false;
try
{
result = adaptee.verify(signature);
}
catch (IllegalStateException x)
{
throw new SignatureException(String.valueOf(x));
}
log.exiting("SignatureAdapter", "engineVerify", new Boolean(result));
return result;
}
// Deprecated. Replaced by engineSetParameter.
public void engineSetParameter(String param, Object value)
throws InvalidParameterException
{
throw new InvalidParameterException("deprecated");
}
public void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException
{
}
// Deprecated
public Object engineGetParameter(String param)
throws InvalidParameterException
{
throw new InvalidParameterException("deprecated");
}
}
@@ -0,0 +1,132 @@
/* IKeyPairCodec.java --
Copyright 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key;
import gnu.java.security.Registry;
import java.security.PrivateKey;
import java.security.PublicKey;
/**
* <p>The visible methods of an object that knows how to encode and decode
* cryptographic asymmetric keypairs. Codecs are useful for (a) externalising
* public and private keys for storage and on-the-wire transmission, as well as
* (b) re-creating their internal Java representation from external sources.</p>
*
* @version $Revision: 1.2 $
*/
public interface IKeyPairCodec
{
// Constants
// -------------------------------------------------------------------------
/** Constant identifying the <i>Raw</i> encoding format. */
int RAW_FORMAT = Registry.RAW_ENCODING_ID;
/** Constant identifying the <i>X.509</i> encoding format. */
int X509_FORMAT = Registry.X509_ENCODING_ID;
/** Constant identifying the <i>PKCS#8</i> encoding format. */
int PKCS8_FORMAT = Registry.PKCS8_ENCODING_ID;
/**
* Constant identifying the <i>ASN.1</i> encoding format: a combined encoding
* of <i>X.509</i> for public keys, and <i>PKCS#8</i> for private ones.
*/
int ASN1_FORMAT = Registry.ASN1_ENCODING_ID;
// Method(s)
// -------------------------------------------------------------------------
/**
* <p>Returns the unique identifier (within this library) of the format used
* to externalise public and private keys.</p>
*
* @return the identifier of the format, the object supports.
*/
int getFormatID();
/**
* <p>Encodes an instance of a public key for storage or transmission purposes.</p>
*
* @param key the non-null key to encode.
* @return a byte sequence representing the encoding of the designated key
* according to the format supported by this codec.
* @exception IllegalArgumentException if the designated key is not supported
* by this codec.
*/
byte[] encodePublicKey(PublicKey key);
/**
* <p>Encodes an instance of a private key for storage or transmission purposes.</p>
*
* @param key the non-null key to encode.
* @return a byte sequence representing the encoding of the designated key
* according to the format supported by this codec.
* @exception IllegalArgumentException if the designated key is not supported
* by this codec.
*/
byte[] encodePrivateKey(PrivateKey key);
/**
* <p>Decodes an instance of an external public key into its native Java
* representation.</p>
*
* @param input the source of the externalised key to decode.
* @return a concrete instance of a public key, reconstructed from the
* designated input.
* @exception IllegalArgumentException if the designated input does not
* contain a known representation of a public key for the format supported by
* the concrete codec.
*/
PublicKey decodePublicKey(byte[] input);
/**
* <p>Decodes an instance of an external private key into its native Java
* representation.</p>
*
* @param input the source of the externalised key to decode.
* @return a concrete instance of a private key, reconstructed from the
* designated input.
* @exception IllegalArgumentException if the designated input does not
* contain a known representation of a private key for the format supported
* by the concrete codec.
*/
PrivateKey decodePrivateKey(byte[] input);
}
@@ -0,0 +1,82 @@
/* IKeyPairGenerator.java --
Copyright 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key;
import java.security.KeyPair;
import java.util.Map;
/**
* The visible methods of every asymmetric keypair generator.<p>
*
* @version $Revision: 1.1 $
*/
public interface IKeyPairGenerator
{
// Constants
// -------------------------------------------------------------------------
// Methods
// -------------------------------------------------------------------------
/**
* Returns the canonical name of this keypair generator.<p>
*
* @return the canonical name of this instance.
*/
String name();
/**
* [Re]-initialises this instance for use with a given set of attributes.<p>
*
* @param attributes a map of name/value pairs to use for setting up the
* instance.
* @exception IllegalArgumentException if at least one of the mandatory
* attributes is missing or an invalid value was specified.
*/
void setup(Map attributes);
/**
* Generates a new keypair based on the attributes used to configure the
* instance.
*
* @return a new keypair.
*/
KeyPair generate();
}
@@ -0,0 +1,362 @@
/* KeyPairCodecFactory.java --
Copyright 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key;
import gnu.java.security.Registry;
import gnu.java.security.key.dss.DSSKeyPairPKCS8Codec;
import gnu.java.security.key.dss.DSSKeyPairRawCodec;
import gnu.java.security.key.dss.DSSKeyPairX509Codec;
import gnu.java.security.key.dss.DSSPrivateKey;
import gnu.java.security.key.dss.DSSPublicKey;
import gnu.java.security.key.rsa.GnuRSAPrivateKey;
import gnu.java.security.key.rsa.GnuRSAPublicKey;
import gnu.java.security.key.rsa.RSAKeyPairPKCS8Codec;
import gnu.java.security.key.rsa.RSAKeyPairRawCodec;
import gnu.java.security.key.rsa.RSAKeyPairX509Codec;
import gnu.java.security.util.FormatUtil;
import java.lang.reflect.Constructor;
import java.security.Key;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* A <i>Factory</i> class to instantiate key encoder/decoder instances.
*/
public class KeyPairCodecFactory
{
private static Set names;
/** Trivial constructor to enforce Singleton pattern. */
private KeyPairCodecFactory()
{
super();
}
/**
* Returns the appropriate codec given a composed key-pair generator algorithm
* and an encoding format. A composed name is formed by the concatenation of
* the canonical key-pair algorithm name, the forward slash character
* <code>/</code> and the canonical name of the encoding format.
* <p>
* <b>IMPORTANT</b>: For backward compatibility, when the encoding format
* name is missing, the Raw encoding format is assumed. When this is the case
* the trailing forward slash is discarded from the name.
*
* @param name the case-insensitive key codec name.
* @return an instance of the keypair codec, or <code>null</code> if none
* found.
*/
public static IKeyPairCodec getInstance(String name)
{
if (name == null)
return null;
name = name.trim();
if (name.length() == 0)
return null;
if (name.startsWith("/"))
return null;
if (name.endsWith("/"))
return getInstance(name.substring(0, name.length() - 1),
Registry.RAW_ENCODING_ID);
int i = name.indexOf("/");
if (i == -1)
return getInstance(name, Registry.RAW_ENCODING_ID);
String kpgName = name.substring(0, i);
String formatName = name.substring(i + 1);
return getInstance(kpgName, formatName);
}
/**
* Returns an instance of a keypair codec given the canonical name of the
* key-pair algorithm, and the name of the encoding format to use when
* externalizing the keys.
*
* @param name the case-insensitive key-pair algorithm name.
* @param format the name of the encoding format to use when externalizing the
* keys generated by the key-pair algorithm.
* @return an instance of the key-pair codec, or <code>null</code> if none
* found.
*/
public static IKeyPairCodec getInstance(String name, String format)
{
int formatID = FormatUtil.getFormatID(format);
if (formatID == 0)
return null;
return getInstance(name, formatID);
}
/**
* Returns an instance of a keypair codec given the canonical name of the
* key-pair algorithm, and the identifier of the format to use when
* externalizing the keys.
*
* @param name the case-insensitive key-pair algorithm name.
* @param formatID the identifier of the format to use when externalizing the
* keys generated by the key-pair algorithm.
* @return an instance of the key-pair codec, or <code>null</code> if none
* found.
*/
public static IKeyPairCodec getInstance(String name, int formatID)
{
if (name == null)
return null;
name = name.trim();
switch (formatID)
{
case Registry.RAW_ENCODING_ID:
return getRawCodec(name);
case Registry.X509_ENCODING_ID:
return getX509Codec(name);
case Registry.PKCS8_ENCODING_ID:
return getPKCS8Codec(name);
}
return null;
}
/**
* Returns an instance of a keypair codec given a key.
*
* @param key the key to encode.
* @return an instance of the keypair codec, or <code>null</code> if none
* found.
*/
public static IKeyPairCodec getInstance(Key key)
{
if (key == null)
return null;
String format = key.getFormat();
int formatID = FormatUtil.getFormatID(format);
if (formatID == 0)
return null;
switch (formatID)
{
case Registry.RAW_ENCODING_ID:
return getRawCodec(key);
case Registry.X509_ENCODING_ID:
return getX509Codec(key);
case Registry.PKCS8_ENCODING_ID:
return getPKCS8Codec(key);
}
return null;
}
/**
* Returns a {@link Set} of supported key-pair codec names.
*
* @return a {@link Set} of the names of supported key-pair codec (Strings).
*/
public static synchronized final Set getNames()
{
if (names == null)
{
HashSet hs = new HashSet();
hs.add(Registry.DSS_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
hs.add(Registry.DSS_KPG + "/" + Registry.X509_ENCODING_SORT_NAME);
hs.add(Registry.DSS_KPG + "/" + Registry.PKCS8_ENCODING_SHORT_NAME);
hs.add(Registry.RSA_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
hs.add(Registry.RSA_KPG + "/" + Registry.X509_ENCODING_SORT_NAME);
hs.add(Registry.RSA_KPG + "/" + Registry.PKCS8_ENCODING_SHORT_NAME);
hs.add(Registry.DH_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
hs.add(Registry.SRP_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME);
names = Collections.unmodifiableSet(hs);
}
return names;
}
private static IKeyPairCodec makeInstance (String clazz)
{
try
{
Class c = Class.forName (clazz);
Constructor ctor = c.getConstructor (new Class[0]);
return (IKeyPairCodec) ctor.newInstance (new Object[0]);
}
catch (Exception x)
{
IllegalArgumentException iae =
new IllegalArgumentException ("strong crypto key codec not available: "
+ clazz);
iae.initCause (x);
throw iae;
}
}
private static boolean matches (Object o, String clazz)
{
try
{
Class c = Class.forName (clazz);
return c.isAssignableFrom (o.getClass ());
}
catch (Exception x)
{
// Can't match.
return false;
}
}
/**
* @param name the trimmed name of a key-pair algorithm.
* @return a Raw format codec for the designated key-pair algorithm, or
* <code>null</code> if none exists.
*/
private static IKeyPairCodec getRawCodec(String name)
{
IKeyPairCodec result = null;
if (name.equalsIgnoreCase(Registry.DSA_KPG)
|| name.equals(Registry.DSS_KPG))
result = new DSSKeyPairRawCodec();
else if (name.equalsIgnoreCase(Registry.RSA_KPG))
result = new RSAKeyPairRawCodec();
else if (name.equalsIgnoreCase(Registry.DH_KPG))
result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairRawCodec");
else if (name.equalsIgnoreCase(Registry.SRP_KPG))
result = makeInstance("gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec");
return result;
}
/**
* @param name the trimmed name of a key-pair algorithm.
* @return a X.509 format codec for the designated key-pair algorithm, or
* <code>null</code> if none exists.
*/
private static IKeyPairCodec getX509Codec(String name)
{
IKeyPairCodec result = null;
if (name.equalsIgnoreCase(Registry.DSA_KPG)
|| name.equals(Registry.DSS_KPG))
result = new DSSKeyPairX509Codec();
else if (name.equalsIgnoreCase(Registry.RSA_KPG))
result = new RSAKeyPairX509Codec();
else if (name.equalsIgnoreCase(Registry.DH_KPG))
result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairX509Codec");
return result;
}
/**
* @param name the trimmed name of a key-pair algorithm.
* @return a PKCS#8 format codec for the designated key-pair algorithm, or
* <code>null</code> if none exists.
*/
private static IKeyPairCodec getPKCS8Codec(String name)
{
IKeyPairCodec result = null;
if (name.equalsIgnoreCase(Registry.DSA_KPG)
|| name.equals(Registry.DSS_KPG))
result = new DSSKeyPairPKCS8Codec();
else if (name.equalsIgnoreCase(Registry.RSA_KPG))
result = new RSAKeyPairPKCS8Codec();
else if (name.equalsIgnoreCase(Registry.DH_KPG))
result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairPKCS8Codec");
return result;
}
/**
* @param key a {@link Key} for which we want to return a Raw codec.
* @return the Raw codec corresponding to the key, or <code>null</code> if
* none exists for this key.
*/
private static IKeyPairCodec getRawCodec(Key key)
{
IKeyPairCodec result = null;
if ((key instanceof DSSPublicKey) || (key instanceof DSSPrivateKey))
result = new DSSKeyPairRawCodec();
else if ((key instanceof GnuRSAPublicKey)
|| (key instanceof GnuRSAPrivateKey))
result = new RSAKeyPairRawCodec();
else if (matches(key, "gnu.javax.crypto.key.dh.GnuDHPublicKey")
|| matches(key, "gnu.javax.crypto.key.dh.GnuDHPrivateKey"))
result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairRawCodec");
else if (matches(key, "gnu.javax.crypto.key.srp6.SRPPublicKey")
|| matches(key, "gnu.javax.crypto.key.srp6.SRPPrivateKey"))
result = makeInstance("gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec");
return result;
}
/**
* @param key a {@link Key} for which we want to return an X.509 codec.
* @return the X.509 codec corresponding to the key, or <code>null</code> if
* none exists for this key.
*/
private static IKeyPairCodec getX509Codec(Key key)
{
IKeyPairCodec result = null;
if (key instanceof DSSPublicKey)
result = new DSSKeyPairX509Codec();
else if (key instanceof GnuRSAPublicKey)
result = new RSAKeyPairX509Codec();
return result;
}
/**
* @param key a {@link Key} for which we want to return a PKCS#8 codec.
* @return the PKCS#8 codec corresponding to the key, or <code>null</code> if
* none exists for this key.
*/
private static IKeyPairCodec getPKCS8Codec(Key key)
{
IKeyPairCodec result = null;
if (key instanceof DSSPrivateKey)
result = new DSSKeyPairPKCS8Codec();
else if (key instanceof GnuRSAPrivateKey)
result = new RSAKeyPairPKCS8Codec();
return result;
}
}
@@ -0,0 +1,148 @@
/* KeyPairGeneratorFactory.java --
Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key;
import gnu.java.security.Registry;
import gnu.java.security.key.dss.DSSKeyPairGenerator;
import gnu.java.security.key.rsa.RSAKeyPairGenerator;
import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* <p>A Factory to instantiate asymmetric keypair generators.</p>
*
* @version $Revision: 1.1 $
*/
public class KeyPairGeneratorFactory
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial constructor to enforce Singleton pattern. */
private KeyPairGeneratorFactory()
{
super();
}
// Class methods
// -------------------------------------------------------------------------
/**
* <p>Returns an instance of a keypair generator given its name.</p>
*
* @param name the case-insensitive key generator name.
* @return an instance of the keypair generator, or <code>null</code> if none
* found.
*/
public static IKeyPairGenerator getInstance(String name)
{
if (name == null)
{
return null;
}
name = name.trim();
IKeyPairGenerator result = null;
if (name.equalsIgnoreCase(Registry.DSA_KPG)
|| name.equals(Registry.DSS_KPG))
{
result = new DSSKeyPairGenerator();
}
else if (name.equalsIgnoreCase(Registry.RSA_KPG))
{
result = new RSAKeyPairGenerator();
}
else if (name.equalsIgnoreCase(Registry.DH_KPG))
{
result = makeInstance ("gnu.javax.crypto.key.dh.GnuDHKeyPairGenerator");
}
else if (name.equalsIgnoreCase(Registry.SRP_KPG))
{
result = makeInstance ("gnu.javax.crypto.key.srp6.SRPKeyPairGenerator");
}
return result;
}
/**
* <p>Returns a {@link Set} of keypair generator names supported by this
* <i>Factory</i>. Those keypair generators may be used in conjunction with
* the digital signature schemes with appendix supported by this library.</p>
*
* @return a {@link Set} of keypair generator names (Strings).
*/
public static final Set getNames()
{
HashSet hs = new HashSet();
hs.add(Registry.DSS_KPG);
hs.add(Registry.RSA_KPG);
hs.add(Registry.DH_KPG);
hs.add(Registry.SRP_KPG);
return Collections.unmodifiableSet(hs);
}
private static IKeyPairGenerator makeInstance (String clazz)
{
try
{
Class c = Class.forName (clazz);
Constructor ctor = c.getConstructor (new Class[0]);
return (IKeyPairGenerator) ctor.newInstance (new Object[0]);
}
catch (Exception x)
{
IllegalArgumentException iae =
new IllegalArgumentException ("strong crypto key pair generator not available: "
+ clazz);
iae.initCause (x);
throw iae;
}
}
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,182 @@
/* DSSKey.java --
Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.java.security.Registry;
import gnu.java.security.util.FormatUtil;
import java.math.BigInteger;
import java.security.Key;
import java.security.interfaces.DSAKey;
import java.security.interfaces.DSAParams;
import java.security.spec.DSAParameterSpec;
/**
* <p>A base asbtract class for both public and private DSS (Digital Signature
* Standard) keys. It encapsulates the three DSS numbers: <code>p</code>,
* <code>q</code> and <code>g</code>.</p>
*
* <p>According to the JDK, cryptographic <i>Keys</i> all have a <i>format</i>.
* The format used in this implementation is called <i>Raw</i>, and basically
* consists of the raw byte sequences of algorithm parameters. The exact order
* of the byte sequences and the implementation details are given in each of
* the relevant <code>getEncoded()</code> methods of each of the private and
* public keys.</p>
*
* @version $Revision: 1.4 $
* @see DSSPrivateKey#getEncoded
* @see DSSPublicKey#getEncoded
*/
public abstract class DSSKey implements Key, DSAKey
{
// Constants and variables
// -------------------------------------------------------------------------
/**
* A prime modulus, where <code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup></code>
* for <code>512 &lt;= L &lt;= 1024</code> and <code>L</code> a multiple of
* <code>64</code>.
*/
protected final BigInteger p;
/**
* A prime divisor of <code>p - 1</code>, where <code>2<sup>159</sup> &lt; q
* &lt; 2<sup>160</sup></code>.
*/
protected final BigInteger q;
/**
* <code>g = h<sup>(p-1)</sup>/q mod p</code>, where <code>h</code> is any
* integer with <code>1 &lt; h &lt; p - 1</code> such that <code>h<sup>
* (p-1)</sup>/q mod p > 1</code> (<code>g</code> has order <code>q mod p
* </code>).
*/
protected final BigInteger g;
/**
* Identifier of the default encoding format to use when externalizing the
* key material.
*/
protected final int defaultFormat;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Trivial protected constructor.
*
* @param defaultFormat the identifier of the encoding format to use by
* default when externalizing the key.
* @param p the DSS parameter <code>p</code>.
* @param q the DSS parameter <code>q</code>.
* @param g the DSS parameter <code>g</code>.
*/
protected DSSKey(int defaultFormat, BigInteger p, BigInteger q, BigInteger g)
{
super();
this.defaultFormat = defaultFormat <= 0 ? Registry.RAW_ENCODING_ID
: defaultFormat;
this.p = p;
this.q = q;
this.g = g;
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// java.security.interfaces.DSAKey interface implementation ----------------
public DSAParams getParams()
{
return new DSAParameterSpec(p, q, g);
}
// java.security.Key interface implementation ------------------------------
public String getAlgorithm()
{
return Registry.DSS_KPG;
}
/** @deprecated see getEncoded(int). */
public byte[] getEncoded()
{
return getEncoded(defaultFormat);
}
public String getFormat()
{
return FormatUtil.getEncodingShortName(defaultFormat);
}
// Other instance methods --------------------------------------------------
/**
* <p>Returns <code>true</code> if the designated object is an instance of
* {@link DSAKey} and has the same DSS (Digital Signature Standard) parameter
* values as this one.</p>
*
* @param obj the other non-null DSS key to compare to.
* @return <code>true</code> if the designated object is of the same type and
* value as this one.
*/
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (!(obj instanceof DSAKey))
{
return false;
}
DSAKey that = (DSAKey) obj;
return p.equals(that.getParams().getP())
&& q.equals(that.getParams().getQ())
&& g.equals(that.getParams().getG());
}
// abstract methods to be implemented by subclasses ------------------------
public abstract byte[] getEncoded(int format);
}
@@ -0,0 +1,445 @@
/* DSSKeyPairGenerator.java --
Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.java.security.Registry;
import gnu.java.security.hash.Sha160;
import gnu.java.security.key.IKeyPairGenerator;
import gnu.java.security.util.PRNG;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.DSAParameterSpec;
import java.util.Map;
/**
* <p>A key-pair generator for asymetric keys to use in conjunction with the DSS
* (Digital Signature Standard).</p>
*
* References:<br>
* <a href="http://www.itl.nist.gov/fipspubs/fip186.htm">Digital Signature
* Standard (DSS)</a>, Federal Information Processing Standards Publication 186.
* National Institute of Standards and Technology.
*/
public class DSSKeyPairGenerator implements IKeyPairGenerator
{
// Debugging methods and variables
// -------------------------------------------------------------------------
private static final String NAME = "dss";
private static final boolean DEBUG = false;
private static final int debuglevel = 5;
private static final PrintWriter err = new PrintWriter(System.out, true);
private static void debug(String s)
{
err.println(">>> " + NAME + ": " + s);
}
// Constants and variables
// -------------------------------------------------------------------------
/** The BigInteger constant 2. */
private static final BigInteger TWO = new BigInteger("2");
/** Property name of the length (Integer) of the modulus (p) of a DSS key. */
public static final String MODULUS_LENGTH = "gnu.crypto.dss.L";
/**
* Property name of the Boolean indicating wether or not to use default pre-
* computed values of <code>p</code>, <code>q</code> and <code>g</code> for
* a given modulus length. The ultimate behaviour of this generator with
* regard to using pre-computed parameter sets will depend on the value of
* this property and of the following one {@link #STRICT_DEFAULTS}:
*
* <ol>
* <li>If this property is {@link Boolean#FALSE} then this generator
* will accept being setup for generating parameters for any modulus length
* provided the modulus length is between <code>512</code> and
* <code>1024</code>, and is of the form <code>512 + 64 * n</code>. In
* addition, a new paramter set will always be generated; i.e. no pre-
* computed values are used.</li>
*
* <li>If this property is {@link Boolean#TRUE} and the value of
* {@link #STRICT_DEFAULTS} is also {@link Boolean#TRUE} then this generator
* will only accept being setup for generating parameters for modulus
* lengths of <code>512</code>, <code>768</code> and <code>1024</code>. Any
* other value, of the modulus length, even if between <code>512</code> and
* <code>1024</code>, and of the form <code>512 + 64 * n</code>, will cause
* an {@link IllegalArgumentException} to be thrown. When those modulus
* length (<code>512</code>, <code>768</code>, and <code>1024</code>) are
* specified, the paramter set is always the same.</li>
*
* <li>Finally, if this property is {@link Boolean#TRUE} and the value of
* {@link #STRICT_DEFAULTS} is {@link Boolean#FALSE} then this generator
* will behave as in point 1 above, except that it will use pre-computed
* values when possible; i.e. the modulus length is one of <code>512</code>,
* <code>768</code>, or <code>1024</code>.</li>
* </ol>
*
* The default value of this property is {@link Boolean#TRUE}.
*/
public static final String USE_DEFAULTS = "gnu.crypto.dss.use.defaults";
/**
* Property name of the Boolean indicating wether or not to generate new
* parameters, even if the modulus length <i>L</i> is not one of the pre-
* computed defaults (value {@link Boolean#FALSE}), or throw an exception
* (value {@link Boolean#TRUE}) -- the exception in this case is an
* {@link IllegalArgumentException}. The default value for this property is
* {@link Boolean#FALSE}. The ultimate behaviour of this generator will
* depend on the values of this and {@link #USE_DEFAULTS} properties -- see
* {@link #USE_DEFAULTS} for more information.
*/
public static final String STRICT_DEFAULTS = "gnu.crypto.dss.strict.defaults";
/**
* Property name of an optional {@link SecureRandom} instance to use. The
* default is to use a classloader singleton from {@link PRNG}.
*/
public static final String SOURCE_OF_RANDOMNESS = "gnu.crypto.dss.prng";
/**
* Property name of an optional {@link DSAParameterSpec} instance to use for
* this generator's <code>p</code>, <code>q</code>, and <code>g</code> values.
* The default is to generate these values or use pre-computed ones,
* depending on the value of the <code>USE_DEFAULTS</code> attribute.
*/
public static final String DSS_PARAMETERS = "gnu.crypto.dss.params";
/**
* Property name of the preferred encoding format to use when externalizing
* generated instance of key-pairs from this generator. The property is taken
* to be an {@link Integer} that encapsulates an encoding format identifier.
*/
public static final String PREFERRED_ENCODING_FORMAT = "gnu.crypto.dss.encoding";
/** Default value for the modulus length. */
public static final int DEFAULT_MODULUS_LENGTH = 1024;
/** Default encoding format to use when none was specified. */
private static final int DEFAULT_ENCODING_FORMAT = Registry.RAW_ENCODING_ID;
/** Initial SHS context. */
private static final int[] T_SHS = new int[] { 0x67452301, 0xEFCDAB89,
0x98BADCFE, 0x10325476,
0xC3D2E1F0 };
// from jdk1.3.1/docs/guide/security/CryptoSpec.html#AppB
public static final DSAParameterSpec KEY_PARAMS_512 = new DSAParameterSpec(
new BigInteger(
"fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae"
+ "01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17",
16),
new BigInteger(
"962eddcc369cba8ebb260ee6b6a126d9346e38c5",
16),
new BigInteger(
"678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e"
+ "35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4",
16));
public static final DSAParameterSpec KEY_PARAMS_768 = new DSAParameterSpec(
new BigInteger(
"e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5d8901419"
+ "22d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a22219d470bce7d77"
+ "7d4a21fbe9c270b57f607002f3cef8393694cf45ee3688c11a8c56ab127a3daf",
16),
new BigInteger(
"9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511",
16),
new BigInteger(
"30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7a31d23c4"
+ "dbbcbe06174544401a5b2c020965d8c2bd2171d3668445771f74ba084d2029d8"
+ "3c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a7064f316933a346d3f529252",
16));
public static final DSAParameterSpec KEY_PARAMS_1024 = new DSAParameterSpec(
new BigInteger(
"fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669"
+ "455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b7"
+ "6b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb"
+ "83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7",
16),
new BigInteger(
"9760508f15230bccb292b982a2eb840bf0581cf5",
16),
new BigInteger(
"f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d078267"
+ "5159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e1"
+ "3c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243b"
+ "cca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a",
16));
private static final BigInteger TWO_POW_160 = TWO.pow(160);
/** The length of the modulus of DSS keys generated by this instance. */
private int L;
/** The optional {@link SecureRandom} instance to use. */
private SecureRandom rnd = null;
private BigInteger seed;
private BigInteger counter;
private BigInteger p;
private BigInteger q;
private BigInteger e;
private BigInteger g;
private BigInteger XKEY;
/** Our default source of randomness. */
private PRNG prng = null;
/** Preferred encoding format of generated keys. */
private int preferredFormat;
// Constructor(s)
// -------------------------------------------------------------------------
// implicit 0-arguments constructor
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// gnu.crypto.key.IKeyPairGenerator interface implementation ---------------
public String name()
{
return Registry.DSS_KPG;
}
/**
* <p>Configures this instance.</p>
*
* @param attributes the map of name/value pairs to use.
* @exception IllegalArgumentException if the designated MODULUS_LENGTH
* value is not greater than 512, less than 1024 and not of the form
* <code>512 + 64j</code>.
*/
public void setup(Map attributes)
{
// find out the modulus length
Integer l = (Integer) attributes.get(MODULUS_LENGTH);
L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue());
if ((L % 64) != 0 || L < 512 || L > 1024)
throw new IllegalArgumentException(MODULUS_LENGTH);
// should we use the default pre-computed params?
Boolean useDefaults = (Boolean) attributes.get(USE_DEFAULTS);
if (useDefaults == null)
{
useDefaults = Boolean.TRUE;
}
Boolean strictDefaults = (Boolean) attributes.get(STRICT_DEFAULTS);
if (strictDefaults == null)
strictDefaults = Boolean.FALSE;
// are we given a set of DSA params or we shall use/generate our own?
DSAParameterSpec params = (DSAParameterSpec) attributes.get(DSS_PARAMETERS);
if (params != null)
{
p = params.getP();
q = params.getQ();
g = params.getG();
}
else if (useDefaults.equals(Boolean.TRUE))
{
switch (L)
{
case 512:
p = KEY_PARAMS_512.getP();
q = KEY_PARAMS_512.getQ();
g = KEY_PARAMS_512.getG();
break;
case 768:
p = KEY_PARAMS_768.getP();
q = KEY_PARAMS_768.getQ();
g = KEY_PARAMS_768.getG();
break;
case 1024:
p = KEY_PARAMS_1024.getP();
q = KEY_PARAMS_1024.getQ();
g = KEY_PARAMS_1024.getG();
break;
default:
if (strictDefaults.equals(Boolean.TRUE))
throw new IllegalArgumentException(
"Does not provide default parameters for " + L
+ "-bit modulus length");
else
{
p = null;
q = null;
g = null;
}
}
}
else
{
p = null;
q = null;
g = null;
}
// do we have a SecureRandom, or should we use our own?
rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS);
// what is the preferred encoding format
Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT);
preferredFormat = formatID == null
? DEFAULT_ENCODING_FORMAT
: formatID.intValue();
// set the seed-key
byte[] kb = new byte[20]; // we need 160 bits of randomness
nextRandomBytes(kb);
XKEY = new BigInteger(1, kb).setBit(159).setBit(0);
}
public KeyPair generate()
{
if (p == null)
{
BigInteger[] params = new FIPS186(L, rnd).generateParameters();
seed = params[FIPS186.DSA_PARAMS_SEED];
counter = params[FIPS186.DSA_PARAMS_COUNTER];
q = params[FIPS186.DSA_PARAMS_Q];
p = params[FIPS186.DSA_PARAMS_P];
e = params[FIPS186.DSA_PARAMS_E];
g = params[FIPS186.DSA_PARAMS_G];
if (DEBUG && debuglevel > 0)
{
debug("seed: " + seed.toString(16));
debug("counter: " + counter.intValue());
debug("q: " + q.toString(16));
debug("p: " + p.toString(16));
debug("e: " + e.toString(16));
debug("g: " + g.toString(16));
}
}
BigInteger x = nextX();
BigInteger y = g.modPow(x, p);
PublicKey pubK = new DSSPublicKey(preferredFormat, p, q, g, y);
PrivateKey secK = new DSSPrivateKey(preferredFormat, p, q, g, x);
return new KeyPair(pubK, secK);
}
// Other instance methods --------------------------------------------------
/**
* <p>This method applies the following algorithm described in 3.1 of
* FIPS-186:</p>
*
* <ol>
* <li>XSEED = optional user input.</li>
* <li>XVAL = (XKEY + XSEED) mod 2<sup>b</sup>.</li>
* <li>x = G(t, XVAL) mod q.</li>
* <li>XKEY = (1 + XKEY + x) mod 2<sup>b</sup>.</li>
* </ol>
*
* <p>Where <code>b</code> is the length of a secret b-bit seed-key (XKEY).</p>
*
* <p>Note that in this implementation, XSEED, the optional user input, is
* always zero.</p>
*/
private synchronized BigInteger nextX()
{
byte[] xk = XKEY.toByteArray();
byte[] in = new byte[64]; // 512-bit block for SHS
System.arraycopy(xk, 0, in, 0, xk.length);
int[] H = Sha160.G(T_SHS[0], T_SHS[1], T_SHS[2], T_SHS[3], T_SHS[4], in, 0);
byte[] h = new byte[20];
for (int i = 0, j = 0; i < 5; i++)
{
h[j++] = (byte) (H[i] >>> 24);
h[j++] = (byte) (H[i] >>> 16);
h[j++] = (byte) (H[i] >>> 8);
h[j++] = (byte) H[i];
}
BigInteger result = new BigInteger(1, h).mod(q);
XKEY = XKEY.add(result).add(BigInteger.ONE).mod(TWO_POW_160);
return result;
}
/**
* <p>Fills the designated byte array with random data.</p>
*
* @param buffer the byte array to fill with random data.
*/
private void nextRandomBytes(byte[] buffer)
{
if (rnd != null)
{
rnd.nextBytes(buffer);
}
else
getDefaultPRNG().nextBytes(buffer);
}
private PRNG getDefaultPRNG()
{
if (prng == null)
prng = PRNG.getInstance();
return prng;
}
}
@@ -0,0 +1,235 @@
/* DSSKeyPairPKCS8Codec.java -- PKCS#8 Encoding/Decoding handler
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.java.security.OID;
import gnu.java.security.Registry;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import gnu.java.security.key.IKeyPairCodec;
import gnu.java.security.util.DerUtil;
import gnu.java.security.util.Util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidParameterException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.ArrayList;
/**
* An implementation of an {@link IKeyPairCodec} that knows how to encode /
* decode PKCS#8 ASN.1 external representation of DSS private keys.
*
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class DSSKeyPairPKCS8Codec
implements IKeyPairCodec
{
private static final OID DSA_ALG_OID = new OID(Registry.DSA_OID_STRING);
// implicit 0-arguments constructor
public int getFormatID()
{
return PKCS8_FORMAT;
}
/**
* @throws InvalidParameterException ALWAYS.
*/
public byte[] encodePublicKey(PublicKey key)
{
throw new InvalidParameterException("Wrong format for public keys");
}
/**
* Returns the PKCS#8 ASN.1 <i>PrivateKeyInfo</i> representation of a DSA
* private key. The ASN.1 specification is as follows:
*
* <pre>
* PrivateKeyInfo ::= SEQUENCE {
* version INTEGER, -- MUST be 0
* privateKeyAlgorithm AlgorithmIdentifier,
* privateKey OCTET STRING
* }
*
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL
* }
*
* DssParams ::= SEQUENCE {
* p INTEGER,
* q INTEGER,
* g INTEGER
* }
* </pre>
*
* @return the DER encoded form of the ASN.1 representation of the
* <i>PrivateKeyInfo</i> field in an X.509 certificate.
* @throw InvalidParameterException if an error occurs during the marshalling
* process.
*/
public byte[] encodePrivateKey(PrivateKey key)
{
if (! (key instanceof DSSPrivateKey))
throw new InvalidParameterException("Wrong key type");
DERValue derVersion = new DERValue(DER.INTEGER, BigInteger.ZERO);
DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, DSA_ALG_OID);
DSSPrivateKey pk = (DSSPrivateKey) key;
BigInteger p = pk.getParams().getP();
BigInteger q = pk.getParams().getQ();
BigInteger g = pk.getParams().getG();
BigInteger x = pk.getX();
ArrayList params = new ArrayList(3);
params.add(new DERValue(DER.INTEGER, p));
params.add(new DERValue(DER.INTEGER, q));
params.add(new DERValue(DER.INTEGER, g));
DERValue derParams = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, params);
ArrayList algorithmID = new ArrayList(2);
algorithmID.add(derOID);
algorithmID.add(derParams);
DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
algorithmID);
DERValue derPrivateKey = new DERValue(DER.OCTET_STRING, Util.trim(x));
ArrayList pki = new ArrayList(3);
pki.add(derVersion);
pki.add(derAlgorithmID);
pki.add(derPrivateKey);
DERValue derPKI = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, pki);
byte[] result;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try
{
DERWriter.write(baos, derPKI);
result = baos.toByteArray();
}
catch (IOException e)
{
InvalidParameterException y = new InvalidParameterException();
y.initCause(e);
throw y;
}
return result;
}
/**
* @throws InvalidParameterException ALWAYS.
*/
public PublicKey decodePublicKey(byte[] input)
{
throw new InvalidParameterException("Wrong format for public keys");
}
/**
* @param input the byte array to unmarshall into a valid DSS
* {@link PrivateKey} instance. MUST NOT be null.
* @return a new instance of a {@link DSSPrivateKey} decoded from the
* <i>PrivateKeyInfo</i> material fed as <code>input</code>.
* @throw InvalidParameterException if an exception occurs during the
* unmarshalling process.
*/
public PrivateKey decodePrivateKey(byte[] input)
{
if (input == null)
throw new InvalidParameterException("Input bytes MUST NOT be null");
BigInteger version, p, q, g, x;
DERReader der = new DERReader(input);
try
{
DERValue derPKI = der.read();
DerUtil.checkIsConstructed(derPKI, "Wrong PrivateKeyInfo field");
DERValue derVersion = der.read();
if (! (derVersion.getValue() instanceof BigInteger))
throw new InvalidParameterException("Wrong Version field");
version = (BigInteger) derVersion.getValue();
if (version.compareTo(BigInteger.ZERO) != 0)
throw new InvalidParameterException("Unexpected Version: " + version);
DERValue derAlgoritmID = der.read();
DerUtil.checkIsConstructed(derAlgoritmID, "Wrong AlgorithmIdentifier field");
DERValue derOID = der.read();
OID algOID = (OID) derOID.getValue();
if (! algOID.equals(DSA_ALG_OID))
throw new InvalidParameterException("Unexpected OID: " + algOID);
DERValue derParams = der.read();
DerUtil.checkIsConstructed(derParams, "Wrong DSS Parameters field");
DERValue val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong P field");
p = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong Q field");
q = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong G field");
g = (BigInteger) val.getValue();
val = der.read();
byte[] xBytes = (byte[]) val.getValue();
x = new BigInteger(1, xBytes);
}
catch (IOException e)
{
InvalidParameterException y = new InvalidParameterException();
y.initCause(e);
throw y;
}
return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x);
}
}
@@ -0,0 +1,383 @@
/* DSSKeyPairRawCodec.java --
Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.java.security.Registry;
import gnu.java.security.key.IKeyPairCodec;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.security.PrivateKey;
import java.security.PublicKey;
/**
* <p>An object that implements the {@link IKeyPairCodec} operations for the
* <i>Raw</i> format to use with DSS keypairs.</p>
*
* @version $Revision: 1.1 $
*/
public class DSSKeyPairRawCodec implements IKeyPairCodec
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
// implicit 0-arguments constructor
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// gnu.crypto.keys.IKeyPairCodec interface implementation ------------------
public int getFormatID()
{
return RAW_FORMAT;
}
/**
* <p>Returns the encoded form of the designated DSS (Digital Signature
* Standard) public key according to the <i>Raw</i> format supported by
* this library.</p>
*
* <p>The <i>Raw</i> format for a DSA public key, in this implementation, is
* a byte sequence consisting of the following:</p>
* <ol>
* <li>4-byte magic consisting of the value of the literal
* {@link Registry#MAGIC_RAW_DSS_PUBLIC_KEY},<li>
* <li>1-byte version consisting of the constant: 0x01,</li>
* <li>4-byte count of following bytes representing the DSA parameter
* <code>p</code> in internet order,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the DSA parameter
* <code>p</code>,</li>
* <li>4-byte count of following bytes representing the DSA parameter
* <code>q</code>,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the DSA parameter
* <code>q</code>,</li>
* <li>4-byte count of following bytes representing the DSA parameter
* <code>g</code>,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the DSA parameter
* <code>g</code>,</li>
* <li>4-byte count of following bytes representing the DSA parameter
* <code>y</code>,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the DSA parameter
* <code>y</code>,</li>
* </ol>
*
* @param key the key to encode.
* @return the <i>Raw</i> format encoding of the designated key.
* @throws IllegalArgumentException if the designated key is not a DSS
* (Digital Signature Standard) one.
* @see Registry#MAGIC_RAW_DSS_PUBLIC_KEY
*/
public byte[] encodePublicKey(PublicKey key)
{
if (!(key instanceof DSSPublicKey))
{
throw new IllegalArgumentException("key");
}
DSSPublicKey dssKey = (DSSPublicKey) key;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// magic
baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[0]);
baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[1]);
baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[2]);
baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[3]);
// version
baos.write(0x01);
// p
byte[] buffer = dssKey.getParams().getP().toByteArray();
int length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// q
buffer = dssKey.getParams().getQ().toByteArray();
length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// g
buffer = dssKey.getParams().getG().toByteArray();
length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// y
buffer = dssKey.getY().toByteArray();
length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
return baos.toByteArray();
}
public PublicKey decodePublicKey(byte[] k)
{
// magic
if (k[0] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[0]
|| k[1] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[1]
|| k[2] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[2]
|| k[3] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[3])
{
throw new IllegalArgumentException("magic");
}
// version
if (k[4] != 0x01)
{
throw new IllegalArgumentException("version");
}
int i = 5;
int l;
byte[] buffer;
// p
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger p = new BigInteger(1, buffer);
// q
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger q = new BigInteger(1, buffer);
// g
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger g = new BigInteger(1, buffer);
// y
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger y = new BigInteger(1, buffer);
return new DSSPublicKey(p, q, g, y);
}
/**
* <p>Returns the encoded form of the designated DSS (Digital Signature
* Standard) private key according to the <i>Raw</i> format supported by
* this library.</p>
*
* <p>The <i>Raw</i> format for a DSA private key, in this implementation, is
* a byte sequence consisting of the following:</p>
* <ol>
* <li>4-byte magic consisting of the value of the literal
* {@link Registry#MAGIC_RAW_DSS_PRIVATE_KEY},<li>
* <li>1-byte version consisting of the constant: 0x01,</li>
* <li>4-byte count of following bytes representing the DSA parameter
* <code>p</code> in internet order,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the DSA parameter
* <code>p</code>,</li>
* <li>4-byte count of following bytes representing the DSA parameter
* <code>q</code>,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the DSA parameter
* <code>q</code>,</li>
* <li>4-byte count of following bytes representing the DSA parameter
* <code>g</code>,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the DSA parameter
* <code>g</code>,</li>
* <li>4-byte count of following bytes representing the DSA parameter
* <code>x</code>,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the DSA parameter
* <code>x</code>,</li>
* </ol>
*
* @param key the key to encode.
* @return the <i>Raw</i> format encoding of the designated key.
* @throws IllegalArgumentException if the designated key is not a DSS
* (Digital Signature Standard) one.
*/
public byte[] encodePrivateKey(PrivateKey key)
{
if (!(key instanceof DSSPrivateKey))
{
throw new IllegalArgumentException("key");
}
DSSPrivateKey dssKey = (DSSPrivateKey) key;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// magic
baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[0]);
baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[1]);
baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[2]);
baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[3]);
// version
baos.write(0x01);
// p
byte[] buffer = dssKey.getParams().getP().toByteArray();
int length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// q
buffer = dssKey.getParams().getQ().toByteArray();
length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// g
buffer = dssKey.getParams().getG().toByteArray();
length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// x
buffer = dssKey.getX().toByteArray();
length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
return baos.toByteArray();
}
public PrivateKey decodePrivateKey(byte[] k)
{
// magic
if (k[0] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[0]
|| k[1] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[1]
|| k[2] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[2]
|| k[3] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[3])
{
throw new IllegalArgumentException("magic");
}
// version
if (k[4] != 0x01)
{
throw new IllegalArgumentException("version");
}
int i = 5;
int l;
byte[] buffer;
// p
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger p = new BigInteger(1, buffer);
// q
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger q = new BigInteger(1, buffer);
// g
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger g = new BigInteger(1, buffer);
// x
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger x = new BigInteger(1, buffer);
return new DSSPrivateKey(p, q, g, x);
}
}
@@ -0,0 +1,248 @@
/* DSSKeyPairX509Codec.java -- X.509 Encoding/Decoding handler
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.java.security.OID;
import gnu.java.security.Registry;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import gnu.java.security.key.IKeyPairCodec;
import gnu.java.security.util.DerUtil;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidParameterException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.ArrayList;
/**
* An implementation of an {@link IKeyPairCodec} that knows how to encode /
* decode X.509 ASN.1 external representation of DSS public keys.
*/
public class DSSKeyPairX509Codec
implements IKeyPairCodec
{
private static final OID DSA_ALG_OID = new OID(Registry.DSA_OID_STRING);
// implicit 0-arguments constructor
public int getFormatID()
{
return X509_FORMAT;
}
/**
* Returns the X.509 ASN.1 <i>SubjectPublicKeyInfo</i> representation of a
* DSA public key. The ASN.1 specification, as defined in RFC-3280, and
* RFC-2459, is as follows:
*
* <pre>
* SubjectPublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
* subjectPublicKey BIT STRING
* }
*
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL
* }
*
* DssParams ::= SEQUENCE {
* p INTEGER,
* q INTEGER,
* g INTEGER
* }
* </pre>
*
* <p>The <i>subjectPublicKey</i> field, which is a BIT STRING, contains the
* DER-encoded form of the DSA public key as an INTEGER.</p>
*
* <pre>
* DSAPublicKey ::= INTEGER -- public key, Y
* </pre>
*
* @param key the {@link PublicKey} instance to encode. MUST be an instance of
* {@link DSSPublicKey}.
* @return the ASN.1 representation of the <i>SubjectPublicKeyInfo</i> in an
* X.509 certificate.
* @throw InvalidParameterException if <code>key</code> is not an instance
* of {@link DSSPublicKey} or if an exception occurs during the
* marshalling process.
*/
public byte[] encodePublicKey(PublicKey key)
{
if (! (key instanceof DSSPublicKey))
throw new InvalidParameterException("key");
DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, DSA_ALG_OID);
DSSPublicKey dssKey = (DSSPublicKey) key;
BigInteger p = dssKey.getParams().getP();
BigInteger q = dssKey.getParams().getQ();
BigInteger g = dssKey.getParams().getG();
BigInteger y = dssKey.getY();
DERValue derP = new DERValue(DER.INTEGER, p);
DERValue derQ = new DERValue(DER.INTEGER, q);
DERValue derG = new DERValue(DER.INTEGER, g);
ArrayList params = new ArrayList(3);
params.add(derP);
params.add(derQ);
params.add(derG);
DERValue derParams = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, params);
ArrayList algorithmID = new ArrayList(2);
algorithmID.add(derOID);
algorithmID.add(derParams);
DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
algorithmID);
DERValue derDSAPublicKey = new DERValue(DER.INTEGER, y);
byte[] yBytes = derDSAPublicKey.getEncoded();
DERValue derSPK = new DERValue(DER.BIT_STRING, new BitString(yBytes));
ArrayList spki = new ArrayList(2);
spki.add(derAlgorithmID);
spki.add(derSPK);
DERValue derSPKI = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, spki);
byte[] result;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try
{
DERWriter.write(baos, derSPKI);
result = baos.toByteArray();
}
catch (IOException x)
{
InvalidParameterException e = new InvalidParameterException();
e.initCause(x);
throw e;
}
return result;
}
/**
* @throws InvalidParameterException ALWAYS.
*/
public byte[] encodePrivateKey(PrivateKey key)
{
throw new InvalidParameterException("Wrong format for private keys");
}
/**
* @param input the byte array to unmarshall into a valid DSS
* {@link PublicKey} instance. MUST NOT be null.
* @return a new instance of a {@link DSSPublicKey} decoded from the
* <i>SubjectPublicKeyInfo</i> material in an X.509 certificate.
* @throw InvalidParameterException if an exception occurs during the
* unmarshalling process.
*/
public PublicKey decodePublicKey(byte[] input)
{
if (input == null)
throw new InvalidParameterException("Input bytes MUST NOT be null");
BigInteger p, g, q, y;
DERReader der = new DERReader(input);
try
{
DERValue derSPKI = der.read();
DerUtil.checkIsConstructed(derSPKI, "Wrong SubjectPublicKeyInfo field");
DERValue derAlgorithmID = der.read();
DerUtil.checkIsConstructed(derAlgorithmID, "Wrong AlgorithmIdentifier field");
DERValue derOID = der.read();
if (! (derOID.getValue() instanceof OID))
throw new InvalidParameterException("Wrong Algorithm field");
OID algOID = (OID) derOID.getValue();
if (! algOID.equals(DSA_ALG_OID))
throw new InvalidParameterException("Unexpected OID: " + algOID);
DERValue derParams = der.read();
DerUtil.checkIsConstructed(derParams, "Wrong DSS Parameters field");
DERValue val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong P field");
p = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong Q field");
q = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong G field");
g = (BigInteger) val.getValue();
val = der.read();
if (! (val.getValue() instanceof BitString))
throw new InvalidParameterException("Wrong SubjectPublicKey field");
byte[] yBytes = ((BitString) val.getValue()).toByteArray();
DERReader dsaPub = new DERReader(yBytes);
val = dsaPub.read();
DerUtil.checkIsBigInteger(val, "Wrong Y field");
y = (BigInteger) val.getValue();
}
catch (IOException x)
{
InvalidParameterException e = new InvalidParameterException();
e.initCause(x);
throw e;
}
return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y);
}
/**
* @throws InvalidParameterException ALWAYS.
*/
public PrivateKey decodePrivateKey(byte[] input)
{
throw new InvalidParameterException("Wrong format for private keys");
}
}
@@ -0,0 +1,201 @@
/* DSSPrivateKey.java --
Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.java.security.Registry;
import gnu.java.security.key.IKeyPairCodec;
import java.math.BigInteger;
import java.security.PrivateKey;
import java.security.interfaces.DSAPrivateKey;
/**
* <p>An object that embodies a DSS (Digital Signature Standard) private key.</p>
*
* @version $Revision: 1.2 $
* @see #getEncoded
*/
public class DSSPrivateKey extends DSSKey implements PrivateKey, DSAPrivateKey
{
// Constants and variables
// -------------------------------------------------------------------------
/**
* <p>A randomly or pseudorandomly generated integer with <code>0 &lt; x &lt;
* q</code>.</p>
*/
private final BigInteger x;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Convenience constructor. Calls the constructor with 5 arguments passing
* {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
* encoding format.
*
* @param p the public modulus.
* @param q the public prime divisor of <code>p-1</code>.
* @param g a generator of the unique cyclic group <code>Z<sup>*</sup>
* <sub>p</sub></code>.
* @param x the private key part.
*/
public DSSPrivateKey(BigInteger p, BigInteger q, BigInteger g, BigInteger x)
{
this(Registry.RAW_ENCODING_ID, p, q, g, x);
}
/**
* Constructs a new instance of a <code>DSSPrivateKey</code> given the
* designated arguments.
*
* @param preferredFormat the indetifier of the preferred encoding format to
* use when externalizing this key.
* @param p the public modulus.
* @param q the public prime divisor of <code>p-1</code>.
* @param g a generator of the unique cyclic group <code>Z<sup>*</sup>
* <sub>p</sub></code>.
* @param x the private key part.
*/
public DSSPrivateKey(int preferredFormat, BigInteger p, BigInteger q,
BigInteger g, BigInteger x)
{
super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.PKCS8_ENCODING_ID
: preferredFormat,
p, q, g);
this.x = x;
}
// Class methods
// -------------------------------------------------------------------------
/**
* A class method that takes the output of the <code>encodePrivateKey()</code>
* method of a DSS keypair codec object (an instance implementing
* {@link gnu.java.security.key.IKeyPairCodec} for DSS keys, and re-constructs
* an instance of this object.
*
* @param k the contents of a previously encoded instance of this object.
* @exception ArrayIndexOutOfBoundsException if there is not enough bytes, in
* <code>k</code>, to represent a valid encoding of an
* instance of this object.
* @exception IllegalArgumentException if the byte sequence does not represent
* a valid encoding of an instance of this object.
*/
public static DSSPrivateKey valueOf(byte[] k)
{
// try RAW codec
if (k[0] == Registry.MAGIC_RAW_DSS_PRIVATE_KEY[0])
try
{
return (DSSPrivateKey) new DSSKeyPairRawCodec().decodePrivateKey(k);
}
catch (IllegalArgumentException ignored)
{
}
// try PKCS#8 codec
return (DSSPrivateKey) new DSSKeyPairPKCS8Codec().decodePrivateKey(k);
}
// Instance methods
// -------------------------------------------------------------------------
// java.security.interfaces.DSAPrivateKey interface implementation ---------
public BigInteger getX()
{
return x;
}
// Other instance methods --------------------------------------------------
/**
* <p>Returns the encoded form of this private key according to the
* designated format.</p>
*
* @param format the desired format identifier of the resulting encoding.
* @return the byte sequence encoding this key according to the designated
* format.
* @exception IllegalArgumentException if the format is not supported.
* @see DSSKeyPairRawCodec
*/
public byte[] getEncoded(int format)
{
byte[] result;
switch (format)
{
case IKeyPairCodec.RAW_FORMAT:
result = new DSSKeyPairRawCodec().encodePrivateKey(this);
break;
case IKeyPairCodec.PKCS8_FORMAT:
result = new DSSKeyPairPKCS8Codec().encodePrivateKey(this);
break;
default:
throw new IllegalArgumentException("Unsupported encoding format: "
+ format);
}
return result;
}
/**
* <p>Returns <code>true</code> if the designated object is an instance of
* {@link DSAPrivateKey} and has the same DSS (Digital Signature Standard)
* parameter values as this one.</p>
*
* @param obj the other non-null DSS key to compare to.
* @return <code>true</code> if the designated object is of the same type and
* value as this one.
*/
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (!(obj instanceof DSAPrivateKey))
{
return false;
}
DSAPrivateKey that = (DSAPrivateKey) obj;
return super.equals(that) && x.equals(that.getX());
}
}
@@ -0,0 +1,201 @@
/* DSSPublicKey.java --
Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.java.security.Registry;
import gnu.java.security.key.IKeyPairCodec;
import java.math.BigInteger;
import java.security.PublicKey;
import java.security.interfaces.DSAPublicKey;
/**
* <p>An object that embodies a DSS (Digital Signature Standard) public key.</p>
*
* @version $Revision: 1.2 $
* @see #getEncoded
*/
public class DSSPublicKey extends DSSKey implements PublicKey, DSAPublicKey
{
// Constants and variables
// -------------------------------------------------------------------------
/**
* <code>y = g<sup>x</sup> mod p</code> where <code>x</code> is the private
* part of the DSA key.
*/
private final BigInteger y;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Conveience constructor. Calls the constructor with 5 arguments passing
* {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
* encoding format.
*
* @param p the public modulus.
* @param q the public prime divisor of <code>p-1</code>.
* @param g a generator of the unique cyclic group <code>Z<sup>*</sup>
* <sub>p</sub></code>.
* @param y the public key part.
*/
public DSSPublicKey(BigInteger p, BigInteger q, BigInteger g, BigInteger y)
{
this(Registry.RAW_ENCODING_ID, p, q, g, y);
}
/**
* Constructs a new instance of <code>DSSPublicKey</code> given the designated
* arguments.
*
* @param preferredFormat the identifier of the preferred encoding format to
* use when externalizing this key.
* @param p the public modulus.
* @param q the public prime divisor of <code>p-1</code>.
* @param g a generator of the unique cyclic group <code>Z<sup>*</sup>
* <sub>p</sub></code>.
* @param y the public key part.
*/
public DSSPublicKey(int preferredFormat, BigInteger p, BigInteger q,
BigInteger g, BigInteger y)
{
super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.X509_ENCODING_ID
: preferredFormat,
p, q, g);
this.y = y;
}
// Class methods
// -------------------------------------------------------------------------
/**
* A class method that takes the output of the <code>encodePublicKey()</code>
* method of a DSS keypair codec object (an instance implementing
* {@link gnu.java.security.key.IKeyPairCodec} for DSS keys, and re-constructs
* an instance of this object.
*
* @param k the contents of a previously encoded instance of this object.
* @exception ArrayIndexOutOfBoundsException if there is not enough bytes, in
* <code>k</code>, to represent a valid encoding of an
* instance of this object.
* @exception IllegalArgumentException if the byte sequence does not represent
* a valid encoding of an instance of this object.
*/
public static DSSPublicKey valueOf(byte[] k)
{
// try RAW codec
if (k[0] == Registry.MAGIC_RAW_DSS_PUBLIC_KEY[0])
try
{
return (DSSPublicKey) new DSSKeyPairRawCodec().decodePublicKey(k);
}
catch (IllegalArgumentException ignored)
{
}
// try X.509 codec
return (DSSPublicKey) new DSSKeyPairX509Codec().decodePublicKey(k);
}
// Instance methods
// -------------------------------------------------------------------------
// java.security.interfaces.DSAPublicKey interface implementation ----------
public BigInteger getY()
{
return y;
}
// Other instance methods --------------------------------------------------
/**
* <p>Returns the encoded form of this public key according to the designated
* format.</p>
*
* @param format the desired format identifier of the resulting encoding.
* @return the byte sequence encoding this key according to the designated
* format.
* @exception IllegalArgumentException if the format is not supported.
* @see DSSKeyPairRawCodec
*/
public byte[] getEncoded(int format)
{
byte[] result;
switch (format)
{
case IKeyPairCodec.RAW_FORMAT:
result = new DSSKeyPairRawCodec().encodePublicKey(this);
break;
case IKeyPairCodec.X509_FORMAT:
result = new DSSKeyPairX509Codec().encodePublicKey(this);
break;
default:
throw new IllegalArgumentException("Unsupported encoding format: "
+ format);
}
return result;
}
/**
* <p>Returns <code>true</code> if the designated object is an instance of
* {@link DSAPublicKey} and has the same DSS (Digital Signature Standard)
* parameter values as this one.</p>
*
* @param obj the other non-null DSS key to compare to.
* @return <code>true</code> if the designated object is of the same type and
* value as this one.
*/
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (!(obj instanceof DSAPublicKey))
{
return false;
}
DSAPublicKey that = (DSAPublicKey) obj;
return super.equals(that) && y.equals(that.getY());
}
}
@@ -0,0 +1,296 @@
/* FIPS186.java --
Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.java.security.hash.Sha160;
import gnu.java.security.util.PRNG;
import gnu.java.security.util.Prime2;
import java.math.BigInteger;
import java.security.SecureRandom;
/**
* <p>An implementation of the DSA parameters generation as described in
* FIPS-186.</p>
*
* References:<br>
* <a href="http://www.itl.nist.gov/fipspubs/fip186.htm">Digital Signature
* Standard (DSS)</a>, Federal Information Processing Standards Publication 186.
* National Institute of Standards and Technology.
*
* @version $Revision: 1.2 $
*/
public class FIPS186
{
// Constants and variables
// -------------------------------------------------------------------------
public static final int DSA_PARAMS_SEED = 0;
public static final int DSA_PARAMS_COUNTER = 1;
public static final int DSA_PARAMS_Q = 2;
public static final int DSA_PARAMS_P = 3;
public static final int DSA_PARAMS_E = 4;
public static final int DSA_PARAMS_G = 5;
/** The BigInteger constant 2. */
private static final BigInteger TWO = new BigInteger("2");
private static final BigInteger TWO_POW_160 = TWO.pow(160);
/** The SHA instance to use. */
private Sha160 sha = new Sha160();
/** The length of the modulus of DSS keys generated by this instance. */
private int L;
/** The optional {@link SecureRandom} instance to use. */
private SecureRandom rnd = null;
/** Our default source of randomness. */
private PRNG prng = null;
// Constructor(s)
// -------------------------------------------------------------------------
public FIPS186(int L, SecureRandom rnd)
{
super();
this.L = L;
this.rnd = rnd;
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
/**
* This method generates the DSS <code>p</code>, <code>q</code>, and
* <code>g</code> parameters only when <code>L</code> (the modulus length)
* is not one of the following: <code>512</code>, <code>768</code> and
* <code>1024</code>. For those values of <code>L</code>, this implementation
* uses pre-computed values of <code>p</code>, <code>q</code>, and
* <code>g</code> given in the document <i>CryptoSpec</i> included in the
* security guide documentation of the standard JDK distribution.<p>
*
* The DSS requires two primes , <code>p</code> and <code>q</code>,
* satisfying the following three conditions:
*
* <ul>
* <li><code>2<sup>159</sup> &lt; q &lt; 2<sup>160</sup></code></li>
* <li><code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup></code> for a
* specified <code>L</code>, where <code>L = 512 + 64j</code> for some
* <code>0 &lt;= j &lt;= 8</code></li>
* <li>q divides p - 1.</li>
* </ul>
*
* The algorithm used to find these primes is as described in FIPS-186,
* section 2.2: GENERATION OF PRIMES. This prime generation scheme starts by
* using the {@link Sha160} and a user supplied <i>SEED</i>
* to construct a prime, <code>q</code>, in the range 2<sup>159</sup> &lt; q
* &lt; 2<sup>160</sup>. Once this is accomplished, the same <i>SEED</i>
* value is used to construct an <code>X</code> in the range <code>2<sup>L-1
* </sup> &lt; X &lt; 2<sup>L</sup>. The prime, <code>p</code>, is then
* formed by rounding <code>X</code> to a number congruent to <code>1 mod
* 2q</code>. In this implementation we use the same <i>SEED</i> value given
* in FIPS-186, Appendix 5.
*/
public BigInteger[] generateParameters()
{
int counter, offset;
BigInteger SEED, alpha, U, q, OFFSET, SEED_PLUS_OFFSET, W, X, p, c, g;
byte[] a, u;
byte[] kb = new byte[20]; // to hold 160 bits of randomness
// Let L-1 = n*160 + b, where b and n are integers and 0 <= b < 160.
int b = (L - 1) % 160;
int n = (L - 1 - b) / 160;
BigInteger[] V = new BigInteger[n + 1];
algorithm: while (true)
{
step1: while (true)
{
// 1. Choose an arbitrary sequence of at least 160 bits and
// call it SEED.
nextRandomBytes(kb);
SEED = new BigInteger(1, kb).setBit(159).setBit(0);
// Let g be the length of SEED in bits. here always 160
// 2. Compute: U = SHA[SEED] XOR SHA[(SEED+1) mod 2**g]
alpha = SEED.add(BigInteger.ONE).mod(TWO_POW_160);
synchronized (sha)
{
a = SEED.toByteArray();
sha.update(a, 0, a.length);
a = sha.digest();
u = alpha.toByteArray();
sha.update(u, 0, u.length);
u = sha.digest();
}
for (int i = 0; i < a.length; i++)
{
a[i] ^= u[i];
}
U = new BigInteger(1, a);
// 3. Form q from U by setting the most significant bit (the
// 2**159 bit) and the least significant bit to 1. In terms of
// boolean operations, q = U OR 2**159 OR 1. Note that
// 2**159 < q < 2**160.
q = U.setBit(159).setBit(0);
// 4. Use a robust primality testing algorithm to test whether
// q is prime(1). A robust primality test is one where the
// probability of a non-prime number passing the test is at
// most 1/2**80.
// 5. If q is not prime, go to step 1.
if (Prime2.isProbablePrime(q))
{
break step1;
}
} // step1
// 6. Let counter = 0 and offset = 2.
counter = 0;
offset = 2;
step7: while (true)
{
OFFSET = BigInteger.valueOf(offset & 0xFFFFFFFFL);
SEED_PLUS_OFFSET = SEED.add(OFFSET);
// 7. For k = 0,...,n let V[k] = SHA[(SEED + offset + k) mod 2**g].
synchronized (sha)
{
for (int k = 0; k <= n; k++)
{
a = SEED_PLUS_OFFSET.add(
BigInteger.valueOf(k & 0xFFFFFFFFL)).mod(
TWO_POW_160).toByteArray();
sha.update(a, 0, a.length);
V[k] = new BigInteger(1, sha.digest());
}
}
// 8. Let W be the integer:
// V[0]+V[1]*2**160+...+V[n-1]*2**((n-1)*160)+(V[n]mod2**b)*2**(n*160)
// and let : X = W + 2**(L-1).
// Note that 0 <= W < 2**(L-1) and hence 2**(L-1) <= X < 2**L.
W = V[0];
for (int k = 1; k < n; k++)
{
W = W.add(V[k].multiply(TWO.pow(k * 160)));
}
W = W.add(V[n].mod(TWO.pow(b)).multiply(TWO.pow(n * 160)));
X = W.add(TWO.pow(L - 1));
// 9. Let c = X mod 2q and set p = X - (c - 1).
// Note that p is congruent to 1 mod 2q.
c = X.mod(TWO.multiply(q));
p = X.subtract(c.subtract(BigInteger.ONE));
// 10. If p < 2**(L-1), then go to step 13.
if (p.compareTo(TWO.pow(L - 1)) >= 0)
{
// 11. Perform a robust primality test on p.
// 12. If p passes the test performed in step 11, go to step 15.
if (Prime2.isProbablePrime(p))
{
break algorithm;
}
}
// 13. Let counter = counter + 1 and offset = offset + n + 1.
counter++;
offset += n + 1;
// 14. If counter >= 4096 go to step 1, otherwise go to step 7.
if (counter >= 4096)
{
continue algorithm;
}
} // step7
} // algorithm
// compute g. from FIPS-186, Appendix 4:
// 1. Generate p and q as specified in Appendix 2.
// 2. Let e = (p - 1) / q
BigInteger e = p.subtract(BigInteger.ONE).divide(q);
BigInteger h = TWO;
BigInteger p_minus_1 = p.subtract(BigInteger.ONE);
g = TWO;
// 3. Set h = any integer, where 1 < h < p - 1 and
// h differs from any value previously tried
for (; h.compareTo(p_minus_1) < 0; h = h.add(BigInteger.ONE))
{
// 4. Set g = h**e mod p
g = h.modPow(e, p);
// 5. If g = 1, go to step 3
if (!g.equals(BigInteger.ONE))
{
break;
}
}
return new BigInteger[] { SEED, BigInteger.valueOf(counter), q, p, e, g };
}
// helper methods ----------------------------------------------------------
/**
* Fills the designated byte array with random data.
*
* @param buffer the byte array to fill with random data.
*/
private void nextRandomBytes(byte[] buffer)
{
if (rnd != null)
{
rnd.nextBytes(buffer);
}
else
getDefaultPRNG().nextBytes(buffer);
}
private PRNG getDefaultPRNG()
{
if (prng == null)
prng = PRNG.getInstance();
return prng;
}
}
@@ -0,0 +1,181 @@
/* GnuRSAKey.java --
Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.rsa;
import gnu.java.security.Registry;
import gnu.java.security.key.IKeyPairCodec;
import gnu.java.security.util.FormatUtil;
import java.math.BigInteger;
import java.security.Key;
import java.security.interfaces.RSAKey;
/**
* <p>A base asbtract class for both public and private RSA keys.</p>
*
* @version $Revision: 1.3 $
*/
public abstract class GnuRSAKey implements Key, RSAKey
{
// Constants and variables
// -------------------------------------------------------------------------
/** The public modulus of an RSA key pair. */
private final BigInteger n;
/** The public exponent of an RSA key pair. */
private final BigInteger e;
/**
* Identifier of the default encoding format to use when externalizing the
* key material.
*/
protected final int defaultFormat;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Trivial protected constructor.
*
* @param defaultFormat the identifier of the encoding format to use by
* default when externalizing the key.
* @param n the public modulus <code>n</code>.
* @param e the public exponent <code>e</code>.
*/
protected GnuRSAKey(int defaultFormat, BigInteger n, BigInteger e)
{
super();
this.defaultFormat = defaultFormat <= 0 ? Registry.RAW_ENCODING_ID
: defaultFormat;
this.n = n;
this.e = e;
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// java.security.interfaces.RSAKey interface implementation ----------------
public BigInteger getModulus()
{
return getN();
}
// java.security.Key interface implementation ------------------------------
public String getAlgorithm()
{
return Registry.RSA_KPG;
}
/** @deprecated see getEncoded(int). */
public byte[] getEncoded()
{
return getEncoded(IKeyPairCodec.RAW_FORMAT);
}
public String getFormat()
{
return FormatUtil.getEncodingShortName(defaultFormat);
}
// Other instance methods --------------------------------------------------
/**
* <p>Returns the modulus <code>n</code>.</p>
*
* @return the modulus <code>n</code>.
*/
public BigInteger getN()
{
return n;
}
/**
* <p>Returns the public exponent <code>e</code>.</p>
*
* @return the public exponent <code>e</code>.
*/
public BigInteger getPublicExponent()
{
return getE();
}
/**
* <p>Same as {@link #getPublicExponent()}.</p>
*
* @return the public exponent <code>e</code>.
*/
public BigInteger getE()
{
return e;
}
/**
* <p>Returns <code>true</code> if the designated object is an instance of
* {@link RSAKey} and has the same RSA parameter values as this one.</p>
*
* @param obj the other non-null RSA key to compare to.
* @return <code>true</code> if the designated object is of the same type and
* value as this one.
*/
public boolean equals(final Object obj)
{
if (obj == null)
{
return false;
}
if (!(obj instanceof RSAKey))
{
return false;
}
final RSAKey that = (RSAKey) obj;
return n.equals(that.getModulus());
}
// abstract methods to be implemented by subclasses ------------------------
public abstract byte[] getEncoded(int format);
}
@@ -0,0 +1,299 @@
/* GnuRSAPrivateKey.java --
Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.rsa;
import gnu.java.security.Registry;
import gnu.java.security.key.IKeyPairCodec;
import java.math.BigInteger;
import java.security.PrivateKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
/**
* <p>An object that embodies an RSA private key.</p>
*
* <p>References:</p>
* <ol>
* <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip">
* RSA-PSS Signature Scheme with Appendix, part B.</a><br>
* Primitive specification and supporting documentation.<br>
* Jakob Jonsson and Burt Kaliski.</li>
* </ol>
*
* @version $Revision: 1.3 $
*/
public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
RSAPrivateCrtKey
{
// Constants and variables
// -------------------------------------------------------------------------
/** The first prime divisor of the modulus. */
private final BigInteger p;
/** The second prime divisor of the modulus. */
private final BigInteger q;
/** The public exponent of an RSA key. */
// private final BigInteger e;
/** The private exponent of an RSA private key. */
private final BigInteger d;
/** The first factor's exponent. */
private final BigInteger dP;
/** The second factor's exponent. */
private final BigInteger dQ;
/** The CRT (Chinese Remainder Theorem) coefficient. */
private final BigInteger qInv;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Convenience constructor. Calls the constructor with 5 arguments passing
* {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
* encoding format.
*
* @param p the modulus first prime divisor.
* @param q the modulus second prime divisor.
* @param e the public exponent.
* @param d the private exponent.
*/
public GnuRSAPrivateKey(BigInteger p, BigInteger q, BigInteger e,
BigInteger d)
{
this(Registry.RAW_ENCODING_ID, p, q, e, d);
}
/**
* Constructs a new instance of a <code>GnuRSAPrivateKey</code> given the
* designated arguments.
*
* @param preferredFormat the indetifier of the preferred encoding format to
* use when externalizing this key.
* @param p the modulus first prime divisor.
* @param q the modulus second prime divisor.
* @param e the public exponent.
* @param d the private exponent.
*/
public GnuRSAPrivateKey(int preferredFormat, BigInteger p, BigInteger q,
BigInteger e, BigInteger d)
{
this(preferredFormat, p.multiply(q), e, d, p, q,
e.modInverse(p.subtract(BigInteger.ONE)),
e.modInverse(q.subtract(BigInteger.ONE)),
q.modInverse(p));
}
/**
* Constructs a new instance of a <code>GnuRSAPrivateKey</code> given the
* designated arguments.
*
* @param preferredFormat the indetifier of the preferred encoding format to
* use when externalizing this key.
* @param n the public modulus, which is also the product of <code>p</code>
* and <code>q</code>.
* @param e the public exponent.
* @param d the private exponent.
* @param p the modulus first prime divisor.
* @param q the modulus second prime divisor.
* @param dP the first prime's exponen. A positive integer less than
* <code>p</code> and <code>q</code>, satisfying <code>e * dP = 1 (mod p-1)
* </code>.
* @param dQ the second prime's exponent. A positive integer less than
* <code>p</code> and <code>q</code>, satisfying <code>e * dQ = 1 (mod p-1)
* </code>.
* @param qInv the Chinese Remainder Theorem coefiicient. A positive integer
* less than <code>p</code>, satisfying <code>q * qInv = 1 (mod p)</code>.
*/
public GnuRSAPrivateKey(int preferredFormat, BigInteger n, BigInteger e,
BigInteger d, BigInteger p, BigInteger q,
BigInteger dP, BigInteger dQ, BigInteger qInv)
{
super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.PKCS8_ENCODING_ID
: preferredFormat,
n, e);
this.d = d;
this.p = p;
this.q = q;
// the exponents dP and dQ are positive integers less than p and q
// respectively satisfying
// e * dP = 1 (mod p-1);
// e * dQ = 1 (mod q-1),
this.dP = dP;
this.dQ = dQ;
// the CRT coefficient qInv is a positive integer less than p satisfying
// q * qInv = 1 (mod p).
this.qInv = qInv;
}
// Class methods
// -------------------------------------------------------------------------
/**
* A class method that takes the output of the <code>encodePrivateKey()</code>
* method of an RSA keypair codec object (an instance implementing
* {@link IKeyPairCodec} for RSA keys, and re-constructs an instance of this
* object.
*
* @param k the contents of a previously encoded instance of this object.
* @throws ArrayIndexOutOfBoundsException if there is not enough bytes, in
* <code>k</code>, to represent a valid encoding of an instance
* of this object.
* @throws IllegalArgumentException if the byte sequence does not represent a
* valid encoding of an instance of this object.
*/
public static GnuRSAPrivateKey valueOf(final byte[] k)
{
// try RAW codec
if (k[0] == Registry.MAGIC_RAW_RSA_PRIVATE_KEY[0])
try
{
return (GnuRSAPrivateKey) new RSAKeyPairRawCodec().decodePrivateKey(k);
}
catch (IllegalArgumentException ignored)
{
}
// try PKCS#8 codec
return (GnuRSAPrivateKey) new RSAKeyPairPKCS8Codec().decodePrivateKey(k);
}
// Instance methods
// -------------------------------------------------------------------------
public BigInteger getPrimeP()
{
return p;
}
public BigInteger getPrimeQ()
{
return q;
}
public BigInteger getPrimeExponentP()
{
return dP;
}
public BigInteger getPrimeExponentQ()
{
return dQ;
}
public BigInteger getCrtCoefficient()
{
return qInv;
}
// java.security.interfaces.RSAPrivateKey interface implementation ---------
public BigInteger getPrivateExponent()
{
return d;
}
// Other instance methods --------------------------------------------------
/**
* Returns the encoded form of this private key according to the
* designated format.
*
* @param format the desired format identifier of the resulting encoding.
* @return the byte sequence encoding this key according to the designated
* format.
* @throws IllegalArgumentException if the format is not supported.
* @see RSAKeyPairRawCodec
* @see RSAKeyPairPKCS8Codec
*/
public byte[] getEncoded(int format)
{
final byte[] result;
switch (format)
{
case IKeyPairCodec.RAW_FORMAT:
result = new RSAKeyPairRawCodec().encodePrivateKey(this);
break;
case IKeyPairCodec.PKCS8_FORMAT:
result = new RSAKeyPairPKCS8Codec().encodePrivateKey(this);
break;
default:
throw new IllegalArgumentException("Unsupported encoding format: "
+ format);
}
return result;
}
/**
* <p>Returns <code>true</code> if the designated object is an instance of
* this class and has the same RSA parameter values as this one.</p>
*
* @param obj the other non-null RSA key to compare to.
* @return <code>true</code> if the designated object is of the same type
* and value as this one.
*/
public boolean equals(final Object obj)
{
if (obj == null)
{
return false;
}
if (obj instanceof RSAPrivateKey)
{
final RSAPrivateKey that = (RSAPrivateKey) obj;
return super.equals(that) && d.equals(that.getPrivateExponent());
}
if (obj instanceof RSAPrivateCrtKey)
{
final RSAPrivateCrtKey that = (RSAPrivateCrtKey) obj;
return super.equals(that) && p.equals(that.getPrimeP())
&& q.equals(that.getPrimeQ())
&& dP.equals(that.getPrimeExponentP())
&& dQ.equals(that.getPrimeExponentQ())
&& qInv.equals(that.getCrtCoefficient());
}
return false;
}
}
@@ -0,0 +1,185 @@
/* GnuRSAPublicKey.java --
Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.rsa;
import gnu.java.security.Registry;
import gnu.java.security.key.IKeyPairCodec;
import java.math.BigInteger;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
/**
* <p>An object that encapsulates an RSA public key.</p>
*
* <p>References:</p>
* <ol>
* <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip">
* RSA-PSS Signature Scheme with Appendix, part B.</a><br>
* Primitive specification and supporting documentation.<br>
* Jakob Jonsson and Burt Kaliski.</li>
* </ol>
*
* @version $Revision: 1.2 $
*/
public class GnuRSAPublicKey extends GnuRSAKey implements PublicKey,
RSAPublicKey
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Conveience constructor. Calls the constructor with 3 arguments passing
* {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
* encoding format.
*
* @param n the modulus.
* @param e the public exponent.
*/
public GnuRSAPublicKey(final BigInteger n, final BigInteger e)
{
this(Registry.RAW_ENCODING_ID, n, e);
}
/**
* Constructs a new instance of <code>GnuRSAPublicKey</code> given the
* designated arguments.
*
* @param preferredFormat the identifier of the preferred encoding format to
* use when externalizing this key.
* @param n the modulus.
* @param e the public exponent.
*/
public GnuRSAPublicKey(int preferredFormat, BigInteger n, BigInteger e)
{
super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.X509_ENCODING_ID
: preferredFormat,
n, e);
}
// Class methods
// -------------------------------------------------------------------------
/**
* A class method that takes the output of the <code>encodePublicKey()</code>
* method of an RSA keypair codec object (an instance implementing
* {@link IKeyPairCodec} for RSA keys, and re-constructs an instance of this
* object.
*
* @param k the contents of a previously encoded instance of this object.
* @throws ArrayIndexOutOfBoundsException if there is not enough bytes, in
* <code>k</code>, to represent a valid encoding of an instance
* of this object.
* @throws IllegalArgumentException if the byte sequence does not represent a
* valid encoding of an instance of this object.
*/
public static GnuRSAPublicKey valueOf(final byte[] k)
{
// try RAW codec
if (k[0] == Registry.MAGIC_RAW_RSA_PUBLIC_KEY[0])
try
{
return (GnuRSAPublicKey) new RSAKeyPairRawCodec().decodePublicKey(k);
}
catch (IllegalArgumentException ignored)
{
}
// try X.509 codec
return (GnuRSAPublicKey) new RSAKeyPairX509Codec().decodePublicKey(k);
}
// Instance methods
// -------------------------------------------------------------------------
/**
* <p>Returns the encoded form of this public key according to the designated
* format.</p>
*
* @param format the desired format identifier of the resulting encoding.
* @return the byte sequence encoding this key according to the designated
* format.
* @throws IllegalArgumentException if the format is not supported.
* @see RSAKeyPairRawCodec
*/
public byte[] getEncoded(final int format)
{
final byte[] result;
switch (format)
{
case IKeyPairCodec.RAW_FORMAT:
result = new RSAKeyPairRawCodec().encodePublicKey(this);
break;
case IKeyPairCodec.X509_FORMAT:
result = new RSAKeyPairX509Codec().encodePublicKey(this);
break;
default:
throw new IllegalArgumentException("Unsupported encoding format: "
+ format);
}
return result;
}
/**
* <p>Returns <code>true</code> if the designated object is an instance of
* this class and has the same RSA parameter values as this one.</p>
*
* @param obj the other non-null RSA key to compare to.
* @return <code>true</code> if the designated object is of the same type and
* value as this one.
*/
public boolean equals(final Object obj)
{
if (obj == null)
{
return false;
}
if (!(obj instanceof RSAPublicKey))
{
return false;
}
final RSAPublicKey that = (RSAPublicKey) obj;
return super.equals(that)
&& getPublicExponent().equals(that.getPublicExponent());
}
}
@@ -0,0 +1,264 @@
/* RSAKeyPairGenerator.java --
Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.rsa;
import gnu.java.security.Registry;
import gnu.java.security.key.IKeyPairGenerator;
import gnu.java.security.util.PRNG;
import gnu.java.security.util.Prime2;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.Map;
/**
* <p>A key-pair generator for asymetric keys to use in conjunction with the RSA
* scheme.</p>
*
* <p>Reference:</p>
* <ol>
* <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip">
* RSA-PSS Signature Scheme with Appendix</a>, part B. Primitive
* specification and supporting documentation. Jakob Jonsson and Burt Kaliski.
* </li>
* <li><a href="http://www.cacr.math.uwaterloo.ca/hac/">Handbook of Applied
* Cryptography</a>, Alfred J. Menezes, Paul C. van Oorschot and Scott A.
* Vanstone. Section 11.3 RSA and related signature schemes.</li>
* </ol>
*/
public class RSAKeyPairGenerator implements IKeyPairGenerator
{
// Constants and variables
// -------------------------------------------------------------------------
/** The BigInteger constant 1. */
private static final BigInteger ONE = BigInteger.ONE;
/** The BigInteger constant 2. */
private static final BigInteger TWO = BigInteger.valueOf(2L);
/** Property name of the length (Integer) of the modulus of an RSA key. */
public static final String MODULUS_LENGTH = "gnu.crypto.rsa.L";
/**
* Property name of an optional {@link SecureRandom} instance to use. The
* default is to use a classloader singleton from {@link PRNG}.
*/
public static final String SOURCE_OF_RANDOMNESS = "gnu.crypto.rsa.prng";
/**
* Property name of an optional {@link RSAKeyGenParameterSpec} instance to
* use for this generator's <code>n</code>, and <code>e</code> values. The
* default is to generate <code>n</code> and use a fixed value for
* <code>e</.code> (Fermat's F4 number).
*/
public static final String RSA_PARAMETERS = "gnu.crypto.rsa.params";
/**
* Property name of the preferred encoding format to use when externalizing
* generated instance of key-pairs from this generator. The property is taken
* to be an {@link Integer} that encapsulates an encoding format identifier.
*/
public static final String PREFERRED_ENCODING_FORMAT = "gnu.crypto.rsa.encoding";
/** Default value for the modulus length. */
private static final int DEFAULT_MODULUS_LENGTH = 1024;
/** Default encoding format to use when none was specified. */
private static final int DEFAULT_ENCODING_FORMAT = Registry.RAW_ENCODING_ID;
/** The desired bit length of the modulus. */
private int L;
/**
* This implementation uses, by default, Fermat's F4 number as the public
* exponent.
*/
private BigInteger e = BigInteger.valueOf(65537L);
/** The optional {@link SecureRandom} instance to use. */
private SecureRandom rnd = null;
/** Our default source of randomness. */
private PRNG prng = null;
/** Preferred encoding format of generated keys. */
private int preferredFormat;
// Constructor(s)
// -------------------------------------------------------------------------
// implicit 0-arguments constructor
// Class methods
// -------------------------------------------------------------------------
// gnu.crypto.key.IKeyPairGenerator interface implementation ---------------
public String name()
{
return Registry.RSA_KPG;
}
/**
* <p>Configures this instance.</p>
*
* @param attributes the map of name/value pairs to use.
* @exception IllegalArgumentException if the designated MODULUS_LENGTH
* value is less than 1024.
*/
public void setup(Map attributes)
{
// do we have a SecureRandom, or should we use our own?
rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS);
// are we given a set of RSA params or we shall use our own?
RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) attributes.get(RSA_PARAMETERS);
// find out the modulus length
if (params != null)
{
L = params.getKeysize();
e = params.getPublicExponent();
}
else
{
Integer l = (Integer) attributes.get(MODULUS_LENGTH);
L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue());
}
if (L < 1024)
{
throw new IllegalArgumentException(MODULUS_LENGTH);
}
// what is the preferred encoding format
Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT);
preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT
: formatID.intValue();
}
/**
* <p>The algorithm used here is described in <i>nessie-pss-B.pdf</i>
* document which is part of the RSA-PSS submission to NESSIE.</p>
*
* @return an RSA keypair.
*/
public KeyPair generate()
{
BigInteger p, q, n, d;
// 1. Generate a prime p in the interval [2**(M-1), 2**M - 1], where
// M = CEILING(L/2), and such that GCD(p, e) = 1
int M = (L + 1) / 2;
BigInteger lower = TWO.pow(M - 1);
BigInteger upper = TWO.pow(M).subtract(ONE);
byte[] kb = new byte[(M + 7) / 8]; // enough bytes to frame M bits
step1: while (true)
{
nextRandomBytes(kb);
p = new BigInteger(1, kb).setBit(0);
if (p.compareTo(lower) >= 0 && p.compareTo(upper) <= 0
&& Prime2.isProbablePrime(p) && p.gcd(e).equals(ONE))
{
break step1;
}
}
// 2. Generate a prime q such that the product of p and q is an L-bit
// number, and such that GCD(q, e) = 1
step2: while (true)
{
nextRandomBytes(kb);
q = new BigInteger(1, kb).setBit(0);
n = p.multiply(q);
if (n.bitLength() == L && Prime2.isProbablePrime(q)
&& q.gcd(e).equals(ONE))
{
break step2;
}
// TODO: test for p != q
}
// TODO: ensure p < q
// 3. Put n = pq. The public key is (n, e).
// 4. Compute the parameters necessary for the private key K (see
// Section 2.2).
BigInteger phi = p.subtract(ONE).multiply(q.subtract(ONE));
d = e.modInverse(phi);
// 5. Output the public key and the private key.
PublicKey pubK = new GnuRSAPublicKey(preferredFormat, n, e);
PrivateKey secK = new GnuRSAPrivateKey(preferredFormat, p, q, e, d);
return new KeyPair(pubK, secK);
}
// helper methods ----------------------------------------------------------
/**
* <p>Fills the designated byte array with random data.</p>
*
* @param buffer the byte array to fill with random data.
*/
private void nextRandomBytes(byte[] buffer)
{
if (rnd != null)
{
rnd.nextBytes(buffer);
}
else
getDefaultPRNG().nextBytes(buffer);
}
private PRNG getDefaultPRNG()
{
if (prng == null)
prng = PRNG.getInstance();
return prng;
}
}
@@ -0,0 +1,284 @@
/* RSAKeyPairPKCS8Codec.java -- PKCS#8 Encoding/Decoding handler
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.rsa;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidParameterException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.ArrayList;
import gnu.java.security.OID;
import gnu.java.security.Registry;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import gnu.java.security.key.IKeyPairCodec;
import gnu.java.security.util.DerUtil;
/**
* An implementation of an {@link IKeyPairCodec} that knows how to encode /
* decode PKCS#8 ASN.1 external representation of RSA private keys.
*/
public class RSAKeyPairPKCS8Codec
implements IKeyPairCodec
{
private static final OID RSA_ALG_OID = new OID(Registry.RSA_OID_STRING);
// implicit 0-arguments constructor
public int getFormatID()
{
return PKCS8_FORMAT;
}
/**
* @throws InvalidParameterException ALWAYS.
*/
public byte[] encodePublicKey(PublicKey key)
{
throw new InvalidParameterException("Wrong format for public keys");
}
/**
* Returns the PKCS#8 ASN.1 <i>PrivateKeyInfo</i> representation of an RSA
* private key. The ASN.1 specification is as follows:
*
* <pre>
* PrivateKeyInfo ::= SEQUENCE {
* version INTEGER, -- MUST be 0
* privateKeyAlgorithm AlgorithmIdentifier,
* privateKey OCTET STRING
* }
*
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL
* }
* </pre>
*
* <p>The <i>privateKey</i> field, which is an OCTET STRING, contains the
* DER-encoded form of the RSA private key defined as:</p>
*
* <pre>
* RSAPrivateKey ::= SEQUENCE {
* version INTEGER, -- MUST be 0
* modulus INTEGER, -- n
* publicExponent INTEGER, -- e
* privateExponent INTEGER, -- d
* prime1 INTEGER, -- p
* prime2 INTEGER, -- q
* exponent1 INTEGER, -- d mod (p-1)
* exponent2 INTEGER, -- d mod (q-1)
* coefficient INTEGER, -- (inverse of q) mod p
* }
* </pre>
*
* @return the DER encoded form of the ASN.1 representation of the
* <i>PrivateKeyInfo</i> field for an RSA {@link PrivateKey}..
* @throw InvalidParameterException if an error occurs during the marshalling
* process.
*/
public byte[] encodePrivateKey(PrivateKey key)
{
if (! (key instanceof GnuRSAPrivateKey))
throw new InvalidParameterException("Wrong key type");
GnuRSAPrivateKey pk = (GnuRSAPrivateKey) key;
BigInteger n = pk.getN();
BigInteger e = pk.getE();
BigInteger d = pk.getPrivateExponent();
BigInteger p = pk.getPrimeP();
BigInteger q = pk.getPrimeQ();
BigInteger dP = pk.getPrimeExponentP();
BigInteger dQ = pk.getPrimeExponentQ();
BigInteger qInv = pk.getCrtCoefficient();
DERValue derVersion = new DERValue(DER.INTEGER, BigInteger.ZERO);
DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, RSA_ALG_OID);
ArrayList algorithmID = new ArrayList(1);
algorithmID.add(derOID);
DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
algorithmID);
DERValue derRSAVersion = new DERValue(DER.INTEGER, BigInteger.ZERO);
DERValue derN = new DERValue(DER.INTEGER, n);
DERValue derE = new DERValue(DER.INTEGER, e);
DERValue derD = new DERValue(DER.INTEGER, d);
DERValue derP = new DERValue(DER.INTEGER, p);
DERValue derQ = new DERValue(DER.INTEGER, q);
DERValue derDP = new DERValue(DER.INTEGER, dP);
DERValue derDQ = new DERValue(DER.INTEGER, dQ);
DERValue derQInv = new DERValue(DER.INTEGER, qInv);
ArrayList rsaPrivateKey = new ArrayList();
rsaPrivateKey.add(derRSAVersion);
rsaPrivateKey.add(derN);
rsaPrivateKey.add(derE);
rsaPrivateKey.add(derD);
rsaPrivateKey.add(derP);
rsaPrivateKey.add(derQ);
rsaPrivateKey.add(derDP);
rsaPrivateKey.add(derDQ);
rsaPrivateKey.add(derQInv);
DERValue derRSAPrivateKey = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
rsaPrivateKey);
byte[] pkBytes = derRSAPrivateKey.getEncoded();
DERValue derPrivateKey = new DERValue(DER.OCTET_STRING, pkBytes);
ArrayList pki = new ArrayList(3);
pki.add(derVersion);
pki.add(derAlgorithmID);
pki.add(derPrivateKey);
DERValue derPKI = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, pki);
byte[] result;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try
{
DERWriter.write(baos, derPKI);
result = baos.toByteArray();
}
catch (IOException x)
{
InvalidParameterException y = new InvalidParameterException();
y.initCause(x);
throw y;
}
return result;
}
/**
* @throws InvalidParameterException ALWAYS.
*/
public PublicKey decodePublicKey(byte[] input)
{
throw new InvalidParameterException("Wrong format for public keys");
}
/**
* @param input the byte array to unmarshall into a valid RSA
* {@link PrivateKey} instance. MUST NOT be null.
* @return a new instance of a {@link GnuRSAPrivateKey} decoded from the
* <i>PrivateKeyInfo</i> material fed as <code>input</code>.
* @throw InvalidParameterException if an exception occurs during the
* unmarshalling process.
*/
public PrivateKey decodePrivateKey(byte[] input)
{
if (input == null)
throw new InvalidParameterException("Input bytes MUST NOT be null");
BigInteger version, n, e, d, p, q, dP, dQ, qInv;
DERReader der = new DERReader(input);
try
{
DERValue derPKI = der.read();
DerUtil.checkIsConstructed(derPKI, "Wrong PrivateKeyInfo field");
DERValue derVersion = der.read();
DerUtil.checkIsBigInteger(derVersion, "Wrong Version field");
version = (BigInteger) derVersion.getValue();
if (version.compareTo(BigInteger.ZERO) != 0)
throw new InvalidParameterException("Unexpected Version: " + version);
DERValue derAlgoritmID = der.read();
DerUtil.checkIsConstructed(derAlgoritmID, "Wrong AlgorithmIdentifier field");
DERValue derOID = der.read();
OID algOID = (OID) derOID.getValue();
if (! algOID.equals(RSA_ALG_OID))
throw new InvalidParameterException("Unexpected OID: " + algOID);
DERValue val = der.read();
byte[] pkBytes = (byte[]) val.getValue();
der = new DERReader(pkBytes);
DERValue derRSAPrivateKey = der.read();
DerUtil.checkIsConstructed(derRSAPrivateKey, "Wrong RSAPrivateKey field");
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong RSAPrivateKey Version field");
version = (BigInteger) val.getValue();
if (version.compareTo(BigInteger.ZERO) != 0)
throw new InvalidParameterException("Unexpected RSAPrivateKey Version: "
+ version);
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong modulus field");
n = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong publicExponent field");
e = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong privateExponent field");
d = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong prime1 field");
p = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong prime2 field");
q = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong exponent1 field");
dP = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong exponent2 field");
dQ = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong coefficient field");
qInv = (BigInteger) val.getValue();
}
catch (IOException x)
{
InvalidParameterException y = new InvalidParameterException();
y.initCause(x);
throw y;
}
return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID, n, e, d, p, q,
dP, dQ, qInv);
}
}
@@ -0,0 +1,332 @@
/* RSAKeyPairRawCodec.java --
Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.rsa;
import gnu.java.security.Registry;
import gnu.java.security.key.IKeyPairCodec;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.security.PrivateKey;
import java.security.PublicKey;
/**
* <p>An object that implements the {@link IKeyPairCodec} interface for the
* <i>Raw</i> format to use with RSA keypairs.</p>
*
* @version $Revision: 1.1 $
*/
public class RSAKeyPairRawCodec implements IKeyPairCodec
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
// implicit 0-arguments constructor
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// gnu.crypto.key.IKeyPairCodec interface implementation -------------------
public int getFormatID()
{
return RAW_FORMAT;
}
/**
* <p>Returns the encoded form of the designated RSA public key according to
* the <i>Raw</i> format supported by this library.</p>
*
* <p>The <i>Raw</i> format for an RSA public key, in this implementation, is
* a byte sequence consisting of the following:</p>
*
* <ol>
* <li>4-byte magic consisting of the value of the literal
* {@link Registry#MAGIC_RAW_RSA_PUBLIC_KEY},<li>
* <li>1-byte version consisting of the constant: 0x01,</li>
* <li>4-byte count of following bytes representing the RSA parameter
* <code>n</code> (the modulus) in internet order,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the RSA parameter <code>n</code>,</li>
* <li>4-byte count of following bytes representing the RSA parameter
* <code>e</code> (the public exponent) in internet order,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the RSA parameter <code>e</code>.</li>
* </ol>
*
* @param key the key to encode.
* @return the <i>Raw</i> format encoding of the designated key.
* @exception IllegalArgumentException if the designated key is not an RSA
* one.
*/
public byte[] encodePublicKey(PublicKey key)
{
if (!(key instanceof GnuRSAPublicKey))
{
throw new IllegalArgumentException("key");
}
GnuRSAPublicKey rsaKey = (GnuRSAPublicKey) key;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// magic
baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[0]);
baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[1]);
baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[2]);
baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[3]);
// version
baos.write(0x01);
// n
byte[] buffer = rsaKey.getModulus().toByteArray();
int length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// e
buffer = rsaKey.getPublicExponent().toByteArray();
length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
return baos.toByteArray();
}
public PublicKey decodePublicKey(byte[] k)
{
// magic
if (k[0] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[0]
|| k[1] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[1]
|| k[2] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[2]
|| k[3] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[3])
{
throw new IllegalArgumentException("magic");
}
// version
if (k[4] != 0x01)
{
throw new IllegalArgumentException("version");
}
int i = 5;
int l;
byte[] buffer;
// n
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger n = new BigInteger(1, buffer);
// e
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger e = new BigInteger(1, buffer);
return new GnuRSAPublicKey(n, e);
}
/**
* <p>Returns the encoded form of the designated RSA private key according to
* the <i>Raw</i> format supported by this library.</p>
*
* <p>The <i>Raw</i> format for an RSA private key, in this implementation,
* is a byte sequence consisting of the following:</p>
*
* <ol>
* <li>4-byte magic consisting of the value of the literal
* {@link Registry#MAGIC_RAW_RSA_PRIVATE_KEY},<li>
* <li>1-byte version consisting of the constant: 0x01,</li>
* <li>4-byte count of following bytes representing the RSA parameter
* <code>p</code> (the first prime factor of the modulus) in internet
* order,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the RSA parameter <code>p</code>,</li>
* <li>4-byte count of following bytes representing the RSA parameter
* <code>q</code> (the second prime factor of the modulus) in internet
* order,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the RSA parameter <code>q</code>,</li>
* <li>4-byte count of following bytes representing the RSA parameter
* <code>e</code> (the public exponent) in internet order,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the RSA parameter <code>e</code>,</li>
* <li>4-byte count of following bytes representing the RSA parameter
* <code>d</code> (the private exponent) in internet order,</li>
* <li>n-bytes representation of a {@link BigInteger} obtained by invoking
* the <code>toByteArray()</code> method on the RSA parameter <code>d</code>,</li>
* </ol>
*
* @param key the key to encode.
* @return the <i>Raw</i> format encoding of the designated key.
*/
public byte[] encodePrivateKey(PrivateKey key)
{
if (!(key instanceof GnuRSAPrivateKey))
{
throw new IllegalArgumentException("key");
}
GnuRSAPrivateKey rsaKey = (GnuRSAPrivateKey) key;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// magic
baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[0]);
baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[1]);
baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[2]);
baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[3]);
// version
baos.write(0x01);
// p
byte[] buffer = rsaKey.getPrimeP().toByteArray();
int length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// q
buffer = rsaKey.getPrimeQ().toByteArray();
length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// e
buffer = rsaKey.getPublicExponent().toByteArray();
length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// d
buffer = rsaKey.getPrivateExponent().toByteArray();
length = buffer.length;
baos.write(length >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
return baos.toByteArray();
}
public PrivateKey decodePrivateKey(byte[] k)
{
// magic
if (k[0] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[0]
|| k[1] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[1]
|| k[2] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[2]
|| k[3] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[3])
{
throw new IllegalArgumentException("magic");
}
// version
if (k[4] != 0x01)
{
throw new IllegalArgumentException("version");
}
int i = 5;
int l;
byte[] buffer;
// p
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger p = new BigInteger(1, buffer);
// q
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger q = new BigInteger(1, buffer);
// e
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger e = new BigInteger(1, buffer);
// d
l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8
| (k[i++] & 0xFF);
buffer = new byte[l];
System.arraycopy(k, i, buffer, 0, l);
i += l;
BigInteger d = new BigInteger(1, buffer);
return new GnuRSAPrivateKey(p, q, e, d);
}
}
@@ -0,0 +1,248 @@
/* RSAKeyPairX509Codec.java -- X.509 Encoding/Decoding handler
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.key.rsa;
import gnu.java.security.OID;
import gnu.java.security.Registry;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import gnu.java.security.key.IKeyPairCodec;
import gnu.java.security.util.DerUtil;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidParameterException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.logging.Logger;
/**
* An implementation of an {@link IKeyPairCodec} that knows how to encode /
* decode X.509 ASN.1 external representation of RSA public keys.
*/
public class RSAKeyPairX509Codec
implements IKeyPairCodec
{
private static final Logger log = Logger.getLogger(RSAKeyPairX509Codec.class.getName());
private static final OID RSA_ALG_OID = new OID(Registry.RSA_OID_STRING);
// implicit 0-arguments constructor
public int getFormatID()
{
return X509_FORMAT;
}
/**
* Returns the X.509 ASN.1 <i>SubjectPublicKeyInfo</i> representation of an
* RSA public key. The ASN.1 specification, as defined in RFC-3280, and
* RFC-2459, is as follows:
*
* <pre>
* SubjectPublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
* subjectPublicKey BIT STRING
* }
*
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL
* }
* </pre>
* <p>
* As indicated in RFC-2459: "The parameters field shall have ASN.1 type NULL
* for this algorithm identifier.".
* <p>
* The <i>subjectPublicKey</i> field, which is a BIT STRING, contains the
* DER-encoded form of the RSA public key defined as:
*
* <pre>
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
* </pre>
*
* @param key the {@link PublicKey} instance to encode. MUST be an instance of
* {@link GnuRSAPublicKey}.
* @return the ASN.1 representation of the <i>SubjectPublicKeyInfo</i> in an
* X.509 certificate.
* @throw InvalidParameterException if <code>key</code> is not an instance
* of {@link GnuRSAPublicKey} or if an exception occurs during the
* marshalling process.
*/
public byte[] encodePublicKey(PublicKey key)
{
log.entering(this.getClass().getName(), "encodePublicKey()", key);
if (! (key instanceof GnuRSAPublicKey))
throw new InvalidParameterException("key");
DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, RSA_ALG_OID);
GnuRSAPublicKey rsaKey = (GnuRSAPublicKey) key;
BigInteger n = rsaKey.getN();
BigInteger e = rsaKey.getE();
DERValue derN = new DERValue(DER.INTEGER, n);
DERValue derE = new DERValue(DER.INTEGER, e);
ArrayList algorithmID = new ArrayList(1);
algorithmID.add(derOID);
DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
algorithmID);
ArrayList publicKey = new ArrayList(2);
publicKey.add(derN);
publicKey.add(derE);
DERValue derPublicKey = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
publicKey);
byte[] spkBytes = derPublicKey.getEncoded();
DERValue derSPK = new DERValue(DER.BIT_STRING, new BitString(spkBytes));
ArrayList spki = new ArrayList(2);
spki.add(derAlgorithmID);
spki.add(derSPK);
DERValue derSPKI = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, spki);
byte[] result;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try
{
DERWriter.write(baos, derSPKI);
result = baos.toByteArray();
}
catch (IOException x)
{
InvalidParameterException y = new InvalidParameterException();
y.initCause(x);
throw y;
}
log.exiting(this.getClass().getName(), "encodePublicKey()", result);
return result;
}
/**
* @throws InvalidParameterException ALWAYS.
*/
public byte[] encodePrivateKey(PrivateKey key)
{
throw new InvalidParameterException("Wrong format for private keys");
}
/**
* @param input the byte array to unmarshall into a valid RSA
* {@link PublicKey} instance. MUST NOT be null.
* @return a new instance of a {@link GnuRSAPublicKey} decoded from the
* <i>SubjectPublicKeyInfo</i> material in an X.509 certificate.
* @throw InvalidParameterException if an exception occurs during the
* unmarshalling process.
*/
public PublicKey decodePublicKey(byte[] input)
{
log.entering(this.getClass().getName(), "decodePublicKey()", input);
if (input == null)
throw new InvalidParameterException("Input bytes MUST NOT be null");
BigInteger n, e;
DERReader der = new DERReader(input);
try
{
DERValue derSPKI = der.read();
DerUtil.checkIsConstructed(derSPKI, "Wrong SubjectPublicKeyInfo field");
DERValue derAlgorithmID = der.read();
DerUtil.checkIsConstructed(derAlgorithmID, "Wrong AlgorithmIdentifier field");
DERValue derOID = der.read();
if (! (derOID.getValue() instanceof OID))
throw new InvalidParameterException("Wrong Algorithm field");
OID algOID = (OID) derOID.getValue();
if (! algOID.equals(RSA_ALG_OID))
throw new InvalidParameterException("Unexpected OID: " + algOID);
// rfc-2459 states that this field is OPTIONAL but NULL if/when present
DERValue val = der.read();
if (val.getTag() == DER.NULL)
val = der.read();
if (! (val.getValue() instanceof BitString))
throw new InvalidParameterException("Wrong SubjectPublicKey field");
byte[] spkBytes = ((BitString) val.getValue()).toByteArray();
der = new DERReader(spkBytes);
val = der.read();
DerUtil.checkIsConstructed(derAlgorithmID, "Wrong subjectPublicKey field");
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong modulus field");
n = (BigInteger) val.getValue();
val = der.read();
DerUtil.checkIsBigInteger(val, "Wrong publicExponent field");
e = (BigInteger) val.getValue();
}
catch (IOException x)
{
InvalidParameterException y = new InvalidParameterException();
y.initCause(x);
throw y;
}
PublicKey result = new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e);
log.exiting(this.getClass().getName(), "decodePublicKey()", result);
return result;
}
/**
* @throws InvalidParameterException ALWAYS.
*/
public PrivateKey decodePrivateKey(byte[] input)
{
throw new InvalidParameterException("Wrong format for private keys");
}
}
@@ -0,0 +1,199 @@
/* BasePRNG.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.prng;
import java.util.Map;
/**
* <p>An abstract class to facilitate implementing PRNG algorithms.</p>
*/
public abstract class BasePRNG implements IRandom
{
// Constants and variables
// -------------------------------------------------------------------------
/** The canonical name prefix of the PRNG algorithm. */
protected String name;
/** Indicate if this instance has already been initialised or not. */
protected boolean initialised;
/** A temporary buffer to serve random bytes. */
protected byte[] buffer;
/** The index into buffer of where the next byte will come from. */
protected int ndx;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* <p>Trivial constructor for use by concrete subclasses.</p>
*
* @param name the canonical name of this instance.
*/
protected BasePRNG(String name)
{
super();
this.name = name;
initialised = false;
buffer = new byte[0];
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// IRandom interface implementation ----------------------------------------
public String name()
{
return name;
}
public void init(Map attributes)
{
this.setup(attributes);
ndx = 0;
initialised = true;
}
public byte nextByte() throws IllegalStateException, LimitReachedException
{
if (!initialised)
{
throw new IllegalStateException();
}
return nextByteInternal();
}
public void nextBytes(byte[] out) throws IllegalStateException,
LimitReachedException
{
nextBytes(out, 0, out.length);
}
public void nextBytes(byte[] out, int offset, int length)
throws IllegalStateException, LimitReachedException
{
if (!initialised)
throw new IllegalStateException("not initialized");
if (length == 0)
return;
if (offset < 0 || length < 0 || offset + length > out.length)
throw new ArrayIndexOutOfBoundsException("offset=" + offset + " length="
+ length + " limit="
+ out.length);
if (ndx >= buffer.length)
{
fillBlock();
ndx = 0;
}
int count = 0;
while (count < length)
{
int amount = Math.min(buffer.length - ndx, length - count);
System.arraycopy(buffer, ndx, out, offset + count, amount);
count += amount;
ndx += amount;
if (ndx >= buffer.length)
{
fillBlock();
ndx = 0;
}
}
}
public void addRandomByte(byte b)
{
throw new UnsupportedOperationException("random state is non-modifiable");
}
public void addRandomBytes(byte[] buffer)
{
addRandomBytes(buffer, 0, buffer.length);
}
public void addRandomBytes(byte[] buffer, int offset, int length)
{
throw new UnsupportedOperationException("random state is non-modifiable");
}
// Instance methods
// -------------------------------------------------------------------------
public boolean isInitialised()
{
return initialised;
}
private byte nextByteInternal() throws LimitReachedException
{
if (ndx >= buffer.length)
{
this.fillBlock();
ndx = 0;
}
return buffer[ndx++];
}
// abstract methods to implement by subclasses -----------------------------
public Object clone() throws CloneNotSupportedException
{
BasePRNG result = (BasePRNG) super.clone();
if (this.buffer != null)
result.buffer = (byte[]) this.buffer.clone();
return result;
}
public abstract void setup(Map attributes);
public abstract void fillBlock() throws LimitReachedException;
}
@@ -0,0 +1,62 @@
/* EntropySource.java --
Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.prng;
/**
* A generic interface for adding random bytes to an entropy pool.
*/
public interface EntropySource
{
/**
* Returns the estimated quality of this source. This value should be
* between 0 and 100 (the running quality is computed as a percentage,
* 100 percent being perfect-quality).
*
* @return The quality.
*/
double quality();
/**
* Returns a new buffer with the next random bytes to add.
*
* @return The next random bytes.
*/
byte[] nextBytes();
}
@@ -0,0 +1,180 @@
/* IRandom.java --
Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.prng;
import java.util.Map;
/**
* <p>The basic visible methods of any pseudo-random number generator.</p>
*
* <p>The [HAC] defines a PRNG (as implemented in this library) as follows:</p>
*
* <ul>
* <li>"5.6 Definition: A pseudorandom bit generator (PRBG) is said to pass
* the <em>next-bit test</em> if there is no polynomial-time algorithm which,
* on input of the first <code>L</code> bits of an output sequence <code>S</code>,
* can predict the <code>(L+1)</code>st bit of <code>S</code> with a
* probability significantly grater than <code>1/2</code>."</li>
*
* <li>"5.8 Definition: A PRBG that passes the <em>next-bit test</em>
* (possibly under some plausible but unproved mathematical assumption such
* as the intractability of factoring integers) is called a
* <em>cryptographically secure pseudorandom bit generator</em> (CSPRBG)."</li>
* </ul>
*
* <p><b>IMPLEMENTATION NOTE</b>: Although all the concrete classes in this
* package implement the {@link Cloneable} interface, it is important to note
* here that such an operation, for those algorithms that use an underlting
* symmetric key block cipher, <b>DOES NOT</b> clone any session key material
* that may have been used in initialising the source PRNG (the instance to be
* cloned). Instead a clone of an already initialised PRNG, that uses and
* underlying symmetric key block cipher, is another instance with a clone of
* the same cipher that operates with the <b>same block size</b> but without any
* knowledge of neither key material nor key size.</p>
*
* <p>References:</p>
*
* <ol>
* <li><a href="http://www.cacr.math.uwaterloo.ca/hac">[HAC]</a>: Handbook of
* Applied Cryptography.<br>
* CRC Press, Inc. ISBN 0-8493-8523-7, 1997<br>
* Menezes, A., van Oorschot, P. and S. Vanstone.</li>
* </ol>
*/
public interface IRandom extends Cloneable
{
// Constants
// -------------------------------------------------------------------------
// Methods
// -------------------------------------------------------------------------
/**
* <p>Returns the canonical name of this instance.</p>
*
* @return the canonical name of this instance. */
String name();
/**
* <p>Initialises the pseudo-random number generator scheme with the
* appropriate attributes.</p>
*
* @param attributes a set of name-value pairs that describe the desired
* future instance behaviour.
* @exception IllegalArgumentException if at least one of the defined name/
* value pairs contains invalid data.
*/
void init(Map attributes);
/**
* <p>Returns the next 8 bits of random data generated from this instance.</p>
*
* @return the next 8 bits of random data generated from this instance.
* @exception IllegalStateException if the instance is not yet initialised.
* @exception LimitReachedException if this instance has reached its
* theoretical limit for generating non-repetitive pseudo-random data.
*/
byte nextByte() throws IllegalStateException, LimitReachedException;
/**
* <p>Fills the designated byte array, starting from byte at index
* <code>offset</code>, for a maximum of <code>length</code> bytes with the
* output of this generator instance.
*
* @param out the placeholder to contain the generated random bytes.
* @param offset the starting index in <i>out</i> to consider. This method
* does nothing if this parameter is not within <code>0</code> and
* <code>out.length</code>.
* @param length the maximum number of required random bytes. This method
* does nothing if this parameter is less than <code>1</code>.
* @exception IllegalStateException if the instance is not yet initialised.
* @exception LimitReachedException if this instance has reached its
* theoretical limit for generating non-repetitive pseudo-random data.
*/
void nextBytes(byte[] out, int offset, int length)
throws IllegalStateException, LimitReachedException;
/**
* <p>Supplement, or possibly replace, the random state of this PRNG with
* a random byte.</p>
*
* <p>Implementations are not required to implement this method in any
* meaningful way; this may be a no-operation, and implementations may
* throw an {@link UnsupportedOperationException}.</p>
*
* @param b The byte to add.
*/
void addRandomByte(byte b);
/**
* <p>Supplement, or possibly replace, the random state of this PRNG with
* a sequence of new random bytes.</p>
*
* <p>Implementations are not required to implement this method in any
* meaningful way; this may be a no-operation, and implementations may
* throw an {@link UnsupportedOperationException}.</p>
*
* @param in The buffer of new random bytes to add.
*/
void addRandomBytes(byte[] in);
/**
* <p>Supplement, or possibly replace, the random state of this PRNG with
* a sequence of new random bytes.</p>
*
* <p>Implementations are not required to implement this method in any
* meaningful way; this may be a no-operation, and implementations may
* throw an {@link UnsupportedOperationException}.</p>
*
* @param in The buffer of new random bytes to add.
* @param offset The offset from whence to begin reading random bytes.
* @param length The number of random bytes to add.
* @exception IndexOutOfBoundsException If <i>offset</i>, <i>length</i>,
* or <i>offset</i>+<i>length</i> is out of bounds.
*/
void addRandomBytes(byte[] in, int offset, int length);
/**
* <p>Returns a clone copy of this instance.</p>
*
* @return a clone copy of this instance.
*/
Object clone() throws CloneNotSupportedException;
}
@@ -0,0 +1,69 @@
/* LimitReachedException.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.prng;
/**
* A checked exception that indicates that a pseudo random number generated has
* reached its theoretical limit in generating random bytes.
*/
public class LimitReachedException extends Exception
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public LimitReachedException()
{
super();
}
public LimitReachedException(String msg)
{
super(msg);
}
// Class methods
// -------------------------------------------------------------------------
// Instant methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,135 @@
/* MDGenerator.java --
Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.prng;
import gnu.java.security.Registry;
import gnu.java.security.hash.HashFactory;
import gnu.java.security.hash.IMessageDigest;
import java.util.Map;
/**
* <p>A simple pseudo-random number generator that relies on a hash algorithm,
* that (a) starts its operation by hashing a <code>seed</code>, and then (b)
* continuously re-hashing its output. If no hash algorithm name is specified
* in the {@link Map} of attributes used to initialise the instance then the
* SHA-160 algorithm is used as the underlying hash function. Also, if no
* <code>seed</code> is given, an empty octet sequence is used.</p>
*/
public class MDGenerator extends BasePRNG implements Cloneable
{
// Constants and variables
// -------------------------------------------------------------------------
/** Property name of underlying hash algorithm for this generator. */
public static final String MD_NAME = "gnu.crypto.prng.md.hash.name";
/** Property name of seed material. */
public static final String SEEED = "gnu.crypto.prng.md.seed";
/** The underlying hash instance. */
private IMessageDigest md;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public MDGenerator()
{
super(Registry.MD_PRNG);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// Implementation of abstract methods in BaseRandom ------------------------
public void setup(Map attributes)
{
// find out which hash to use
String underlyingMD = (String) attributes.get(MD_NAME);
if (underlyingMD == null)
{
if (md == null)
{ // happy birthday
// ensure we have a reliable implementation of this hash
md = HashFactory.getInstance(Registry.SHA160_HASH);
}
else
{ // a clone. reset it for reuse
md.reset();
}
}
else
{ // ensure we have a reliable implementation of this hash
md = HashFactory.getInstance(underlyingMD);
}
// get the seeed
byte[] seed = (byte[]) attributes.get(SEEED);
if (seed == null)
{
seed = new byte[0];
}
md.update(seed, 0, seed.length);
}
public void fillBlock() throws LimitReachedException
{
IMessageDigest mdc = (IMessageDigest) md.clone();
buffer = mdc.digest();
md.update(buffer, 0, buffer.length);
}
// Cloneable interface implementation ---------------------------------------
public Object clone() throws CloneNotSupportedException
{
MDGenerator result = (MDGenerator) super.clone();
if (this.md != null)
result.md = (IMessageDigest) this.md.clone();
return result;
}
}
@@ -0,0 +1,109 @@
/* PRNGFactory.java --
Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.prng;
import gnu.java.security.Registry;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* <p>A Factory to instantiate pseudo random number generators.</p>
*/
public class PRNGFactory implements Registry
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial constructor to enforce <i>Singleton</i> pattern. */
protected PRNGFactory()
{
}
// Class methods
// -------------------------------------------------------------------------
/**
* <p>Returns an instance of a padding algorithm given its name.</p>
*
* @param prng the case-insensitive name of the PRNG.
* @return an instance of the pseudo-random number generator.
* @exception InternalError if the implementation does not pass its self-
* test.
*/
public static final IRandom getInstance(String prng)
{
if (prng == null)
{
return null;
}
prng = prng.trim();
IRandom result = null;
if (prng.equalsIgnoreCase(MD_PRNG))
{
result = new MDGenerator();
}
return result;
}
/**
* <p>Returns a {@link Set} of names of padding algorithms supported by this
* <i>Factory</i>.</p>
*
* @return a {@link Set} of pseudo-random number generator algorithm names
* (Strings).
*/
public static final Set getNames()
{
HashSet hs = new HashSet();
hs.add(MD_PRNG);
return Collections.unmodifiableSet(hs);
}
// Instance methods
// -------------------------------------------------------------------------
}
@@ -0,0 +1,82 @@
/* RandomEvent.java -- an event with random data.
Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.prng;
import java.util.EventObject;
/**
* An interface for entropy accumulators that will be notified of random
* events.
*/
public class RandomEvent extends EventObject
{
private final byte sourceNumber;
private final byte poolNumber;
private final byte[] data;
public RandomEvent(Object source, byte sourceNumber, byte poolNumber,
byte[] data)
{
super(source);
this.sourceNumber = sourceNumber;
this.poolNumber = poolNumber;
if (data.length == 0 || data.length > 32)
throw new IllegalArgumentException(
"random events take between 1 and 32 bytes of data");
this.data = (byte[]) data.clone();
}
public byte getSourceNumber()
{
return sourceNumber;
}
public byte getPoolNumber()
{
return poolNumber;
}
public byte[] getData()
{
return data;
}
}
@@ -0,0 +1,50 @@
/* RandomEventListener.java --
Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is a part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.prng;
import java.util.EventListener;
/**
* An interface for entropy accumulators that will be notified of random
* events.
*/
public interface RandomEventListener extends EventListener
{
void addRandomEvent(RandomEvent event);
}
@@ -1,134 +0,0 @@
/* DSAKeyFactory.java -- DSA key factory.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactorySpi;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
/**
* DSA key factory.
*
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class DSAKeyFactory extends KeyFactorySpi
{
// Constructor.
// ------------------------------------------------------------------------
public DSAKeyFactory()
{
super();
}
// Instance methods.
// ------------------------------------------------------------------------
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException
{
if (!(keySpec instanceof DSAPrivateKeySpec))
throw new InvalidKeySpecException();
return new GnuDSAPrivateKey(
((DSAPrivateKeySpec) keySpec).getX(),
((DSAPrivateKeySpec) keySpec).getP(),
((DSAPrivateKeySpec) keySpec).getQ(),
((DSAPrivateKeySpec) keySpec).getG());
}
protected PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException
{
if (!(keySpec instanceof DSAPublicKeySpec))
throw new InvalidKeySpecException();
return new GnuDSAPublicKey(
((DSAPublicKeySpec) keySpec).getY(),
((DSAPublicKeySpec) keySpec).getP(),
((DSAPublicKeySpec) keySpec).getQ(),
((DSAPublicKeySpec) keySpec).getG());
}
protected KeySpec engineGetKeySpec(Key key, Class keySpec)
throws InvalidKeySpecException
{
if ((key instanceof DSAPublicKey) &&
keySpec.isAssignableFrom(DSAPublicKeySpec.class))
{
return new DSAPublicKeySpec(((DSAPublicKey) key).getY(),
((DSAPublicKey) key).getParams().getP(),
((DSAPublicKey) key).getParams().getQ(),
((DSAPublicKey) key).getParams().getG());
}
if ((key instanceof DSAPrivateKey) &&
keySpec.isAssignableFrom(DSAPrivateKeySpec.class))
{
return new DSAPrivateKeySpec(((DSAPrivateKey) key).getX(),
((DSAPrivateKey) key).getParams().getP(),
((DSAPrivateKey) key).getParams().getQ(),
((DSAPrivateKey) key).getParams().getG());
}
throw new InvalidKeySpecException();
}
protected Key engineTranslateKey(Key key) throws InvalidKeyException
{
if ((key instanceof GnuDSAPublicKey) || (key instanceof GnuDSAPrivateKey))
return key;
if (key instanceof DSAPublicKey)
return new GnuDSAPublicKey(((DSAPublicKey) key).getY(),
((DSAPublicKey) key).getParams().getP(),
((DSAPublicKey) key).getParams().getQ(),
((DSAPublicKey) key).getParams().getG());
if (key instanceof DSAPrivateKey)
return new GnuDSAPrivateKey(((DSAPrivateKey) key).getX(),
((DSAPrivateKey) key).getParams().getP(),
((DSAPrivateKey) key).getParams().getQ(),
((DSAPrivateKey) key).getParams().getG());
throw new InvalidKeyException();
}
}
@@ -1,194 +0,0 @@
/* GnuDSAKeyPairGenerator.java --- Gnu DSA Key Pair Generator
Copyright (C) 1999, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import java.math.BigInteger;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidParameterException;
import java.security.KeyPair;
import java.security.KeyPairGeneratorSpi;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.DSAParams;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.DSAParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.util.Random;
public class DSAKeyPairGenerator extends KeyPairGeneratorSpi
implements java.security.interfaces.DSAKeyPairGenerator
{
int keysize;
SecureRandom random;
private BigInteger q = null; // the small prime
private BigInteger p = null; // the big prime
private BigInteger g = null;
public DSAKeyPairGenerator()
{
keysize = 1024;
getDefaults ();
}
public void initialize(int keysize, SecureRandom random)
{
initialize (keysize, false, random);
}
public void initialize(AlgorithmParameterSpec params,
SecureRandom random)
throws InvalidAlgorithmParameterException
{
if( !( params instanceof DSAParameterSpec ) )
throw new InvalidAlgorithmParameterException("Must be DSAParameterSpec");
try
{
initialize ((DSAParams) params, random);
}
catch (InvalidParameterException ipe)
{
InvalidAlgorithmParameterException iape =
new InvalidAlgorithmParameterException();
iape.initCause (ipe);
throw iape;
}
}
public void initialize (DSAParams params, SecureRandom random)
{
DSAParameterSpec dsaparameterspec = (DSAParameterSpec)params;
if (dsaparameterspec.getP() == null
|| dsaparameterspec.getQ() == null
|| dsaparameterspec.getG() == null)
{
throw new InvalidParameterException ("none of p, q, or g may be null");
}
p = dsaparameterspec.getP();
q = dsaparameterspec.getQ();
g = dsaparameterspec.getG();
this.random = random;
}
public void initialize(int modlen, boolean genParams, SecureRandom random)
throws InvalidParameterException
{
if( ((modlen % 64) != 0) || (modlen < 512) || (modlen > 1024) )
throw new InvalidParameterException();
this.keysize = modlen;
this.random = random;
if (this.random == null)
{
this.random = new SecureRandom ();
}
if (genParams)
{
try
{
AlgorithmParameterGenerator apgDSA = AlgorithmParameterGenerator.getInstance("DSA");
apgDSA.init (modlen, random);
AlgorithmParameters apDSA = apgDSA.generateParameters();
DSAParameterSpec dsaparameterspec = (DSAParameterSpec)apDSA.getParameterSpec( DSAParameterSpec.class );
p = dsaparameterspec.getP();
q = dsaparameterspec.getQ();
g = dsaparameterspec.getG();
}
catch (NoSuchAlgorithmException nsae)
{
InvalidParameterException ipe =
new InvalidParameterException ("can't generate DSA parameters");
ipe.initCause (nsae);
throw ipe;
}
catch (InvalidParameterSpecException ipse)
{
InvalidParameterException ipe =
new InvalidParameterException ("can't generate DSA parameters");
ipe.initCause (ipse);
throw ipe;
}
}
else if (!getDefaults ())
{
throw new InvalidParameterException ("unsupported key size: " + modlen);
}
}
public KeyPair generateKeyPair()
{
if (random == null)
{
random = new SecureRandom ();
}
BigInteger x = new BigInteger( 159, random );
BigInteger y = g.modPow( x, p );
return new KeyPair( new GnuDSAPublicKey(y,p,q,g), new GnuDSAPrivateKey(x,p,q,g));
//return new KeyPair( public, private );
}
//These constants are Sun's Constants copied from the
//Cryptography Specification
private boolean getDefaults()
{
if( keysize == 512) {
p = new BigInteger("fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17", 16);
q = new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16);
g = new BigInteger("678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4", 16);
return true;
} else if( keysize == 768) {
p = new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45ee3688c11a8c56ab127a3daf", 16);
q = new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16);
g = new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d3668445771f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a7064f316933a346d3f529252", 16);
return true;
} else if( keysize == 1024) {
p = new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16);
q = new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16);
g = new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16);
return true;
}
return false;
}
}
@@ -1,150 +0,0 @@
/* DSAParameters.java --- DSA Parameters Implementation
Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import gnu.java.io.ASN1ParsingException;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.AlgorithmParametersSpi;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.DSAParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.util.ArrayList;
/*
ASN.1 Encoding for DSA from rfc2459
id-dsa ID ::= { iso(1) member-body(2) us(840) x9-57(10040)
x9cm(4) 1 }
Dss-Parms ::= SEQUENCE {
p INTEGER,
q INTEGER,
g INTEGER }
*/
public class DSAParameters extends AlgorithmParametersSpi
{
private BigInteger q; // the small prime
private BigInteger p; // the big prime
private BigInteger g;
public void engineInit(AlgorithmParameterSpec paramSpec)
throws InvalidParameterSpecException
{
if( paramSpec instanceof DSAParameterSpec ) {
DSAParameterSpec dsaParamSpec = (DSAParameterSpec)paramSpec;
p = dsaParamSpec.getP();
q = dsaParamSpec.getQ();
g = dsaParamSpec.getG();
}
else
throw new InvalidParameterSpecException("Only accepts DSAParameterSpec");
}
public void engineInit(byte[] params)
throws IOException
{
DERReader in = new DERReader(params);
DERValue val = in.read();
if (val.getValue() != DER.CONSTRUCTED_VALUE)
throw new ASN1ParsingException("badly formed parameters");
try
{
p = (BigInteger) in.read().getValue();
q = (BigInteger) in.read().getValue();
g = (BigInteger) in.read().getValue();
}
catch (Exception x)
{
throw new ASN1ParsingException("badly formed parameters");
}
}
public void engineInit(byte[] params, String format)
throws IOException
{
if( !format.equals("ASN.1") )
throw new IOException("Invalid Format: Only accepts ASN.1");
engineInit( params );
}
public AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec)
throws InvalidParameterSpecException
{
if( paramSpec.isAssignableFrom(DSAParameterSpec.class) )
return new DSAParameterSpec(p, q, g);
else
throw new InvalidParameterSpecException("Only accepts DSAParameterSpec");
}
public byte[] engineGetEncoded()
throws IOException
{
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ArrayList seq = new ArrayList(3);
seq.add(new DERValue(DER.INTEGER, p));
seq.add(new DERValue(DER.INTEGER, q));
seq.add(new DERValue(DER.INTEGER, g));
DERWriter.write(bout, new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, seq));
return bout.toByteArray();
}
public byte[] engineGetEncoded(String format)
throws IOException
{
if( !format.equals("ASN.1") )
throw new IOException("Invalid Format: Only accepts ASN.1");
return engineGetEncoded();
}
public String engineToString()
{
return ("q: " + q + " p: " + p + " g: " + g);
}
}
@@ -1,251 +0,0 @@
/* DSASignature.java --
Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.SignatureSpi;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.util.ArrayList;
import java.util.Random;
public class DSASignature extends SignatureSpi
{
private DSAPublicKey publicKey;
private DSAPrivateKey privateKey;
private final MessageDigest digest;
private final SecureRandom random;
public DSASignature() throws NoSuchAlgorithmException
{
random = new SecureRandom();
digest = MessageDigest.getInstance ("SHA1");
}
private void init()
{
digest.reset();
}
public void engineInitVerify (PublicKey publicKey)
throws InvalidKeyException
{
if (publicKey instanceof DSAPublicKey)
this.publicKey = (DSAPublicKey) publicKey;
else
throw new InvalidKeyException();
init();
}
public void engineInitSign (PrivateKey privateKey)
throws InvalidKeyException
{
if (privateKey instanceof DSAPrivateKey)
this.privateKey = (DSAPrivateKey) privateKey;
else
throw new InvalidKeyException ("not a DSA private key");
init();
}
public void engineInitSign (PrivateKey privateKey,
SecureRandom random)
throws InvalidKeyException
{
if (privateKey instanceof DSAPrivateKey)
this.privateKey = (DSAPrivateKey) privateKey;
else
throw new InvalidKeyException ("not a DSA private key");
appRandom = random;
init();
}
public void engineUpdate(byte b)
throws SignatureException
{
digest.update (b);
}
public void engineUpdate (byte[] b, int off, int len)
throws SignatureException
{
digest.update (b, off, len);
}
public byte[] engineSign() throws SignatureException
{
if (privateKey == null)
throw new SignatureException ("not initialized for signing");
try
{
BigInteger g = privateKey.getParams().getG();
BigInteger p = privateKey.getParams().getP();
BigInteger q = privateKey.getParams().getQ();
BigInteger x = privateKey.getX();
BigInteger k = new BigInteger (159, appRandom != null ? appRandom : random);
BigInteger r = g.modPow(k, p);
r = r.mod(q);
byte bytes[] = digest.digest();
BigInteger sha = new BigInteger (1, bytes);
BigInteger s = sha.add (x.multiply (r));
s = s.multiply (k.modInverse(q)).mod (q);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ArrayList seq = new ArrayList (2);
seq.add(0, new DERValue (DER.INTEGER, r));
seq.add(1, new DERValue (DER.INTEGER, s));
DERWriter.write (bout, new DERValue (DER.CONSTRUCTED | DER.SEQUENCE, seq));
return bout.toByteArray();
}
catch (IOException ioe)
{
SignatureException se = new SignatureException();
se.initCause (ioe);
throw se;
}
catch (ArithmeticException ae)
{
SignatureException se = new SignatureException();
se.initCause (ae);
throw se;
}
}
public int engineSign (byte[] outbuf, int offset, int len)
throws SignatureException
{
byte tmp[] = engineSign();
if (tmp.length > len)
throw new SignatureException ("output buffer too short");
System.arraycopy (tmp, 0, outbuf, offset, tmp.length);
return tmp.length;
}
public boolean engineVerify (byte[] sigBytes)
throws SignatureException
{
// Decode sigBytes from ASN.1 DER encoding
try
{
DERReader in = new DERReader (sigBytes);
DERValue val = in.read();
if (!val.isConstructed())
throw new SignatureException ("badly formed signature");
BigInteger r = (BigInteger) in.read().getValue();
BigInteger s = (BigInteger) in.read().getValue();
BigInteger g = publicKey.getParams().getG();
BigInteger p = publicKey.getParams().getP();
BigInteger q = publicKey.getParams().getQ();
BigInteger y = publicKey.getY();
BigInteger w = s.modInverse (q);
byte bytes[] = digest.digest();
BigInteger sha = new BigInteger (1, bytes);
BigInteger u1 = w.multiply (sha).mod ( q );
BigInteger u2 = r.multiply (w).mod(q);
BigInteger v = g.modPow (u1, p).multiply (y.modPow (u2, p)).mod (p).mod (q);
if (v.equals (r))
return true;
else
return false;
}
catch (IOException ioe)
{
SignatureException se = new SignatureException ("badly formed signature");
se.initCause (ioe);
throw se;
}
}
public void engineSetParameter (String param,
Object value)
throws InvalidParameterException
{
throw new InvalidParameterException();
}
public void engineSetParameter (AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException
{
throw new InvalidParameterException();
}
public Object engineGetParameter (String param)
throws InvalidParameterException
{
throw new InvalidParameterException();
}
public Object clone() throws CloneNotSupportedException
{
return super.clone();
}
}
@@ -1,123 +0,0 @@
/* DiffieHellmanKeyFactoryImpl.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import gnu.javax.crypto.GnuDHPrivateKey;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactorySpi;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHPrivateKeySpec;
import javax.crypto.spec.DHPublicKeySpec;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
public class DiffieHellmanKeyFactoryImpl extends KeyFactorySpi
{
protected PrivateKey engineGeneratePrivate (final KeySpec spec)
throws InvalidKeySpecException
{
if (spec instanceof DHPrivateKeySpec)
{
DHPrivateKeySpec dh = (DHPrivateKeySpec) spec;
return new GnuDHPrivateKey (dh.getX (),
new DHParameterSpec (dh.getP (), dh.getG ()));
}
throw new InvalidKeySpecException ();
}
protected PublicKey engineGeneratePublic (final KeySpec spec)
throws InvalidKeySpecException
{
if (spec instanceof DHPublicKeySpec)
{
DHPublicKeySpec dh = (DHPublicKeySpec) spec;
return new GnuDHPublicKey (new DHParameterSpec (dh.getP (), dh.getG ()),
dh.getY(), null);
}
throw new InvalidKeySpecException ();
}
protected KeySpec engineGetKeySpec (final Key key, final Class specClass)
throws InvalidKeySpecException
{
if (key instanceof DHPrivateKey)
{
if (DHPrivateKeySpec.class.isAssignableFrom (specClass))
{
DHParameterSpec params = ((DHPrivateKey) key).getParams ();
return new DHPrivateKeySpec (((DHPrivateKey) key).getX (),
params.getP (), params.getG ());
}
}
if (key instanceof DHPublicKey)
{
if (DHPublicKeySpec.class.isAssignableFrom (specClass))
{
DHParameterSpec params = ((DHPublicKey) key).getParams ();
return new DHPublicKeySpec (((DHPublicKey) key).getY (),
params.getP (), params.getG ());
}
}
throw new InvalidKeySpecException ();
}
protected Key engineTranslateKey (final Key key)
throws InvalidKeyException
{
if (key instanceof DHPrivateKey)
{
return new GnuDHPrivateKey (((DHPrivateKey) key).getX (),
((DHPrivateKey) key).getParams ());
}
if (key instanceof DHPublicKey)
{
return new GnuDHPublicKey (((DHPublicKey) key).getParams (),
((DHPublicKey) key).getY (), null);
}
throw new InvalidKeyException ();
}
}
@@ -1,303 +0,0 @@
/* EncodedKeyFactory.java -- encoded key factory.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import gnu.java.security.OID;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;
import java.io.IOException;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactorySpi;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.DSAParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.spec.DHParameterSpec;
/**
* A factory for keys encoded in either the X.509 format (for public
* keys) or the PKCS#8 format (for private keys).
*
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class EncodedKeyFactory extends KeyFactorySpi
{
// Constants.
// ------------------------------------------------------------------------
private static final OID ID_DSA = new OID("1.2.840.10040.4.1");
private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1");
private static final OID ID_DH = new OID("1.2.840.10046.2.1");
// Instance methods.
// ------------------------------------------------------------------------
public PublicKey engineGeneratePublic(KeySpec spec)
throws InvalidKeySpecException
{
if (!(spec instanceof X509EncodedKeySpec))
throw new InvalidKeySpecException("only supports X.509 key specs");
DERReader der = new DERReader(((X509EncodedKeySpec) spec).getEncoded());
try
{
DERValue spki = der.read();
if (!spki.isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
DERValue alg = der.read();
if (!alg.isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
DERValue val = der.read();
if (!(val.getValue() instanceof OID))
{
throw new InvalidKeySpecException("malformed encoded key");
}
OID algId = (OID) val.getValue();
byte[] algParams = null;
if (alg.getLength() > val.getEncodedLength())
{
val = der.read();
algParams = val.getEncoded();
if (val.isConstructed())
der.skip(val.getLength());
}
val = der.read();
if (!(val.getValue() instanceof BitString))
{
throw new InvalidKeySpecException("malformed encoded key");
}
byte[] publicKey = ((BitString) val.getValue()).toByteArray();
if (algId.equals(ID_DSA))
{
BigInteger p = null, g = null, q = null, Y;
if (algParams != null)
{
DERReader dsaParams = new DERReader(algParams);
val = dsaParams.read();
if (!val.isConstructed())
throw new InvalidKeySpecException("malformed DSA parameters");
val = dsaParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DSA parameters");
p = (BigInteger) val.getValue();
val = dsaParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DSA parameters");
q = (BigInteger) val.getValue();
val = dsaParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DSA parameters");
g = (BigInteger) val.getValue();
}
DERReader dsaPub = new DERReader(publicKey);
val = dsaPub.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DSA parameters");
Y = (BigInteger) val.getValue();
return new GnuDSAPublicKey(Y, p, q, g);
}
else if (algId.equals(ID_RSA))
{
DERReader rsaParams = new DERReader(publicKey);
if (!rsaParams.read().isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
return new GnuRSAPublicKey(new RSAPublicKeySpec(
(BigInteger) rsaParams.read().getValue(),
(BigInteger) rsaParams.read().getValue()));
}
else if (algId.equals(ID_DH))
{
if (algParams == null)
throw new InvalidKeySpecException("missing DH parameters");
DERReader dhParams = new DERReader(algParams);
val = dhParams.read();
BigInteger p, g, q, Y;
if (!val.isConstructed())
throw new InvalidKeySpecException("malformed DH parameters");
val = dhParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DH parameters");
p = (BigInteger) val.getValue();
val = dhParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DH parameters");
g = (BigInteger) val.getValue();
val = dhParams.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DH parameters");
q = (BigInteger) val.getValue();
DERReader dhPub = new DERReader(publicKey);
val = dhPub.read();
if (!(val.getValue() instanceof BigInteger))
throw new InvalidKeySpecException("malformed DH parameters");
Y = (BigInteger) val.getValue();
return (PublicKey) new GnuDHPublicKey(new DHParameterSpec(p, g), Y, q);
}
else
throw new InvalidKeySpecException("unknown algorithm: " + algId);
}
catch (IOException ioe)
{
throw new InvalidKeySpecException(ioe.getMessage());
}
}
public PrivateKey engineGeneratePrivate(KeySpec spec)
throws InvalidKeySpecException
{
if (!(spec instanceof PKCS8EncodedKeySpec))
{
throw new InvalidKeySpecException("only supports PKCS8 key specs");
}
DERReader der = new DERReader(((PKCS8EncodedKeySpec) spec).getEncoded());
try
{
DERValue pki = der.read();
if (!pki.isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
DERValue val = der.read();
if (!(val.getValue() instanceof BigInteger))
{
throw new InvalidKeySpecException("malformed encoded key");
}
DERValue alg = der.read();
if (!alg.isConstructed())
{
throw new InvalidKeySpecException("malformed encoded key");
}
val = der.read();
if (!(val.getValue() instanceof OID))
{
throw new InvalidKeySpecException("malformed encoded key");
}
OID algId = (OID) val.getValue();
byte[] algParams = null;
if (alg.getLength() > val.getEncodedLength())
{
val = der.read();
algParams = val.getEncoded();
if (val.isConstructed())
der.skip(val.getLength());
}
byte[] privateKey = (byte[]) der.read().getValue();
if (algId.equals(ID_DSA))
{
if (algParams == null)
{
throw new InvalidKeySpecException("missing DSA parameters");
}
AlgorithmParameters params = AlgorithmParameters.getInstance("DSA");
params.init(algParams);
DSAParameterSpec dsaSpec = (DSAParameterSpec)
params.getParameterSpec(DSAParameterSpec.class);
DERReader dsaPriv = new DERReader(privateKey);
return new GnuDSAPrivateKey((BigInteger) dsaPriv.read().getValue(),
dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG());
}
else if (algId.equals(ID_RSA))
{
DERReader rsaParams = new DERReader(privateKey);
if (!rsaParams.read().isConstructed())
throw new InvalidKeySpecException("malformed encoded key");
return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec(
(BigInteger) rsaParams.read().getValue(), // n
(BigInteger) rsaParams.read().getValue(), // e
(BigInteger) rsaParams.read().getValue(), // d
(BigInteger) rsaParams.read().getValue(), // p
(BigInteger) rsaParams.read().getValue(), // q
(BigInteger) rsaParams.read().getValue(), // d mod (p - 1)
(BigInteger) rsaParams.read().getValue(), // d mod (q - 1)
(BigInteger) rsaParams.read().getValue())); // (inv q) mod p
}
else
throw new InvalidKeySpecException("unknown algorithm: " + algId);
}
catch (InvalidParameterSpecException iapse)
{
throw new InvalidKeySpecException(iapse.getMessage());
}
catch (NoSuchAlgorithmException nsae)
{
throw new InvalidKeySpecException(nsae.getMessage());
}
catch (IOException ioe)
{
throw new InvalidKeySpecException(ioe.getMessage());
}
}
public KeySpec engineGetKeySpec(Key key, Class speClass)
throws InvalidKeySpecException
{
if ((key instanceof PrivateKey) && key.getFormat().equals("PKCS#8")
&& speClass.isAssignableFrom(PKCS8EncodedKeySpec.class))
return new PKCS8EncodedKeySpec(key.getEncoded());
else if ((key instanceof PublicKey) && key.getFormat().equals("X.509")
&& speClass.isAssignableFrom(X509EncodedKeySpec.class))
return new X509EncodedKeySpec(key.getEncoded());
else
throw new InvalidKeySpecException();
}
public Key engineTranslateKey(Key key) throws InvalidKeyException
{
throw new InvalidKeyException("translating keys not supported");
}
}
@@ -57,105 +57,209 @@ public final class Gnu extends Provider
// we automatically get all the implementation classes.
// Signature
put("Signature.SHA1withDSA",
gnu.java.security.provider.DSASignature.class.getName());
put("Signature.SHA160withDSS",
gnu.java.security.jce.sig.SHA160withDSS.class.getName());
put("Alg.Alias.Signature.SHA1withDSA", "SHA160withDSS");
put("Alg.Alias.Signature.DSS", "SHA160withDSS");
put("Alg.Alias.Signature.DSA", "SHA160withDSS");
put("Alg.Alias.Signature.SHAwithDSA", "SHA160withDSS");
put("Alg.Alias.Signature.DSAwithSHA", "SHA160withDSS");
put("Alg.Alias.Signature.DSAwithSHA1", "SHA160withDSS");
put("Alg.Alias.Signature.SHA/DSA", "SHA160withDSS");
put("Alg.Alias.Signature.SHA-1/DSA", "SHA160withDSS");
put("Alg.Alias.Signature.SHA1/DSA", "SHA160withDSS");
put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", "SHA160withDSS");
put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA160withDSS");
put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA160withDSS");
put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA160withDSS");
put("Alg.Alias.Signature.DSS", "SHA1withDSA");
put("Alg.Alias.Signature.DSA", "SHA1withDSA");
put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA");
put("Alg.Alias.Signature.DSAwithSHA", "SHA1withDSA");
put("Alg.Alias.Signature.DSAwithSHA1", "SHA1withDSA");
put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA");
put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA");
put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", "SHA1withDSA");
put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA");
put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA");
put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA");
put("Signature.MD2withRSA", MD2withRSA.class.getName());
put("Signature.MD2withRSA",
gnu.java.security.jce.sig.MD2withRSA.class.getName());
put("Signature.MD2withRSA ImplementedIn", "Software");
put("Alg.Alias.Signature.md2WithRSAEncryption", "MD2withRSA");
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.2", "MD2withRSA");
put("Alg.Alias.Signature.1.2.840.113549.1.1.2", "MD2withRSA");
put("Signature.MD4withRSA", MD4withRSA.class.getName());
put("Signature.MD4withRSA ImplementedIn", "Software");
put("Alg.Alias.Signature.md4WithRSAEncryption", "MD4withRSA");
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.3", "MD4withRSA");
put("Alg.Alias.Signature.1.2.840.113549.1.1.3", "MD4withRSA");
put("Signature.MD5withRSA", MD5withRSA.class.getName());
put("Signature.MD5withRSA",
gnu.java.security.jce.sig.MD5withRSA.class.getName());
put("Signature.MD5withRSA ImplementedIn", "Software");
put("Alg.Alias.Signature.md5WithRSAEncryption", "MD5withRSA");
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4", "MD5withRSA");
put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA");
put("Signature.SHA1withRSA", SHA1withRSA.class.getName());
put("Signature.SHA1withRSA ImplementedIn", "Software");
put("Alg.Alias.Signature.sha-1WithRSAEncryption", "SHA1withRSA");
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "SHA1withRSA");
put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA");
put("Signature.SHA160withRSA",
gnu.java.security.jce.sig.SHA160withRSA.class.getName());
put("Signature.SHA160withRSA ImplementedIn", "Software");
put("Alg.Alias.Signature.sha-1WithRSAEncryption", "SHA160withRSA");
put("Alg.Alias.Signature.sha-160WithRSAEncryption", "SHA160withRSA");
put("Alg.Alias.Signature.sha1WithRSAEncryption", "SHA160withRSA");
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "SHA160withRSA");
put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA160withRSA");
put("Alg.Alias.Signature.SHA1withRSA", "SHA160withRSA");
put("Signature.SHA256withRSA",
gnu.java.security.jce.sig.SHA256withRSA.class.getName());
put("Signature.SHA160withRSA ImplementedIn", "Software");
put("Alg.Alias.Signature.sha256WithRSAEncryption", "SHA256withRSA");
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.11", "SHA256withRSA");
put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256withRSA");
put("Signature.SHA384withRSA",
gnu.java.security.jce.sig.SHA384withRSA.class.getName());
put("Signature.SHA160withRSA ImplementedIn", "Software");
put("Alg.Alias.Signature.sha384WithRSAEncryption", "SHA384withRSA");
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.12", "SHA384withRSA");
put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384withRSA");
put("Signature.SHA512withRSA",
gnu.java.security.jce.sig.SHA512withRSA.class.getName());
put("Signature.SHA160withRSA ImplementedIn", "Software");
put("Alg.Alias.Signature.sha512WithRSAEncryption", "SHA512withRSA");
put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA");
put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA");
put("Signature.DSS/RAW",
gnu.java.security.jce.sig.DSSRawSignatureSpi.class.getName());
put("Signature.DSS/RAW KeySize", "1024");
put("Signature.DSS/RAW ImplementedIn", "Software");
put("Signature.RSA-PSS/RAW",
gnu.java.security.jce.sig.RSAPSSRawSignatureSpi.class.getName());
put("Signature.RSA-PSS/RAW KeySize", "1024");
put("Signature.RSA-PSS/RAW ImplementedIn", "Software");
// Key Pair Generator
put("KeyPairGenerator.DSA",
gnu.java.security.provider.DSAKeyPairGenerator.class.getName());
put("KeyPairGenerator.DiffieHellman", DiffieHellmanKeyPairGeneratorImpl.class.getName ());
put("KeyPairGenerator.DSS",
gnu.java.security.jce.sig.DSSKeyPairGeneratorSpi.class.getName());
put("KeyPairGenerator.DSS KeySize", "1024");
put("KeyPairGenerator.DSS ImplementedIn", "Software");
put("Alg.Alias.KeyPairGenerator.DSA", "DSS");
put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSS");
put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSS");
put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSS");
put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA");
put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA");
put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA");
put("Alg.Alias.KeyPairGenerator.DH", "DiffieHellman");
put("KeyPairGenerator.RSA",
gnu.java.security.jce.sig.RSAKeyPairGeneratorSpi.class.getName());
put("KeyPairGenerator.RSA KeySize", "1024");
put("KeyPairGenerator.RSA ImplementedIn", "Software");
// Key Factory
put("KeyFactory.DSA",
gnu.java.security.provider.DSAKeyFactory.class.getName());
put("KeyFactory.DSS",
gnu.java.security.jce.sig.DSSKeyFactory.class.getName());
put("Alg.Alias.KeyFactory.DSA", "DSS");
put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSS");
put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSS");
put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSS");
put("KeyFactory.Encoded", EncodedKeyFactory.class.getName());
put("KeyFactory.RSA",
gnu.java.security.jce.sig.RSAKeyFactory.class.getName());
put("KeyFactory.Encoded",
gnu.java.security.jce.sig.EncodedKeyFactory.class.getName());
put("KeyFactory.Encoded ImplementedIn", "Software");
put("Alg.Alias.KeyFactory.X.509", "Encoded");
put("Alg.Alias.KeyFactory.X509", "Encoded");
put("Alg.Alias.KeyFactory.PKCS#8", "Encoded");
put("Alg.Alias.KeyFactory.PKCS8", "Encoded");
put("KeyFactory.RSA", RSAKeyFactory.class.getName());
put("MessageDigest.HAVAL", gnu.java.security.jce.hash.HavalSpi.class.getName());
put("MessageDigest.HAVAL ImplementedIn", "Software");
put("MessageDigest.MD2", gnu.java.security.jce.hash.MD2Spi.class.getName());
put("MessageDigest.MD2 ImplementedIn", "Software");
put("MessageDigest.MD4", gnu.java.security.jce.hash.MD4Spi.class.getName());
put("MessageDigest.MD4 ImplementedIn", "Software");
put("MessageDigest.MD5", gnu.java.security.jce.hash.MD5Spi.class.getName());
put("MessageDigest.MD5 ImplementedIn", "Software");
put("MessageDigest.RIPEMD128", gnu.java.security.jce.hash.RipeMD128Spi.class.getName());
put("MessageDigest.RIPEMD128 ImplementedIn", "Software");
put("MessageDigest.RIPEMD160", gnu.java.security.jce.hash.RipeMD160Spi.class.getName());
put("MessageDigest.RIPEMD160 ImplementedIn", "Software");
put("MessageDigest.SHA-160", gnu.java.security.jce.hash.Sha160Spi.class.getName());
put("MessageDigest.SHA-160 ImplementedIn", "Software");
put("MessageDigest.SHA-256", gnu.java.security.jce.hash.Sha256Spi.class.getName());
put("MessageDigest.SHA-256 ImplementedIn", "Software");
put("MessageDigest.SHA-384", gnu.java.security.jce.hash.Sha384Spi.class.getName());
put("MessageDigest.SHA-384 ImplementedIn", "Software");
put("MessageDigest.SHA-512", gnu.java.security.jce.hash.Sha512Spi.class.getName());
put("MessageDigest.SHA-512 ImplementedIn", "Software");
put("MessageDigest.TIGER", gnu.java.security.jce.hash.TigerSpi.class.getName());
put("MessageDigest.TIGER ImplementedIn", "Software");
put("MessageDigest.WHIRLPOOL", gnu.java.security.jce.hash.WhirlpoolSpi.class.getName());
put("MessageDigest.WHIRLPOOL ImplementedIn", "Software");
put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSA");
put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA");
put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA");
put("KeyFactory.DiffieHellman", DiffieHellmanKeyFactoryImpl.class.getName());
put("Alg.Alias.KeyFactory.DH", "DiffieHellman");
// Message Digests
put("MessageDigest.SHA", gnu.java.security.provider.SHA.class.getName());
put("MessageDigest.MD5", gnu.java.security.provider.MD5.class.getName());
// Format "Alias", "Actual Name"
put("Alg.Alias.MessageDigest.SHA1", "SHA");
put("Alg.Alias.MessageDigest.SHA-1", "SHA");
put("Alg.Alias.MessageDigest.SHA-160", "SHA");
put("Alg.Alias.MessageDigest.SHS", "SHA-160");
put("Alg.Alias.MessageDigest.SHA", "SHA-160");
put("Alg.Alias.MessageDigest.SHA1", "SHA-160");
put("Alg.Alias.MessageDigest.SHA-1", "SHA-160");
put("Alg.Alias.MessageDigest.SHA2-256", "SHA-256");
put("Alg.Alias.MessageDigest.SHA2-384", "SHA-384");
put("Alg.Alias.MessageDigest.SHA2-512", "SHA-512");
put("Alg.Alias.MessageDigest.SHA256", "SHA-256");
put("Alg.Alias.MessageDigest.SHA384", "SHA-384");
put("Alg.Alias.MessageDigest.SHA512", "SHA-512");
put("Alg.Alias.MessageDigest.RIPEMD-160", "RIPEMD160");
put("Alg.Alias.MessageDigest.RIPEMD-128", "RIPEMD128");
put("Alg.Alias.MessageDigest.OID.1.2.840.11359.2.2", "MD2");
put("Alg.Alias.MessageDigest.1.2.840.11359.2.2", "MD2");
put("Alg.Alias.MessageDigest.OID.1.2.840.11359.2.5", "MD5");
put("Alg.Alias.MessageDigest.1.2.840.11359.2.5", "MD5");
put("Alg.Alias.MessageDigest.OID.1.3.14.3.2.26", "SHA1");
put("Alg.Alias.MessageDigest.1.3.14.3.2.26", "SHA1");
// Algorithm Parameters
put("AlgorithmParameters.DSA",
gnu.java.security.provider.DSAParameters.class.getName());
put("Alg.Alias.AlgorithmParameters.DSS", "DSA");
put("Alg.Alias.AlgorithmParameters.SHAwithDSA", "DSA");
put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.3", "DSA");
put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.3", "DSA");
put("AlgorithmParameters.DSS",
gnu.java.security.jce.sig.DSSParameters.class.getName());
put("Alg.Alias.AlgorithmParameters.DSA", "DSS");
put("Alg.Alias.AlgorithmParameters.SHAwithDSA", "DSS");
put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.3", "DSS");
put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.3", "DSS");
// Algorithm Parameter Generator
put("AlgorithmParameterGenerator.DSA",
gnu.java.security.provider.DSAParameterGenerator.class.getName());
gnu.java.security.jce.sig.DSSParametersGenerator.class.getName());
put("Alg.Alias.AlgorithmParameterGenerator.DSA", "DSS");
// SecureRandom
put("SecureRandom.SHA1PRNG",
gnu.java.security.provider.SHA1PRNG.class.getName());
gnu.java.security.jce.prng.Sha160RandomSpi.class.getName());
put("SecureRandom.MD2PRNG", gnu.java.security.jce.prng.MD2RandomSpi.class.getName());
put("SecureRandom.MD2PRNG ImplementedIn", "Software");
put("SecureRandom.MD4PRNG", gnu.java.security.jce.prng.MD4RandomSpi.class.getName());
put("SecureRandom.MD4PRNG ImplementedIn", "Software");
put("SecureRandom.MD5PRNG", gnu.java.security.jce.prng.MD5RandomSpi.class.getName());
put("SecureRandom.MD5PRNG ImplementedIn", "Software");
put("SecureRandom.RIPEMD128PRNG", gnu.java.security.jce.prng.RipeMD128RandomSpi.class.getName());
put("SecureRandom.RIPEMD128PRNG ImplementedIn", "Software");
put("SecureRandom.RIPEMD160PRNG", gnu.java.security.jce.prng.RipeMD160RandomSpi.class.getName());
put("SecureRandom.RIPEMD160PRNG ImplementedIn", "Software");
put("SecureRandom.SHA-160PRNG", gnu.java.security.jce.prng.Sha160RandomSpi.class.getName());
put("SecureRandom.SHA-160PRNG ImplementedIn", "Software");
put("SecureRandom.SHA-256PRNG", gnu.java.security.jce.prng.Sha256RandomSpi.class.getName());
put("SecureRandom.SHA-256PRNG ImplementedIn", "Software");
put("SecureRandom.SHA-384PRNG", gnu.java.security.jce.prng.Sha384RandomSpi.class.getName());
put("SecureRandom.SHA-384PRNG ImplementedIn", "Software");
put("SecureRandom.SHA-512PRNG", gnu.java.security.jce.prng.Sha512RandomSpi.class.getName());
put("SecureRandom.SHA-512PRNG ImplementedIn", "Software");
put("SecureRandom.TIGERPRNG", gnu.java.security.jce.prng.TigerRandomSpi.class.getName());
put("SecureRandom.TIGERPRNG ImplementedIn", "Software");
put("SecureRandom.HAVALPRNG", gnu.java.security.jce.prng.HavalRandomSpi.class.getName());
put("SecureRandom.HAVALPRNG ImplementedIn", "Software");
put("SecureRandom.WHIRLPOOLPRNG", gnu.java.security.jce.prng.WhirlpoolRandomSpi.class.getName());
put("SecureRandom.WHIRLPOOLPRNG ImplementedIn", "Software");
put("Alg.Alias.SecureRandom.SHA-1PRNG", "SHA-160PRNG");
put("Alg.Alias.SecureRandom.SHA1PRNG", "SHA-160PRNG");
put("Alg.Alias.SecureRandom.SHAPRNG", "SHA-160PRNG");
put("Alg.Alias.SecureRandom.SHA-256PRNG", "SHA-256PRNG");
put("Alg.Alias.SecureRandom.SHA-2-1PRNG", "SHA-256PRNG");
put("Alg.Alias.SecureRandom.SHA-384PRNG", "SHA-384PRNG");
put("Alg.Alias.SecureRandom.SHA-2-2PRNG", "SHA-384PRNG");
put("Alg.Alias.SecureRandom.SHA-512PRNG", "SHA-512PRNG");
put("Alg.Alias.SecureRandom.SHA-2-3PRNG", "SHA-512PRNG");
// CertificateFactory
put("CertificateFactory.X509", X509CertificateFactory.class.getName());
put("CertificateFactory.X509 ImplementedIn", "Software");
put("Alg.Alias.CertificateFactory.X.509", "X509");
@@ -166,14 +270,6 @@ public final class Gnu extends Provider
// CertStore
put("CertStore.Collection", CollectionCertStoreImpl.class.getName());
// KeyAgreement
put("KeyAgreement.DiffieHellman", gnu.javax.crypto.DiffieHellmanImpl.class.getName());
put("Alg.Alias.KeyAgreement.DH", "DiffieHellman");
// Cipher
put("Cipher.RSAES-PKCS1-v1_5", gnu.javax.crypto.RSACipherImpl.class.getName());
put("Alg.Alias.Cipher.RSA", "RSAES-PKCS1-v1_5");
return null;
}
});
@@ -1,115 +0,0 @@
/* GnuDHPublicKey.java -- A Diffie-Hellman public key.
Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import gnu.java.security.OID;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERValue;
import java.math.BigInteger;
import java.util.ArrayList;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
public class GnuDHPublicKey implements DHPublicKey
{
// Fields.
// -------------------------------------------------------------------------
private byte[] encoded;
private final DHParameterSpec params;
private final BigInteger Y;
private final BigInteger q;
// Constructor.
// -------------------------------------------------------------------------
public GnuDHPublicKey(DHParameterSpec params, BigInteger Y, BigInteger q)
{
this.params = params;
this.Y = Y;
this.q = q;
}
// Instance methods.
// -------------------------------------------------------------------------
public BigInteger getY()
{
return Y;
}
public DHParameterSpec getParams()
{
return params;
}
public String getAlgorithm()
{
return "DH";
}
public String getFormat()
{
return "X.509";
}
public byte[] getEncoded()
{
if (encoded != null)
return (byte[]) encoded.clone();
ArrayList spki = new ArrayList(2);
ArrayList alg = new ArrayList(2);
alg.add(new DERValue(DER.OBJECT_IDENTIFIER, new OID("1.2.840.10046.2.1")));
ArrayList param = new ArrayList(3);
param.add(new DERValue(DER.INTEGER, params.getP()));
param.add(new DERValue(DER.INTEGER, params.getG()));
param.add(new DERValue(DER.INTEGER, q));
alg.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, param));
spki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg));
spki.add(new DERValue(DER.BIT_STRING, new BitString(Y.toByteArray())));
encoded = new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, spki).getEncoded();
if (encoded != null)
return (byte[]) encoded.clone();
return null;
}
}
@@ -1,147 +0,0 @@
/* GnuDSAPrivateKey.java --- Gnu DSA Private Key
Copyright (C) 1999,2003,2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import gnu.java.security.OID;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPrivateKey;
import java.security.spec.DSAParameterSpec;
import java.util.ArrayList;
public class GnuDSAPrivateKey implements DSAPrivateKey
{
private byte[] encodedKey;
BigInteger x;
BigInteger p;
BigInteger q;
BigInteger g;
public GnuDSAPrivateKey(BigInteger x, BigInteger p, BigInteger q, BigInteger g )
{
this.x = x;
this.p = p;
this.q = q;
this.g = g;
}
public String getAlgorithm()
{
return "DSA";
}
public String getFormat()
{
return "PKCS#8";
}
/**
* Encodes this key as a <code>PrivateKeyInfo</code>, as described in
* PKCS #8. The ASN.1 specification for this structure is:
*
* <blockquote><pre>
* PrivateKeyInfo ::= SEQUENCE {
* version Version,
* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
* privateKey PrivateKey,
* attributes [0] IMPLICIT Attributes OPTIONAL }
*
* Version ::= INTEGER
*
* PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
*
* PrivateKey ::= OCTET STRING
*
* Attributes ::= SET OF Attribute
* </pre></blockquote>
*
* <p>DSA private keys (in Classpath at least) have no attributes.
*/
public byte[] getEncoded()
{
if (encodedKey != null)
return (byte[]) encodedKey.clone();
try
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
ArrayList pki = new ArrayList(3);
pki.add(new DERValue(DER.INTEGER, BigInteger.ZERO));
ArrayList algId = new ArrayList(2);
algId.add(new DERValue(DER.OBJECT_IDENTIFIER,
new OID("1.2.840.10040.4.1")));
ArrayList algParams = new ArrayList(3);
algParams.add(new DERValue(DER.INTEGER, p));
algParams.add(new DERValue(DER.INTEGER, q));
algParams.add(new DERValue(DER.INTEGER, g));
algId.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, algParams));
pki.add(new DERValue(DER.OCTET_STRING, x.toByteArray()));
DERWriter.write(out, new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, pki));
return (byte[]) (encodedKey = out.toByteArray()).clone();
}
catch (IOException ioe)
{
return null;
}
}
public DSAParams getParams()
{
return (DSAParams)(new DSAParameterSpec(p,q,g));
}
public BigInteger getX()
{
return x;
}
public String toString()
{
return "GnuDSAPrivateKey: x="
+ (x != null ? x.toString(16) : "null") + " p="
+ (p != null ? p.toString(16) : "null") + " q="
+ (q != null ? q.toString(16) : "null") + " g="
+ (g != null ? g.toString(16) : "null");
}
}
@@ -1,137 +0,0 @@
/* GnuDSAPublicKey.java --- Gnu DSA Public Key
Copyright (C) 1999,2003,2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.security.provider;
import gnu.java.security.OID;
import gnu.java.security.der.BitString;
import gnu.java.security.der.DER;
import gnu.java.security.der.DERValue;
import gnu.java.security.der.DERWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.DSAParameterSpec;
import java.util.ArrayList;
public class GnuDSAPublicKey implements DSAPublicKey
{
private byte[] encodedKey;
BigInteger y;
BigInteger p;
BigInteger q;
BigInteger g;
public GnuDSAPublicKey(BigInteger y, BigInteger p, BigInteger q, BigInteger g )
{
this.y = y;
this.p = p;
this.q = q;
this.g = g;
}
public String getAlgorithm()
{
return "DSA";
}
public String getFormat()
{
return "X.509";
}
/**
* The encoded form of DSA public keys is:
*
* <blockquote><pre>
* SubjectPublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
* subjectPublicKey BIT STRING }
* </pre></blockquote>
*/
public byte[] getEncoded()
{
if (encodedKey != null)
return (byte[]) encodedKey.clone();
try
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
ArrayList spki = new ArrayList(2);
ArrayList alg = new ArrayList(2);
alg.add(new DERValue(DER.OBJECT_IDENTIFIER,
new OID("1.2.840.113549.1.1.1")));
ArrayList params = new ArrayList(3);
params.add(new DERValue(DER.INTEGER, p));
params.add(new DERValue(DER.INTEGER, q));
params.add(new DERValue(DER.INTEGER, g));
alg.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, params));
spki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg));
spki.add(new DERValue(DER.BIT_STRING, new BitString(y.toByteArray())));
DERWriter.write(out, new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, spki));
return (byte[]) (encodedKey = out.toByteArray()).clone();
}
catch (IOException ioe)
{
return null;
}
}
public DSAParams getParams()
{
if (p == null || q == null || g == null)
return null;
return (DSAParams)(new DSAParameterSpec(p,q,g));
}
public BigInteger getY()
{
return y;
}
public String toString()
{
return
"GnuDSAPublicKey: y=" + (y != null ? y.toString(16) : "(null)") +
" p=" + (p != null ? p.toString(16) : "(null)") +
" q=" + (q != null ? q.toString(16) : "(null)") +
" g=" + (g != null ? g.toString(16) : "(null)");
}
}

Some files were not shown because too many files have changed in this diff Show More