summaryrefslogtreecommitdiff
path: root/gnu/javax/crypto/mac
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/javax/crypto/mac')
-rw-r--r--gnu/javax/crypto/mac/BaseMac.java43
-rw-r--r--gnu/javax/crypto/mac/HMac.java195
-rw-r--r--gnu/javax/crypto/mac/HMacFactory.java65
-rw-r--r--gnu/javax/crypto/mac/IMac.java154
-rw-r--r--gnu/javax/crypto/mac/MacFactory.java78
-rw-r--r--gnu/javax/crypto/mac/MacInputStream.java42
-rw-r--r--gnu/javax/crypto/mac/MacOutputStream.java59
-rw-r--r--gnu/javax/crypto/mac/OMAC.java209
-rw-r--r--gnu/javax/crypto/mac/TMMH16.java195
-rw-r--r--gnu/javax/crypto/mac/UHash32.java499
-rw-r--r--gnu/javax/crypto/mac/UMac32.java287
11 files changed, 605 insertions, 1221 deletions
diff --git a/gnu/javax/crypto/mac/BaseMac.java b/gnu/javax/crypto/mac/BaseMac.java
index 1b42a1644..16922130f 100644
--- a/gnu/javax/crypto/mac/BaseMac.java
+++ b/gnu/javax/crypto/mac/BaseMac.java
@@ -40,35 +40,26 @@ package gnu.javax.crypto.mac;
import gnu.java.security.hash.IMessageDigest;
-import java.util.Map;
import java.security.InvalidKeyException;
+import java.util.Map;
/**
- * <p>A base abstract class to facilitate <i>MAC</i> (Message Authentication
- * Code) implementations.</p>
+ * A base abstract class to facilitate <i>MAC</i> (Message Authentication Code)
+ * implementations.
*/
-public abstract class BaseMac implements IMac
+public abstract class BaseMac
+ implements IMac
{
-
- // Constants and variables
- // -------------------------------------------------------------------------
-
/** The canonical name prefix of the <i>MAC</i>. */
protected String name;
-
/** Reference to the underlying hash algorithm instance. */
protected IMessageDigest underlyingHash;
-
/** The length of the truncated output in bytes. */
protected int truncatedSize;
- /** The authentication key for this instance. */
- // protected transient byte[] K;
- // Constructor(s)
- // -------------------------------------------------------------------------
/**
- * <p>Trivial constructor for use by concrete subclasses.</p>
- *
+ * Trivial constructor for use by concrete subclasses.
+ *
* @param name the canonical name of this instance.
*/
protected BaseMac(String name)
@@ -79,8 +70,8 @@ public abstract class BaseMac implements IMac
}
/**
- * <p>Trivial constructor for use by concrete subclasses.</p>
- *
+ * Trivial constructor for use by concrete subclasses.
+ *
* @param name the canonical name of this instance.
* @param underlyingHash the underlying message digest algorithm instance.
*/
@@ -89,20 +80,10 @@ public abstract class BaseMac implements IMac
this(name);
if (underlyingHash != null)
- {
- truncatedSize = underlyingHash.hashSize();
- }
+ truncatedSize = underlyingHash.hashSize();
this.underlyingHash = underlyingHash;
}
- // Class methods
- // -------------------------------------------------------------------------
-
- // Instance methods
- // -------------------------------------------------------------------------
-
- // gnu.crypto.mac.IMac interface implementation ----------------------------
-
public String name()
{
return name;
@@ -137,12 +118,10 @@ public abstract class BaseMac implements IMac
return result;
}
- // methods to be implemented by concrete subclasses ------------------------
-
public abstract void init(Map attributes) throws InvalidKeyException,
IllegalStateException;
public abstract byte[] digest();
public abstract boolean selfTest();
-} \ No newline at end of file
+}
diff --git a/gnu/javax/crypto/mac/HMac.java b/gnu/javax/crypto/mac/HMac.java
index c1f97b541..f0e588d18 100644
--- a/gnu/javax/crypto/mac/HMac.java
+++ b/gnu/javax/crypto/mac/HMac.java
@@ -48,70 +48,51 @@ import java.util.HashMap;
import java.util.Map;
/**
- * <p>The implementation of the <i>HMAC</i> (Keyed-Hash Message Authentication
- * Code).</p>
- *
- * <p><i>HMAC</i> can be used in combination with any iterated cryptographic
- * hash function. <i>HMAC</i> also uses a <i>secret key</i> for calculation and
+ * The implementation of the <i>HMAC</i> (Keyed-Hash Message Authentication
+ * Code).
+ * <p>
+ * <i>HMAC</i> can be used in combination with any iterated cryptographic hash
+ * function. <i>HMAC</i> also uses a <i>secret key</i> for calculation and
* verification of the message authentication values. The main goals behind this
- * construction are</p>
- *
+ * construction are:
* <ul>
- * <li>To use, without modifications, available hash functions. In
- * particular, hash functions that perform well in software, and for which
- * code is freely and widely available.</li>
- *
- * <li>To preserve the original performance of the hash function without
- * incurring a significant degradation.</li>
- *
- * <li>To use and handle keys in a simple way.</li>
- *
- * <li>To have a well understood cryptographic analysis of the strength of
- * the authentication mechanism based on reasonable assumptions on the
- * underlying hash function.</li>
- *
- * <li>To allow for easy replaceability of the underlying hash function in
- * case that faster or more secure hash functions are found or required.</li>
+ * <li>To use, without modifications, available hash functions. In particular,
+ * hash functions that perform well in software, and for which code is freely
+ * and widely available.</li>
+ * <li>To preserve the original performance of the hash function without
+ * incurring a significant degradation.</li>
+ * <li>To use and handle keys in a simple way.</li>
+ * <li>To have a well understood cryptographic analysis of the strength of the
+ * authentication mechanism based on reasonable assumptions on the underlying
+ * hash function.</li>
+ * <li>To allow for easy replaceability of the underlying hash function in case
+ * that faster or more secure hash functions are found or required.</li>
* </ul>
- *
- * <p>References:</p>
- *
+ * <p>
+ * References:
* <ol>
- * <li><a href="http://www.ietf.org/rfc/rfc-2104.txt">RFC 2104</a>HMAC:
- * Keyed-Hashing for Message Authentication.<br>
- * H. Krawczyk, M. Bellare, and R. Canetti.</li>
+ * <li><a href="http://www.ietf.org/rfc/rfc-2104.txt">RFC 2104</a>HMAC:
+ * Keyed-Hashing for Message Authentication.<br>
+ * H. Krawczyk, M. Bellare, and R. Canetti.</li>
* </ol>
*/
-public class HMac extends BaseMac implements Cloneable
+public class HMac
+ extends BaseMac
+ implements Cloneable
{
-
- // Constants and variables
- // -------------------------------------------------------------------------
-
public static final String USE_WITH_PKCS5_V2 = "gnu.crypto.hmac.pkcs5";
-
private static final byte IPAD_BYTE = 0x36;
-
private static final byte OPAD_BYTE = 0x5C;
-
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
-
protected int macSize;
-
protected int blockSize;
-
protected IMessageDigest ipadHash;
-
protected IMessageDigest opadHash;
-
protected byte[] ipad;
- // Constructor(s)
- // -------------------------------------------------------------------------
-
/**
- * <p>Trivial constructor for use by concrete subclasses.</p>
+ * Trivial constructor for use by concrete subclasses.
*
* @param underlyingHash the underlying hash algorithm instance.
*/
@@ -124,14 +105,6 @@ public class HMac extends BaseMac implements Cloneable
ipadHash = opadHash = null;
}
- // Class methods
- // -------------------------------------------------------------------------
-
- // Instance methods
- // -------------------------------------------------------------------------
-
- // java.lang.Cloneable interface implementation ----------------------------
-
public Object clone() throws CloneNotSupportedException
{
HMac result = (HMac) super.clone();
@@ -145,88 +118,65 @@ public class HMac extends BaseMac implements Cloneable
return result;
}
- // implementation of abstract methods in BaseMac ---------------------------
-
public void init(Map attributes) throws InvalidKeyException,
IllegalStateException
{
Integer ts = (Integer) attributes.get(TRUNCATED_SIZE);
truncatedSize = (ts == null ? macSize : ts.intValue());
if (truncatedSize < (macSize / 2))
- {
- throw new IllegalArgumentException("Truncated size too small");
- }
+ throw new IllegalArgumentException("Truncated size too small");
else if (truncatedSize < 10)
- {
- throw new IllegalArgumentException("Truncated size less than 80 bits");
- }
+ throw new IllegalArgumentException("Truncated size less than 80 bits");
// we dont use/save the key outside this method
byte[] K = (byte[]) attributes.get(MAC_KEY_MATERIAL);
if (K == null)
{ // take it as an indication to re-use previous key if set
if (ipadHash == null)
- {
- throw new InvalidKeyException("Null key");
- }
+ throw new InvalidKeyException("Null key");
// we already went through the motions; ie. up to step #4. re-use
underlyingHash = (IMessageDigest) ipadHash.clone();
return;
}
- // for HMACs used in key-derivation functions (e.g. PBKDF2) the key
- // material need not be >= the (output) block size of the underlying
- // algorithm
+ // for HMACs used in key-derivation functions (e.g. PBKDF2) the key material
+ // need not be >= the (output) block size of the underlying algorithm
Boolean pkcs5 = (Boolean) attributes.get(USE_WITH_PKCS5_V2);
if (pkcs5 == null)
- {
- pkcs5 = Boolean.FALSE;
- }
- if (K.length < macSize && !pkcs5.booleanValue())
- {
- throw new InvalidKeyException("Key too short");
- }
+ pkcs5 = Boolean.FALSE;
+ if (K.length < macSize && ! pkcs5.booleanValue())
+ throw new InvalidKeyException("Key too short");
if (K.length > blockSize)
{
- // (0) replace K with HASH(K) if K is larger than the hash's
- // block size. Then pad with zeros until it is the correct
- // size (the next `if').
+ // (0) replace K with HASH(K) if K is larger than the hash's block size.
+ // Then pad with zeros until it is the correct size (the next `if').
underlyingHash.update(K, 0, K.length);
K = underlyingHash.digest();
}
if (K.length < blockSize)
{
- // (1) append zeros to the end of K to create a B byte string
- // (e.g., if K is of length 20 bytes and B=64, then K will be
- // appended with 44 zero bytes 0x00)
+ // (1) append zeros to the end of K to create a B byte string (e.g., if
+ // K is of length 20 bytes and B=64, then K will be appended with 44
+ // zero bytes 0x00)
int limit = (K.length > blockSize) ? blockSize : K.length;
byte[] newK = new byte[blockSize];
System.arraycopy(K, 0, newK, 0, limit);
K = newK;
}
-
underlyingHash.reset();
opadHash = (IMessageDigest) underlyingHash.clone();
if (ipad == null)
- {
- ipad = new byte[blockSize];
- }
- // (2) XOR (bitwise exclusive-OR) the B byte string computed in step
- // (1) with ipad
- // (3) append the stream of data 'text' to the B byte string resulting
- // from step (2)
+ ipad = new byte[blockSize];
+ // (2) XOR (bitwise exclusive-OR) the B byte string computed in step (1)
+ // with ipad
+ // (3) append the stream of data 'text' to the B byte string resulting from
+ // step (2)
// (4) apply H to the stream generated in step (3)
for (int i = 0; i < blockSize; i++)
- {
- // underlyingHash.update((byte)(K[i] ^ IPAD_BYTE));
- ipad[i] = (byte) (K[i] ^ IPAD_BYTE);
- }
+ ipad[i] = (byte)(K[i] ^ IPAD_BYTE);
for (int i = 0; i < blockSize; i++)
- {
- opadHash.update((byte) (K[i] ^ OPAD_BYTE));
- }
-
+ opadHash.update((byte)(K[i] ^ OPAD_BYTE));
underlyingHash.update(ipad, 0, blockSize);
ipadHash = (IMessageDigest) underlyingHash.clone();
K = null;
@@ -245,28 +195,21 @@ public class HMac extends BaseMac implements Cloneable
public byte[] digest()
{
if (ipadHash == null)
- {
- throw new IllegalStateException("HMAC not initialised");
- }
-
+ throw new IllegalStateException("HMAC not initialised");
byte[] out = underlyingHash.digest();
- // (5) XOR (bitwise exclusive-OR) the B byte string computed in
- // step (1) with opad
+ // (5) XOR (bitwise exclusive-OR) the B byte string computed in step (1)
+ // with opad
underlyingHash = (IMessageDigest) opadHash.clone();
- // (6) append the H result from step (4) to the B byte string
- // resulting from step (5)
+ // (6) append the H result from step (4) to the B byte string resulting from
+ // step (5)
underlyingHash.update(out, 0, macSize);
- // (7) apply H to the stream generated in step (6) and output
- // the result
+ // (7) apply H to the stream generated in step (6) and output the result
out = underlyingHash.digest(); // which also resets the underlying hash
-
// truncate and return
if (truncatedSize == macSize)
return out;
-
byte[] result = new byte[truncatedSize];
System.arraycopy(out, 0, result, 0, truncatedSize);
-
return result;
}
@@ -279,31 +222,25 @@ public class HMac extends BaseMac implements Cloneable
IMac mac = new HMac(new MD5()); // use rfc-2104 test vectors
String tv1 = "9294727A3638BB1C13F48EF8158BFC9D";
String tv3 = "56BE34521D144C88DBB8C733F0E8B3F6";
- byte[] k1 = new byte[] { 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
- 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
- 0x0B, 0x0B };
- byte[] k3 = new byte[] { (byte) 0xAA, (byte) 0xAA, (byte) 0xAA,
- (byte) 0xAA, (byte) 0xAA, (byte) 0xAA,
- (byte) 0xAA, (byte) 0xAA, (byte) 0xAA,
- (byte) 0xAA, (byte) 0xAA, (byte) 0xAA,
- (byte) 0xAA, (byte) 0xAA, (byte) 0xAA,
- (byte) 0xAA };
+ byte[] k1 = new byte[] {
+ 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
+ 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B };
+ byte[] k3 = new byte[] {
+ (byte) 0xAA, (byte) 0xAA, (byte) 0xAA, (byte) 0xAA,
+ (byte) 0xAA, (byte) 0xAA, (byte) 0xAA, (byte) 0xAA,
+ (byte) 0xAA, (byte) 0xAA, (byte) 0xAA, (byte) 0xAA,
+ (byte) 0xAA, (byte) 0xAA, (byte) 0xAA, (byte) 0xAA };
byte[] data = new byte[50];
for (int i = 0; i < 50;)
- {
- data[i++] = (byte) 0xDD;
- }
+ data[i++] = (byte) 0xDD;
HashMap map = new HashMap();
-
// test vector #1
map.put(MAC_KEY_MATERIAL, k1);
mac.init(map);
mac.update("Hi There".getBytes("ASCII"), 0, 8);
- if (!tv1.equals(Util.toString(mac.digest())))
- {
- valid = Boolean.FALSE;
- }
+ if (! tv1.equals(Util.toString(mac.digest())))
+ valid = Boolean.FALSE;
// test #2 is not used since it causes a "Key too short" exception
@@ -311,10 +248,8 @@ public class HMac extends BaseMac implements Cloneable
map.put(MAC_KEY_MATERIAL, k3);
mac.init(map);
mac.update(data, 0, 50);
- if (!tv3.equals(Util.toString(mac.digest())))
- {
- valid = Boolean.FALSE;
- }
+ if (! tv3.equals(Util.toString(mac.digest())))
+ valid = Boolean.FALSE;
valid = Boolean.TRUE;
}
catch (Exception x)
diff --git a/gnu/javax/crypto/mac/HMacFactory.java b/gnu/javax/crypto/mac/HMacFactory.java
index 156e6ced5..bc70e8b66 100644
--- a/gnu/javax/crypto/mac/HMacFactory.java
+++ b/gnu/javax/crypto/mac/HMacFactory.java
@@ -47,68 +47,56 @@ import java.util.Iterator;
import java.util.Set;
/**
- * <p>A <i>Factory</i> to instantiate Keyed-Hash Message Authentication Code
- * (HMAC) algorithm instances.</p>
+ * A <i>Factory</i> to instantiate Keyed-Hash Message Authentication Code
+ * (HMAC) algorithm instances.
*/
-public class HMacFactory implements Registry
+public class HMacFactory
+ implements Registry
{
-
- // Constants and variables
- // -------------------------------------------------------------------------
-
- // Constructor(s)
- // -------------------------------------------------------------------------
-
/** Trivial constructor to enforce <i>Singleton</i> pattern. */
private HMacFactory()
{
super();
}
- // Class methods
- // -------------------------------------------------------------------------
-
/**
- * <p>Return an instance of a <i>HMAC</i> algorithm given the name of its
+ * Return an instance of a <i>HMAC</i> algorithm given the name of its
* underlying hash function, prefixed with the literal defined in
- * {@link Registry#HMAC_NAME_PREFIX}.</p>
- *
+ * {@link Registry#HMAC_NAME_PREFIX}.
+ *
* @param name the fully qualified name of the underlying algorithm: composed
- * as the concatenation of a literal prefix (see {@link Registry#HMAC_NAME_PREFIX})
- * and the name of the underlying hash algorithm.
- * @return an instance of the <i>HMAC</i> algorithm, or <code>null</code> if
- * none can be constructed.
+ * as the concatenation of a literal prefix (see
+ * {@link Registry#HMAC_NAME_PREFIX}) and the name of the underlying
+ * hash algorithm.
+ * @return an instance of the <i>HMAC</i> algorithm, or <code>null</code>
+ * if none can be constructed.
* @exception InternalError if the implementation does not pass its self-test.
*/
public static IMac getInstance(String name)
{
if (name == null)
- {
- return null;
- }
+ return null;
name = name.trim();
name = name.toLowerCase();
- if (!name.startsWith(HMAC_NAME_PREFIX))
- {
- return null;
- }
+ if (! name.startsWith(HMAC_NAME_PREFIX))
+ return null;
// strip the prefix
name = name.substring(HMAC_NAME_PREFIX.length()).trim();
IMac result = new HMac(HashFactory.getInstance(name));
- if (result != null && !result.selfTest())
- {
- throw new InternalError(result.name());
- }
+ if (result != null && ! result.selfTest())
+ throw new InternalError(result.name());
return result;
}
/**
- * <p>Returns a {@link java.util.Set} of names of <i>HMAC</i> algorithms
- * supported by this <i>Factory</i>.</p>
- *
+ * <p>
+ * Returns a {@link java.util.Set} of names of <i>HMAC</i> algorithms
+ * supported by this <i>Factory</i>.
+ * </p>
+ *
* @return a {@link java.util.Set} of HMAC algorithm names (Strings).
*/
public static final Set getNames()
@@ -116,13 +104,8 @@ public class HMacFactory implements Registry
Set hashNames = HashFactory.getNames();
HashSet hs = new HashSet();
for (Iterator it = hashNames.iterator(); it.hasNext();)
- {
- hs.add(HMAC_NAME_PREFIX + ((String) it.next()));
- }
+ hs.add(HMAC_NAME_PREFIX + ((String) it.next()));
return Collections.unmodifiableSet(hs);
}
-
- // Instance methods
- // -------------------------------------------------------------------------
-} \ No newline at end of file
+}
diff --git a/gnu/javax/crypto/mac/IMac.java b/gnu/javax/crypto/mac/IMac.java
index c4170c42c..a9da9eefb 100644
--- a/gnu/javax/crypto/mac/IMac.java
+++ b/gnu/javax/crypto/mac/IMac.java
@@ -38,108 +38,93 @@ exception statement from your version. */
package gnu.javax.crypto.mac;
-import java.util.Map;
import java.security.InvalidKeyException;
+import java.util.Map;
/**
- * <p>The basic visible methods of any MAC (Message Authentication Code)
- * algorithm.</p>
- *
- * <p>A <i>MAC</i> provides a way to check the integrity of information
+ * The basic visible methods of any MAC (Message Authentication Code) algorithm.
+ * <p>
+ * A <i>MAC</i> provides a way to check the integrity of information
* transmitted over, or stored in, an unreliable medium, based on a secret key.
* Typically, <i>MAC</i>s are used between two parties, that share a common
- * secret key, in order to validate information transmitted between them.</p>
- *
- * <p>When a <i>MAC</i> algorithm is based on a cryptographic hash function, it
- * is then called to a <i>HMAC</i> (Hashed Message Authentication Code) --see
- * <a href="http://www.ietf.org/rfc/rfc-2104.txt">RFC-2104</a>.</p>
- *
+ * secret key, in order to validate information transmitted between them.
+ * <p>
+ * When a <i>MAC</i> algorithm is based on a cryptographic hash function, it is
+ * then called to a <i>HMAC</i> (Hashed Message Authentication Code) --see <a
+ * href="http://www.ietf.org/rfc/rfc-2104.txt">RFC-2104</a>.
+ * <p>
* Another type of <i>MAC</i> algorithms exist: UMAC or <i>Universal Message
- * Authentication Code</i>, described in
- * <a href="http://www.ietf.org/internet-drafts/draft-krovetz-umac-01.txt">
- * draft-krovetz-umac-01.txt</a>.</p>
- *
- * <p>With <i>UMAC</i>s, the sender and receiver share a common secret key (the
- * <i>MAC</i> key) which determines:</p>
- *
+ * Authentication Code</i>, described in <a
+ * href="http://www.ietf.org/internet-drafts/draft-krovetz-umac-01.txt">
+ * draft-krovetz-umac-01.txt</a>.
+ * <p>
+ * With <i>UMAC</i>s, the sender and receiver share a common secret key (the
+ * <i>MAC</i> key) which determines:
* <ul>
- * <li>The key for a <i>universal hash function</i>. This hash function is
- * <i>non-cryptographic</i>, in the sense that it does not need to have any
- * cryptographic <i>hardness</i> property. Rather, it needs to satisfy some
- * combinatorial property, which can be proven to hold without relying on
- * unproven hardness assumptions.</li>
- *
- * <li>The key for a <i>pseudorandom function</i>. This is where one needs a
- * cryptographic hardness assumption. The pseudorandom function may be
- * obtained from a <i>block cipher</i> or a <i>cryptographic hash function</i>.
- * </li>
+ * <li>The key for a <i>universal hash function</i>. This hash function is
+ * <i>non-cryptographic</i>, in the sense that it does not need to have any
+ * cryptographic <i>hardness</i> property. Rather, it needs to satisfy some
+ * combinatorial property, which can be proven to hold without relying on
+ * unproven hardness assumptions.</li>
+ * <li>The key for a <i>pseudorandom function</i>. This is where one needs a
+ * cryptographic hardness assumption. The pseudorandom function may be obtained
+ * from a <i>block cipher</i> or a <i>cryptographic hash function</i>. </li>
* </ul>
- *
- * <p>References:</p>
- *
+ * <p>
+ * References:
* <ol>
- * <li><a href="http://www.ietf.org/rfc/rfc-2104.txt">RFC 2104</a>HMAC:
- * Keyed-Hashing for Message Authentication.<br>
- * H. Krawczyk, M. Bellare, and R. Canetti.</li>
- *
- * <li><a href="http://www.ietf.org/internet-drafts/draft-krovetz-umac-01.txt">
- * UMAC</a>: Message Authentication Code using Universal Hashing.<br>
- * T. Krovetz, J. Black, S. Halevi, A. Hevia, H. Krawczyk, and P. Rogaway.</li>
+ * <li><a href="http://www.ietf.org/rfc/rfc-2104.txt">RFC 2104</a>HMAC:
+ * Keyed-Hashing for Message Authentication.<br>
+ * H. Krawczyk, M. Bellare, and R. Canetti.</li>
+ * <li><a href="http://www.ietf.org/internet-drafts/draft-krovetz-umac-01.txt">
+ * UMAC</a>: Message Authentication Code using Universal Hashing.<br>
+ * T. Krovetz, J. Black, S. Halevi, A. Hevia, H. Krawczyk, and P. Rogaway.</li>
* </ol>
*/
public interface IMac
{
-
- // Constants
- // -------------------------------------------------------------------------
-
/**
* Property name of the user-supplied key material. The value associated to
* this property name is taken to be a byte array.
*/
String MAC_KEY_MATERIAL = "gnu.crypto.mac.key.material";
-
/**
- * <p>Property name of the desired truncated output size in bytes. The value
- * associated to this property name is taken to be an integer. If no value
- * is specified in the attributes map at initialisation time, then all bytes
- * of the underlying hash algorithm's output are emitted.</p>
- *
- * <p>This implementation, follows the recommendation of the <i>RFC 2104</i>
- * authors; specifically:</p>
- *
+ * Property name of the desired truncated output size in bytes. The value
+ * associated to this property name is taken to be an integer. If no value is
+ * specified in the attributes map at initialisation time, then all bytes of
+ * the underlying hash algorithm's output are emitted.
+ * <p>
+ * This implementation, follows the recommendation of the <i>RFC 2104</i>
+ * authors; specifically:
* <pre>
- * We recommend that the output length t be not less than half the
- * length of the hash output (to match the birthday attack bound)
- * and not less than 80 bits (a suitable lower bound on the number
- * of bits that need to be predicted by an attacker).
+ * We recommend that the output length t be not less than half the
+ * length of the hash output (to match the birthday attack bound)
+ * and not less than 80 bits (a suitable lower bound on the number
+ * of bits that need to be predicted by an attacker).
* </pre>
*/
String TRUNCATED_SIZE = "gnu.crypto.mac.truncated.size";
- // Methods
- // -------------------------------------------------------------------------
-
/**
- * <p>Returns the canonical name of this algorithm.</p>
- *
+ * Returns the canonical name of this algorithm.
+ *
* @return the canonical name of this algorithm.
*/
String name();
/**
- * <p>Returns the output length in bytes of this <i>MAC</i> algorithm.</p>
- *
+ * Returns the output length in bytes of this <i>MAC</i> algorithm.
+ *
* @return the output length in bytes of this <i>MAC</i> algorithm.
*/
int macSize();
/**
- * <p>Initialises the algorithm with designated attributes. Permissible names
- * and values are described in the class documentation above.</p>
- *
+ * Initialises the algorithm with designated attributes. Permissible names and
+ * values are described in the class documentation above.
+ *
* @param attributes a set of name-value pairs that describe the desired
- * future instance behaviour.
+ * future instance behaviour.
* @exception InvalidKeyException if the key data is invalid.
* @exception IllegalStateException if the instance is already initialised.
* @see #MAC_KEY_MATERIAL
@@ -147,18 +132,17 @@ public interface IMac
void init(Map attributes) throws InvalidKeyException, IllegalStateException;
/**
- * <p>Continues a <i>MAC</i> operation using the input byte.</p>
- *
+ * Continues a <i>MAC</i> operation using the input byte.
+ *
* @param b the input byte to digest.
*/
void update(byte b);
/**
- * <p>Continues a <i>MAC</i> operation, by filling the buffer, processing
- * data in the algorithm's MAC_SIZE-bit block(s), updating the context and
- * count, and buffering the remaining bytes in buffer for the next
- * operation.</p>
- *
+ * Continues a <i>MAC</i> operation, by filling the buffer, processing data
+ * in the algorithm's MAC_SIZE-bit block(s), updating the context and count,
+ * and buffering the remaining bytes in buffer for the next operation.
+ *
* @param in the input block.
* @param offset start of meaningful bytes in input block.
* @param length number of bytes, in input block, to consider.
@@ -166,32 +150,32 @@ public interface IMac
void update(byte[] in, int offset, int length);
/**
- * <p>Completes the <i>MAC</i> by performing final operations such as
- * padding and resetting the instance.</p>
- *
+ * Completes the <i>MAC</i> by performing final operations such as padding
+ * and resetting the instance.
+ *
* @return the array of bytes representing the <i>MAC</i> value.
*/
byte[] digest();
/**
- * <p>Resets the algorithm instance for re-initialisation and use with other
- * characteristics. This method always succeeds.</p>
+ * Resets the algorithm instance for re-initialisation and use with other
+ * characteristics. This method always succeeds.
*/
void reset();
/**
- * <p>A basic test. Ensures that the MAC of a pre-determined message is equal
- * to a known pre-computed value.</p>
- *
+ * A basic test. Ensures that the MAC of a pre-determined message is equal to
+ * a known pre-computed value.
+ *
* @return <code>true</code> if the implementation passes a basic self-test.
- * Returns <code>false</code> otherwise.
+ * Returns <code>false</code> otherwise.
*/
boolean selfTest();
/**
- * <p>Returns a clone copy of this instance.</p>
- *
+ * Returns a clone copy of this instance.
+ *
* @return a clone copy of this instance.
*/
Object clone() throws CloneNotSupportedException;
-} \ No newline at end of file
+}
diff --git a/gnu/javax/crypto/mac/MacFactory.java b/gnu/javax/crypto/mac/MacFactory.java
index d8f8bcfce..5d4a56182 100644
--- a/gnu/javax/crypto/mac/MacFactory.java
+++ b/gnu/javax/crypto/mac/MacFactory.java
@@ -48,17 +48,13 @@ import java.util.Iterator;
import java.util.Set;
/**
- * <p>A <i>Factory</i> that instantiates instances of every supported Message
- * Authentication Code algorithms, including all <i>HMAC</i> algorithms.</p>
+ * A <i>Factory</i> that instantiates instances of every supported Message
+ * Authentication Code algorithms, including all <i>HMAC</i> algorithms.
*/
-public class MacFactory implements Registry
+public class MacFactory
+ implements Registry
{
-
- // Constants and variables
- // -------------------------------------------------------------------------
-
- // Constructor(s)
- // -------------------------------------------------------------------------
+ private static Set names;
/** Trivial constructor to enforce <i>Singleton</i> pattern. */
private MacFactory()
@@ -66,72 +62,51 @@ public class MacFactory implements Registry
super();
}
- // Class methods
- // -------------------------------------------------------------------------
-
/**
- * <p>Returns an instance of a <i>MAC</i> algorithm given its name.</p>
- *
+ * Returns an instance of a <i>MAC</i> algorithm given its name.
+ *
* @param name the name of the MAC algorithm.
* @return an instance of the <i>MAC</i> algorithm, or <code>null</code> if
- * none can be constructed.
+ * none can be constructed.
* @exception InternalError if the implementation does not pass its self-test.
*/
public static IMac getInstance(String name)
{
if (name == null)
- {
- return null;
- }
+ return null;
name = name.trim();
name = name.toLowerCase();
if (name.startsWith(HMAC_NAME_PREFIX))
- {
- return HMacFactory.getInstance(name);
- }
+ return HMacFactory.getInstance(name);
if (name.startsWith(OMAC_PREFIX))
{
name = name.substring(OMAC_PREFIX.length());
IBlockCipher cipher = CipherFactory.getInstance(name);
if (cipher == null)
- {
- return null;
- }
+ return null;
return new OMAC(cipher);
}
-
IMac result = null;
if (name.equalsIgnoreCase(UHASH32))
- {
- result = new UHash32();
- }
+ result = new UHash32();
else if (name.equalsIgnoreCase(UMAC32))
- {
- result = new UMac32();
- }
+ result = new UMac32();
else if (name.equalsIgnoreCase(TMMH16))
- {
- result = new TMMH16();
- }
- // else if (name.equalsIgnoreCase(TMMH32)) {
- // result = new TMMH32();
- // }
+ result = new TMMH16();
- if (result != null && !result.selfTest())
- {
- throw new InternalError(result.name());
- }
+ if (result != null && ! result.selfTest())
+ throw new InternalError(result.name());
return result;
}
/**
- * <p>Returns a {@link java.util.Set} of names of <i>MAC</i> algorithms
- * supported by this <i>Factory</i>.</p>
- *
- * @return a {@link java.util.Set} of MAC names (Strings).
+ * Returns a {@link Set} of names of <i>MAC</i> algorithms supported by this
+ * <i>Factory</i>.
+ *
+ * @return a {@link Set} of MAC names (Strings).
*/
public static final Set getNames()
{
@@ -144,21 +119,12 @@ public class MacFactory implements Registry
hs.add(UHASH32);
hs.add(UMAC32);
hs.add(TMMH16);
- // hs.add(TMMH32);
-
for (Iterator it = CipherFactory.getNames().iterator(); it.hasNext();)
- {
- hs.add(OMAC_PREFIX + it.next());
- }
+ hs.add(OMAC_PREFIX + it.next());
names = Collections.unmodifiableSet(hs);
}
}
return names;
}
-
- private static Set names;
-
- // Instance methods
- // -------------------------------------------------------------------------
-} \ No newline at end of file
+}
diff --git a/gnu/javax/crypto/mac/MacInputStream.java b/gnu/javax/crypto/mac/MacInputStream.java
index 9acd18b19..e734b1bbb 100644
--- a/gnu/javax/crypto/mac/MacInputStream.java
+++ b/gnu/javax/crypto/mac/MacInputStream.java
@@ -46,30 +46,19 @@ import java.io.IOException;
* A filtering input stream that computes a MAC (message authentication code)
* over all data read from the stream.
*/
-public class MacInputStream extends FilterInputStream
+public class MacInputStream
+ extends FilterInputStream
{
-
- // Field.
- // ------------------------------------------------------------------------
-
- /**
- * The digesting state. The MAC is updated only if this flag is true.
- */
+ /** The digesting state. The MAC is updated only if this flag is true. */
private boolean digesting;
-
- /**
- * The MAC being updated.
- */
+ /** The MAC being updated. */
private IMac mac;
- // Constructor.
- // ------------------------------------------------------------------------
-
/**
- * Creates a new MacInputStream. The stream is initially set to digest
- * data written, the <i>mac</i> argument must have already been initialized,
- * and the <i>mac</i> argument is <b>not</b> cloned.
- *
+ * Creates a new MacInputStream. The stream is initially set to digest data
+ * written, the <i>mac</i> argument must have already been initialized, and
+ * the <i>mac</i> argument is <b>not</b> cloned.
+ *
* @param in The underlying input stream.
* @param mac The mac instance to use.
*/
@@ -82,12 +71,9 @@ public class MacInputStream extends FilterInputStream
digesting = true;
}
- // Instance methods.
- // ------------------------------------------------------------------------
-
/**
* Returns the MAC this stream is updating.
- *
+ *
* @return The MAC.
*/
public IMac getMac()
@@ -98,7 +84,7 @@ public class MacInputStream extends FilterInputStream
/**
* Sets the MAC this stream is updating, which must have already been
* initialized. The argument is not cloned by this method.
- *
+ *
* @param mac The new MAC.
* @throws NullPointerException If the argument is null.
*/
@@ -110,9 +96,9 @@ public class MacInputStream extends FilterInputStream
}
/**
- * Turns the digesting state on or off. When off, the MAC will not be
- * updated when data is written to the stream.
- *
+ * Turns the digesting state on or off. When off, the MAC will not be updated
+ * when data is written to the stream.
+ *
* @param flag The new digesting state.
*/
public void on(boolean flag)
@@ -135,4 +121,4 @@ public class MacInputStream extends FilterInputStream
mac.update(buf, off, i);
return i;
}
-} \ No newline at end of file
+}
diff --git a/gnu/javax/crypto/mac/MacOutputStream.java b/gnu/javax/crypto/mac/MacOutputStream.java
index a48d25ba3..739a78497 100644
--- a/gnu/javax/crypto/mac/MacOutputStream.java
+++ b/gnu/javax/crypto/mac/MacOutputStream.java
@@ -43,29 +43,23 @@ import java.io.IOException;
import java.io.OutputStream;
/**
- * <p>A filtering output stream that computes a MAC (message authentication
- * code) over all data written to the stream.</p>
+ * A filtering output stream that computes a MAC (message authentication code)
+ * over all data written to the stream.
*/
-public class MacOutputStream extends FilterOutputStream
+public class MacOutputStream
+ extends FilterOutputStream
{
-
- // Constants and variables
- // -------------------------------------------------------------------------
-
/** The digesting state. The MAC is updated only if this flag is true. */
private boolean digesting;
-
/** The MAC being updated. */
private IMac mac;
- // Constructor(s)
- // -------------------------------------------------------------------------
-
/**
- * <p>Creates a new <code>MacOutputStream</code>. The stream is initially set
+ * Creates a new <code>MacOutputStream</code>. The stream is initially set
* to digest data written, the <code>mac</code> argument must have already
- * been initialized, and the <code>mac</code> argument is <b>not</b> cloned.</p>
- *
+ * been initialized, and the <code>mac</code> argument is <b>not</b>
+ * cloned.
+ *
* @param out The underlying output stream.
* @param mac The mac instance to use.
*/
@@ -73,19 +67,14 @@ public class MacOutputStream extends FilterOutputStream
{
super(out);
if (mac == null)
- {
- throw new NullPointerException();
- }
+ throw new NullPointerException();
this.mac = mac;
digesting = true;
}
- // Instance methods
- // -------------------------------------------------------------------------
-
/**
- * <p>Returns the MAC this stream is updating.</p>
- *
+ * Returns the MAC this stream is updating.
+ *
* @return The MAC.
*/
public IMac getMac()
@@ -94,25 +83,23 @@ public class MacOutputStream extends FilterOutputStream
}
/**
- * <p>Sets the MAC this stream is updating, which must have already been
- * initialized. The argument is not cloned by this method.</p>
- *
+ * Sets the MAC this stream is updating, which must have already been
+ * initialized. The argument is not cloned by this method.
+ *
* @param mac The non-null new MAC.
* @throws NullPointerException If the argument is null.
*/
public void setMac(IMac mac)
{
if (mac == null)
- {
- throw new NullPointerException();
- }
+ throw new NullPointerException();
this.mac = mac;
}
/**
- * <p>Turns the digesting state on or off. When off, the MAC will not be
- * updated when data is written to the stream.</p>
- *
+ * Turns the digesting state on or off. When off, the MAC will not be updated
+ * when data is written to the stream.
+ *
* @param flag The new digesting state.
*/
public void on(boolean flag)
@@ -123,18 +110,14 @@ public class MacOutputStream extends FilterOutputStream
public void write(int b) throws IOException
{
if (digesting)
- {
- mac.update((byte) b);
- }
+ mac.update((byte) b);
out.write(b);
}
public void write(byte[] buf, int off, int len) throws IOException
{
if (digesting)
- {
- mac.update(buf, off, len);
- }
+ mac.update(buf, off, len);
out.write(buf, off, len);
}
-} \ No newline at end of file
+}
diff --git a/gnu/javax/crypto/mac/OMAC.java b/gnu/javax/crypto/mac/OMAC.java
index 21156ac63..cd753acaf 100644
--- a/gnu/javax/crypto/mac/OMAC.java
+++ b/gnu/javax/crypto/mac/OMAC.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.javax.crypto.mac;
+import gnu.java.security.Configuration;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
import gnu.javax.crypto.cipher.CipherFactory;
@@ -48,76 +49,49 @@ import java.security.InvalidKeyException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
+import java.util.logging.Logger;
/**
- * <p>The One-Key CBC MAC, OMAC. This message authentication code is based on
- * a block cipher in CBC mode.</p>
- *
- * <p>References:</p>
+ * The One-Key CBC MAC, OMAC. This message authentication code is based on a
+ * block cipher in CBC mode.
+ * <p>
+ * References:
* <ol>
* <li>Tetsu Iwata and Kaoru Kurosawa, <i><a
* href="http://crypt.cis.ibaraki.ac.jp/omac/docs/omac.pdf">OMAC: One-Key CBC
* MAC</a></i>.</li>
* </ol>
*/
-public class OMAC implements IMac
+public class OMAC
+ implements IMac
{
-
- // Constants and fields.
- // ------------------------------------------------------------------------
-
- private static final boolean DEBUG = false;
-
- private static void debug(String msg)
- {
- System.out.print(">>> OMAC: ");
- System.out.println(msg);
- }
-
+ private static final Logger log = Logger.getLogger(OMAC.class.getName());
private static final byte C1 = (byte) 0x87;
-
private static final byte C2 = 0x1b;
-
// Test key for OMAC-AES-128
- private static final byte[] KEY0 = Util.toBytesFromString("2b7e151628aed2a6abf7158809cf4f3c");
-
+ private static final byte[] KEY0 =
+ Util.toBytesFromString("2b7e151628aed2a6abf7158809cf4f3c");
// Test MAC for zero-length input.
- private static final byte[] DIGEST0 = Util.toBytesFromString("bb1d6929e95937287fa37d129b756746");
-
+ private static final byte[] DIGEST0 =
+ Util.toBytesFromString("bb1d6929e95937287fa37d129b756746");
private static Boolean valid;
-
private final IBlockCipher cipher;
-
private final String name;
-
private IMode mode;
-
private int blockSize;
-
private int outputSize;
-
private byte[] Lu, Lu2;
-
private byte[] M;
-
private byte[] Y;
-
private boolean init;
-
private int index;
- // Constructor.
- // ------------------------------------------------------------------------
-
public OMAC(IBlockCipher cipher)
{
this.cipher = cipher;
this.name = "OMAC-" + cipher.name();
}
- // Instance methods.
- // ------------------------------------------------------------------------
-
public Object clone()
{
return new OMAC(cipher);
@@ -139,135 +113,89 @@ public class OMAC implements IMac
attrib2.put(IBlockCipher.KEY_MATERIAL, attrib.get(MAC_KEY_MATERIAL));
cipher.reset();
cipher.init(attrib2);
-
blockSize = cipher.currentBlockSize();
Integer os = (Integer) attrib.get(TRUNCATED_SIZE);
if (os != null)
{
outputSize = os.intValue();
if (outputSize < 0 || outputSize > blockSize)
- {
- throw new IllegalArgumentException("truncated size out of range");
- }
+ throw new IllegalArgumentException("truncated size out of range");
}
else
- {
- outputSize = blockSize;
- }
+ outputSize = blockSize;
byte[] L = new byte[blockSize];
cipher.encryptBlock(L, 0, L, 0);
-
- if (DEBUG)
- {
- debug("L = " + Util.toString(L).toLowerCase());
- }
-
+ if (Configuration.DEBUG)
+ log.fine("L = " + Util.toString(L).toLowerCase());
if (Lu != null)
{
Arrays.fill(Lu, (byte) 0);
if (Lu.length != blockSize)
- {
- Lu = new byte[blockSize];
- }
+ Lu = new byte[blockSize];
}
else
- {
- Lu = new byte[blockSize];
- }
+ Lu = new byte[blockSize];
if (Lu2 != null)
{
Arrays.fill(Lu2, (byte) 0);
if (Lu2.length != blockSize)
- {
- Lu2 = new byte[blockSize];
- }
+ Lu2 = new byte[blockSize];
}
else
- {
- Lu2 = new byte[blockSize];
- }
+ Lu2 = new byte[blockSize];
boolean msb = (L[0] & 0x80) != 0;
for (int i = 0; i < blockSize; i++)
{
- Lu[i] = (byte) (L[i] << 1 & 0xFF);
+ Lu[i] = (byte)(L[i] << 1 & 0xFF);
if (i + 1 < blockSize)
- {
- Lu[i] |= (byte) ((L[i + 1] & 0x80) >> 7);
- }
+ Lu[i] |= (byte)((L[i + 1] & 0x80) >> 7);
}
if (msb)
{
if (blockSize == 16)
- {
- Lu[Lu.length - 1] ^= C1;
- }
+ Lu[Lu.length - 1] ^= C1;
else if (blockSize == 8)
- {
- Lu[Lu.length - 1] ^= C2;
- }
+ Lu[Lu.length - 1] ^= C2;
else
- {
- throw new IllegalArgumentException(
- "unsupported cipher block size: "
- + blockSize);
- }
+ throw new IllegalArgumentException("unsupported cipher block size: "
+ + blockSize);
}
- if (DEBUG)
- {
- debug("Lu = " + Util.toString(Lu).toLowerCase());
- }
-
+ if (Configuration.DEBUG)
+ log.fine("Lu = " + Util.toString(Lu).toLowerCase());
msb = (Lu[0] & 0x80) != 0;
for (int i = 0; i < blockSize; i++)
{
- Lu2[i] = (byte) (Lu[i] << 1 & 0xFF);
+ Lu2[i] = (byte)(Lu[i] << 1 & 0xFF);
if (i + 1 < blockSize)
- {
- Lu2[i] |= (byte) ((Lu[i + 1] & 0x80) >> 7);
- }
+ Lu2[i] |= (byte)((Lu[i + 1] & 0x80) >> 7);
}
if (msb)
{
if (blockSize == 16)
- {
- Lu2[Lu2.length - 1] ^= C1;
- }
+ Lu2[Lu2.length - 1] ^= C1;
else
- {
- Lu2[Lu2.length - 1] ^= C2;
- }
+ Lu2[Lu2.length - 1] ^= C2;
}
- if (DEBUG)
- {
- debug("Lu2 = " + Util.toString(Lu2).toLowerCase());
- }
-
+ if (Configuration.DEBUG)
+ log.fine("Lu2 = " + Util.toString(Lu2).toLowerCase());
if (M != null)
{
Arrays.fill(M, (byte) 0);
if (M.length != blockSize)
- {
- M = new byte[blockSize];
- }
+ M = new byte[blockSize];
}
else
- {
- M = new byte[blockSize];
- }
+ M = new byte[blockSize];
if (Y != null)
{
Arrays.fill(Y, (byte) 0);
if (Y.length != blockSize)
- {
- Y = new byte[blockSize];
- }
+ Y = new byte[blockSize];
}
else
- {
- Y = new byte[blockSize];
- }
+ Y = new byte[blockSize];
index = 0;
init = true;
@@ -275,10 +203,8 @@ public class OMAC implements IMac
public void update(byte b)
{
- if (!init)
- {
- throw new IllegalStateException("not initialized");
- }
+ if (! init)
+ throw new IllegalStateException("not initialized");
if (index == M.length)
{
process();
@@ -289,15 +215,11 @@ public class OMAC implements IMac
public void update(byte[] buf, int off, int len)
{
- if (!init)
- {
- throw new IllegalStateException("not initialized");
- }
+ if (! init)
+ throw new IllegalStateException("not initialized");
if (off < 0 || len < 0 || off + len > buf.length)
- {
- throw new IndexOutOfBoundsException("size=" + buf.length + "; off="
- + off + "; len=" + len);
- }
+ throw new IndexOutOfBoundsException("size=" + buf.length + "; off=" + off
+ + "; len=" + len);
for (int i = 0; i < len;)
{
if (index == blockSize)
@@ -321,30 +243,22 @@ public class OMAC implements IMac
public void digest(byte[] out, int off)
{
- if (!init)
- {
- throw new IllegalStateException("not initialized");
- }
+ if (! init)
+ throw new IllegalStateException("not initialized");
if (off < 0 || off + outputSize > out.length)
- {
- throw new IndexOutOfBoundsException("size=" + out.length + "; off="
- + off + "; len=" + outputSize);
- }
+ throw new IndexOutOfBoundsException("size=" + out.length + "; off=" + off
+ + "; len=" + outputSize);
byte[] T = new byte[blockSize];
byte[] L = Lu;
if (index < blockSize)
{
M[index++] = (byte) 0x80;
while (index < blockSize)
- {
- M[index++] = 0;
- }
+ M[index++] = 0;
L = Lu2;
}
for (int i = 0; i < blockSize; i++)
- {
- T[i] = (byte) (M[i] ^ Y[i] ^ L[i]);
- }
+ T[i] = (byte)(M[i] ^ Y[i] ^ L[i]);
cipher.encryptBlock(T, 0, T, 0);
System.arraycopy(T, 0, out, off, outputSize);
reset();
@@ -354,13 +268,9 @@ public class OMAC implements IMac
{
index = 0;
if (Y != null)
- {
- Arrays.fill(Y, (byte) 0);
- }
+ Arrays.fill(Y, (byte) 0);
if (M != null)
- {
- Arrays.fill(M, (byte) 0);
- }
+ Arrays.fill(M, (byte) 0);
}
public boolean selfTest()
@@ -380,21 +290,14 @@ public class OMAC implements IMac
return false;
}
if (digest == null)
- {
- return false;
- }
+ return false;
return Arrays.equals(DIGEST0, digest);
}
- // Own methods.
- // ------------------------------------------------------------------------
-
private void process()
{
for (int i = 0; i < blockSize; i++)
- {
- M[i] = (byte) (M[i] ^ Y[i]);
- }
+ M[i] = (byte)(M[i] ^ Y[i]);
cipher.encryptBlock(M, 0, Y, 0);
}
-} \ No newline at end of file
+}
diff --git a/gnu/javax/crypto/mac/TMMH16.java b/gnu/javax/crypto/mac/TMMH16.java
index af6e78fcf..0a7b4a6ca 100644
--- a/gnu/javax/crypto/mac/TMMH16.java
+++ b/gnu/javax/crypto/mac/TMMH16.java
@@ -46,91 +46,63 @@ import java.security.InvalidKeyException;
import java.util.Map;
/**
- * <p><i>TMMH</i> is a <i>universal</i> hash function suitable for message
+ * <i>TMMH</i> is a <i>universal</i> hash function suitable for message
* authentication in the Wegman-Carter paradigm, as in the Stream Cipher
* Security Transform. It is simple, quick, and especially appropriate for
* Digital Signal Processors and other processors with a fast multiply
* operation, though a straightforward implementation requires storage equal in
- * length to the largest message to be hashed.</p>
- *
- * <p><i>TMMH</i> is a simple hash function which maps a key and a message to a
+ * length to the largest message to be hashed.
+ * <p>
+ * <i>TMMH</i> is a simple hash function which maps a key and a message to a
* hash value. There are two versions of TMMH: TMMH/16 and TMMH/32. <i>TMMH</i>
* can be used as a message authentication code, as described in Section 5 (see
- * References).</p>
- *
- * <p>The key, message, and hash value are all octet strings, and the lengths of
+ * References).
+ * <p>
+ * The key, message, and hash value are all octet strings, and the lengths of
* these quantities are denoted as <code>KEY_LENGTH</code>,
- * <code>MESSAGE_LENGTH</code>, and <code>TAG_LENGTH</code>, respectively. The
- * values of <code>KEY_LENGTH</code> and <code>TAG_LENGTH</code>
+ * <code>MESSAGE_LENGTH</code>, and <code>TAG_LENGTH</code>, respectively.
+ * The values of <code>KEY_LENGTH</code> and <code>TAG_LENGTH</code>
* <bold>MUST</bold> be fixed for any particular fixed value of the key, and
- * must obey the alignment restrictions described below.</p>
- *
- * <p>The parameter <code>MAX_HASH_LENGTH</code>, which denotes the maximum
+ * must obey the alignment restrictions described below.
+ * <p>
+ * The parameter <code>MAX_HASH_LENGTH</code>, which denotes the maximum
* value which <code>MESSAGE_LENGTH</code> may take, is equal to
- * <code>KEY_LENGTH - TAG_LENGTH</code>.</p>
- *
- * <p>References:</p>
- *
+ * <code>KEY_LENGTH - TAG_LENGTH</code>.
+ * <p>
+ * References:
* <ol>
- * <li><a
- href="http://www.ietf.org/internet-drafts/draft-mcgrew-saag-tmmh-01.txt">
- * The Truncated Multi-Modular Hash Function (TMMH)</a>, David A. McGrew.</li>
+ * <li><a
+ * href="http://www.ietf.org/internet-drafts/draft-mcgrew-saag-tmmh-01.txt"> The
+ * Truncated Multi-Modular Hash Function (TMMH)</a>, David A. McGrew.</li>
* </ol>
*/
-public class TMMH16 extends BaseMac implements Cloneable
+public class TMMH16
+ extends BaseMac
+ implements Cloneable
{
-
- // Constants and variables
- // -------------------------------------------------------------------------
-
public static final String TAG_LENGTH = "gnu.crypto.mac.tmmh.tag.length";
-
public static final String KEYSTREAM = "gnu.crypto.mac.tmmh.keystream";
-
public static final String PREFIX = "gnu.crypto.mac.tmmh.prefix";
-
private static final int P = (1 << 16) + 1; // the TMMH/16 prime
-
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
-
private int tagWords = 0; // the tagLength expressed in words
-
private IRandom keystream = null; // the keystream generator
-
private byte[] prefix; // mask to use when operating as an authentication f.
-
private long keyWords; // key words counter
-
private long msgLength; // in bytes
-
private long msgWords; // should be = msgLength * WORD_LENGTH
-
private int[] context; // the tmmh running context; length == TAG_WORDS
-
private int[] K0; // the first TAG_WORDS words of the keystream
-
private int[] Ki; // the sliding TAG_WORDS words of the keystream
-
private int Mi; // current message word being constructed
- // Constructor(s)
- // -------------------------------------------------------------------------
-
/** Trivial 0-arguments constructor. */
public TMMH16()
{
super(Registry.TMMH16);
}
- // Class methods
- // -------------------------------------------------------------------------
-
- // Instance methods
- // -------------------------------------------------------------------------
-
- // gnu.crypto.mac.IMac interface implementation ----------------------------
-
public int macSize()
{
return tagWords * 2;
@@ -143,22 +115,17 @@ public class TMMH16 extends BaseMac implements Cloneable
Integer tagLength = (Integer) attributes.get(TAG_LENGTH); // get tag length
if (tagLength == null)
{
- if (tagWords == 0)
- { // was never set
- throw new IllegalArgumentException(TAG_LENGTH);
- } // else re-use
+ if (tagWords == 0) // was never set
+ throw new IllegalArgumentException(TAG_LENGTH);
+ // else re-use
}
- else
- { // check if positive and is divisible by WORD_LENGTH
+ else // check if positive and is divisible by WORD_LENGTH
+ {
wantTagLength = tagLength.intValue();
if (wantTagLength < 2 || (wantTagLength % 2 != 0))
- {
- throw new IllegalArgumentException(TAG_LENGTH);
- }
- else if (wantTagLength > (512 / 8))
- { // 512-bits is our maximum
- throw new IllegalArgumentException(TAG_LENGTH);
- }
+ throw new IllegalArgumentException(TAG_LENGTH);
+ else if (wantTagLength > (512 / 8)) // 512-bits is our maximum
+ throw new IllegalArgumentException(TAG_LENGTH);
tagWords = wantTagLength / 2; // init local vars
K0 = new int[tagWords];
@@ -167,36 +134,27 @@ public class TMMH16 extends BaseMac implements Cloneable
}
prefix = (byte[]) attributes.get(PREFIX);
- if (prefix == null)
- { // default to all-zeroes
- prefix = new byte[tagWords * 2];
- }
- else
- { // ensure it's as long as it should
+ if (prefix == null) // default to all-zeroes
+ prefix = new byte[tagWords * 2];
+ else // ensure it's as long as it should
+ {
if (prefix.length != tagWords * 2)
- {
- throw new IllegalArgumentException(PREFIX);
- }
+ throw new IllegalArgumentException(PREFIX);
}
IRandom prng = (IRandom) attributes.get(KEYSTREAM); // get keystream
if (prng == null)
{
if (keystream == null)
- {
- throw new IllegalArgumentException(KEYSTREAM);
- } // else reuse
+ throw new IllegalArgumentException(KEYSTREAM);
+ // else reuse
}
else
- {
- keystream = prng;
- }
+ keystream = prng;
reset(); // reset context variables
- for (int i = 0; i < tagWords; i++)
- { // init starting key words
- Ki[i] = K0[i] = getNextKeyWord(keystream);
- }
+ for (int i = 0; i < tagWords; i++) // init starting key words
+ Ki[i] = K0[i] = getNextKeyWord(keystream);
}
// The words of the key are denoted as K[1], K[2], ..., K[KEY_WORDS], and the
@@ -206,12 +164,12 @@ public class TMMH16 extends BaseMac implements Cloneable
//
// If MESSAGE_LENGTH is greater than MAX_HASH_LENGTH, then the value of
// TMMH/16 is undefined. Implementations MUST indicate an error if asked to
- // hash a message with such a length. Otherwise, the hash value is defined
+ // hash a message with such a length. Otherwise, the hash value is defined
// to be the length TAG_WORDS sequence of words in which the j-th word in the
// sequence is defined as
//
// [ [ K[j] * MESSAGE_LENGTH +32 K[j+1] * M[1] +32 K[j+2] * M[2]
- // +32 ... K[j+MSG_WORDS] * M[MSG_WORDS] ] modulo p ] modulo 2^16
+ // +32 ... K[j+MSG_WORDS] * M[MSG_WORDS] ] modulo p ] modulo 2^16
//
// where j ranges from 1 to TAG_WORDS.
public void update(byte b)
@@ -222,23 +180,21 @@ public class TMMH16 extends BaseMac implements Cloneable
public void update(byte[] b, int offset, int len)
{
for (int i = 0; i < len; i++)
- {
- this.update(b[offset + i], keystream);
- }
+ this.update(b[offset + i], keystream);
}
// For TMMH/16, KEY_LENGTH and TAG_LENGTH MUST be a multiple of two. The key,
// message, and hash value are treated as a sequence of unsigned sixteen bit
- // integers in network byte order. (In this section, we call such an integer
- // a word.) If MESSAGE_LENGTH is odd, then a zero byte is appended to the
+ // integers in network byte order. (In this section, we call such an integer
+ // a word.) If MESSAGE_LENGTH is odd, then a zero byte is appended to the
// message to align it on a word boundary, though this process does not
// change the value of MESSAGE_LENGTH.
//
- // ... Otherwise, the hash value is defined to be the length TAG_WORDS
+ // ... Otherwise, the hash value is defined to be the length TAG_WORDS
// sequence of words in which the j-th word in the sequence is defined as
//
// [ [ K[j] * MESSAGE_LENGTH +32 K[j+1] * M[1] +32 K[j+2] * M[2]
- // +32 ... K[j+MSG_WORDS] * M[MSG_WORDS] ] modulo p ] modulo 2^16
+ // +32 ... K[j+MSG_WORDS] * M[MSG_WORDS] ] modulo p ] modulo 2^16
//
// where j ranges from 1 to TAG_WORDS.
//
@@ -255,9 +211,7 @@ public class TMMH16 extends BaseMac implements Cloneable
msgLength = msgWords = keyWords = 0L;
Mi = 0;
for (int i = 0; i < tagWords; i++)
- {
- context[i] = 0;
- }
+ context[i] = 0;
}
public boolean selfTest()
@@ -265,42 +219,31 @@ public class TMMH16 extends BaseMac implements Cloneable
if (valid == null)
{
// TODO: compute and test equality with one known vector
-
valid = Boolean.TRUE;
}
return valid.booleanValue();
}
- // Cloneable interface implementation ---------------------------------------
-
public Object clone() throws CloneNotSupportedException
{
TMMH16 result = (TMMH16) super.clone();
-
if (this.keystream != null)
result.keystream = (IRandom) this.keystream.clone();
-
if (this.prefix != null)
result.prefix = (byte[]) this.prefix.clone();
-
if (this.context != null)
result.context = (int[]) this.context.clone();
-
if (this.K0 != null)
result.K0 = (int[]) this.K0.clone();
-
if (this.Ki != null)
result.Ki = (int[]) this.Ki.clone();
-
return result;
}
- // own methods -------------------------------------------------------------
-
/**
- * <p>Similar to the same method with one argument, but uses the designated
- * random number generator to compute needed keying material.</p>
- *
+ * Similar to the same method with one argument, but uses the designated
+ * random number generator to compute needed keying material.
+ *
* @param b the byte to process.
* @param prng the source of randomness to use.
*/
@@ -309,14 +252,14 @@ public class TMMH16 extends BaseMac implements Cloneable
Mi <<= 8; // update message buffer
Mi |= b & 0xFF;
msgLength++; // update message length (bytes)
- if (msgLength % 2 == 0)
- { // got a full word
+ if (msgLength % 2 == 0) // got a full word
+ {
msgWords++; // update message words counter
System.arraycopy(Ki, 1, Ki, 0, tagWords - 1); // 1. shift Ki up by 1
Ki[tagWords - 1] = getNextKeyWord(prng); // 2. fill last box of Ki
long t; // temp var to allow working in modulo 2^32
- for (int i = 0; i < tagWords; i++)
- { // 3. update context
+ for (int i = 0; i < tagWords; i++) // 3. update context
+ {
t = context[i] & 0xFFFFFFFFL;
t += Ki[i] * Mi;
context[i] = (int) t;
@@ -326,28 +269,26 @@ public class TMMH16 extends BaseMac implements Cloneable
}
/**
- * <p>Similar to the same method with three arguments, but uses the
- * designated random number generator to compute needed keying material.</p>
- *
+ * Similar to the same method with three arguments, but uses the designated
+ * random number generator to compute needed keying material.
+ *
* @param b the byte array to process.
* @param offset the starting offset in <code>b</code> to start considering
- * the bytes to process.
+ * the bytes to process.
* @param len the number of bytes in <code>b</code> starting from
- * <code>offset</code> to process.
+ * <code>offset</code> to process.
* @param prng the source of randomness to use.
*/
public void update(byte[] b, int offset, int len, IRandom prng)
{
for (int i = 0; i < len; i++)
- {
- this.update(b[offset + i], prng);
- }
+ this.update(b[offset + i], prng);
}
/**
- * <p>Similar to the same method with no arguments, but uses the designated
- * random number generator to compute needed keying material.</p>
- *
+ * Similar to the same method with no arguments, but uses the designated
+ * random number generator to compute needed keying material.
+ *
* @param prng the source of randomness to use.
* @return the final result of the algorithm.
*/
@@ -357,12 +298,11 @@ public class TMMH16 extends BaseMac implements Cloneable
byte[] result = new byte[tagWords * 2];
for (int i = 0, j = 0; i < tagWords; i++)
{
- result[j] = (byte) ((context[i] >>> 8) ^ prefix[j]);
+ result[j] = (byte)((context[i] >>> 8) ^ prefix[j]);
j++;
- result[j] = (byte) (context[i] ^ prefix[j]);
+ result[j] = (byte)(context[i] ^ prefix[j]);
j++;
}
-
reset();
return result;
}
@@ -378,7 +318,6 @@ public class TMMH16 extends BaseMac implements Cloneable
{
throw new RuntimeException(String.valueOf(x));
}
-
keyWords++; // update key words counter
return result;
}
@@ -387,9 +326,7 @@ public class TMMH16 extends BaseMac implements Cloneable
{
long limit = msgLength; // formula works on real message length
while (msgLength % 2 != 0)
- {
- update((byte) 0x00, prng);
- }
+ update((byte) 0x00, prng);
long t;
for (int i = 0; i < tagWords; i++)
{
diff --git a/gnu/javax/crypto/mac/UHash32.java b/gnu/javax/crypto/mac/UHash32.java
index 8abb0255e..737e9ce24 100644
--- a/gnu/javax/crypto/mac/UHash32.java
+++ b/gnu/javax/crypto/mac/UHash32.java
@@ -40,7 +40,6 @@ package gnu.javax.crypto.mac;
import gnu.java.security.prng.IRandom;
import gnu.java.security.prng.LimitReachedException;
-
import gnu.javax.crypto.cipher.IBlockCipher;
import gnu.javax.crypto.prng.UMacGenerator;
@@ -51,103 +50,63 @@ import java.util.HashMap;
import java.util.Map;
/**
- * <p><i>UHASH</i> is a keyed hash function, which takes as input a string of
+ * <i>UHASH</i> is a keyed hash function, which takes as input a string of
* arbitrary length, and produces as output a string of fixed length (such as 8
- * bytes). The actual output length depends on the parameter UMAC-OUTPUT-LEN.</p>
- *
- * <p><i>UHASH</i> has been shown to be <i>epsilon-ASU</i> ("Almost Strongly
+ * bytes). The actual output length depends on the parameter UMAC-OUTPUT-LEN.
+ * <p>
+ * <i>UHASH</i> has been shown to be <i>epsilon-ASU</i> ("Almost Strongly
* Universal"), where epsilon is a small (parameter-dependent) real number.
* Informally, saying that a keyed hash function is <i>epsilon-ASU</i> means
* that for any two distinct fixed input strings, the two outputs of the hash
* function with a random key "look almost like a pair of random strings". The
- * number epsilon measures how non-random the output strings may be.</p>
- *
- * <i>UHASH</i> has been designed to be fast by exploiting several architectural
- * features of modern commodity processors. It was specifically designed for use
- * in <i>UMAC</i>. But <i>UHASH</i> is useful beyond that domain, and can be
- * easily adopted for other purposes.</p>
- *
+ * number epsilon measures how non-random the output strings may be.
+ * <p>
+ * <i>UHASH</i> has been designed to be fast by exploiting several
+ * architectural features of modern commodity processors. It was specifically
+ * designed for use in <i>UMAC</i>. But <i>UHASH</i> is useful beyond that
+ * domain, and can be easily adopted for other purposes.
+ * <p>
* <i>UHASH</i> does its work in three layers. First, a hash function called
* <code>NH</code> is used to compress input messages into strings which are
* typically many times smaller than the input message. Second, the compressed
* message is hashed with an optimized <i>polynomial hash function</i> into a
* fixed-length 16-byte string. Finally, the 16-byte string is hashed using an
- * <i>inner-product hash</i> into a string of length WORD-LEN bytes. These three
- * layers are repeated (with a modified key) until the outputs total
- * UMAC-OUTPUT-LEN bytes.</p>
- *
- * <p>References:</p>
- *
+ * <i>inner-product hash</i> into a string of length WORD-LEN bytes. These
+ * three layers are repeated (with a modified key) until the outputs total
+ * UMAC-OUTPUT-LEN bytes.
+ * <p>
+ * References:
* <ol>
- * <li><a href="http://www.ietf.org/internet-drafts/draft-krovetz-umac-01.txt">
- * UMAC</a>: Message Authentication Code using Universal Hashing.<br>
- * T. Krovetz, J. Black, S. Halevi, A. Hevia, H. Krawczyk, and P. Rogaway.</li>
+ * <li><a href="http://www.ietf.org/internet-drafts/draft-krovetz-umac-01.txt">
+ * UMAC</a>: Message Authentication Code using Universal Hashing.<br>
+ * T. Krovetz, J. Black, S. Halevi, A. Hevia, H. Krawczyk, and P. Rogaway.</li>
* </ol>
*/
-public class UHash32 extends BaseMac
+public class UHash32
+ extends BaseMac
{
-
- // Constants and variables
- // -------------------------------------------------------------------------
-
// UMAC prime values
private static final BigInteger PRIME_19 = BigInteger.valueOf(0x7FFFFL);
-
private static final BigInteger PRIME_32 = BigInteger.valueOf(0xFFFFFFFBL);
-
private static final BigInteger PRIME_36 = BigInteger.valueOf(0xFFFFFFFFBL);
-
- private static final BigInteger PRIME_64 = new BigInteger(
- 1,
- new byte[] {
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xC5 });
-
- private static final BigInteger PRIME_128 = new BigInteger(
- 1,
- new byte[] {
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0xFF,
- (byte) 0x61 });
-
+ private static final BigInteger PRIME_64 = new BigInteger(1, new byte[] {
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xC5 });
+ private static final BigInteger PRIME_128 = new BigInteger(1, new byte[] {
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+ (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x61 });
static final BigInteger TWO = BigInteger.valueOf(2L);
-
static final long BOUNDARY = TWO.shiftLeft(17).longValue();
-
// 2**64 - 2**32
static final BigInteger LOWER_RANGE = TWO.pow(64).subtract(TWO.pow(32));
-
// 2**128 - 2**96
static final BigInteger UPPER_RANGE = TWO.pow(128).subtract(TWO.pow(96));
-
static final byte[] ALL_ZEROES = new byte[32];
-
int streams;
-
L1Hash32[] l1hash;
- // Constructor(s)
- // -------------------------------------------------------------------------
-
/** Trivial 0-arguments constructor. */
public UHash32()
{
@@ -155,7 +114,7 @@ public class UHash32 extends BaseMac
}
/**
- * <p>Private constructor for cloning purposes.</p>
+ * Private constructor for cloning purposes.
*
* @param that the instance to clone.
*/
@@ -166,24 +125,15 @@ public class UHash32 extends BaseMac
this.streams = that.streams;
if (that.l1hash != null)
{
- // this.l1hash = new L1Hash32[that.l1hash.length];
this.l1hash = new L1Hash32[that.streams];
- // for (int i = 0; i < that.l1hash.length; i++) {
for (int i = 0; i < that.streams; i++)
- {
- if (that.l1hash[i] != null)
- {
- this.l1hash[i] = (L1Hash32) that.l1hash[i].clone();
- }
- }
+ if (that.l1hash[i] != null)
+ this.l1hash[i] = (L1Hash32) that.l1hash[i].clone();
}
}
- // Class methods
- // -------------------------------------------------------------------------
-
/**
- * <p>The prime numbers used in UMAC are:</p>
+ * The prime numbers used in UMAC are:
* <pre>
* +-----+--------------------+---------------------------------------+
* | x | prime(x) [Decimal] | prime(x) [Hexadecimal] |
@@ -219,18 +169,11 @@ public class UHash32 extends BaseMac
}
}
- // Instance methods
- // -------------------------------------------------------------------------
-
- // java.lang.Cloneable interface implementation ----------------------------
-
public Object clone()
{
return new UHash32(this);
}
- // gnu.crypto.mac.IMac interface implementation ----------------------------
-
public int macSize()
{
return UMac32.OUTPUT_LEN;
@@ -241,18 +184,12 @@ public class UHash32 extends BaseMac
{
byte[] K = (byte[]) attributes.get(MAC_KEY_MATERIAL);
if (K == null)
- {
- throw new InvalidKeyException("Null Key");
- }
+ throw new InvalidKeyException("Null Key");
if (K.length != UMac32.KEY_LEN)
- {
- throw new InvalidKeyException("Invalid Key length: "
- + String.valueOf(K.length));
- }
-
+ throw new InvalidKeyException("Invalid Key length: "
+ + String.valueOf(K.length));
// Calculate iterations needed to make UMAC-OUTPUT-LEN bytes
streams = (UMac32.OUTPUT_LEN + 3) / 4;
-
// Define total key needed for all iterations using UMacGenerator.
// L1Key and L3Key1 both reuse most key between iterations.
IRandom kdf1 = new UMacGenerator();
@@ -261,15 +198,14 @@ public class UHash32 extends BaseMac
IRandom kdf4 = new UMacGenerator();
Map map = new HashMap();
map.put(IBlockCipher.KEY_MATERIAL, K);
- map.put(UMacGenerator.INDEX, new Integer(0));
+ map.put(UMacGenerator.INDEX, Integer.valueOf(0));
kdf1.init(map);
- map.put(UMacGenerator.INDEX, new Integer(1));
+ map.put(UMacGenerator.INDEX, Integer.valueOf(1));
kdf2.init(map);
- map.put(UMacGenerator.INDEX, new Integer(2));
+ map.put(UMacGenerator.INDEX, Integer.valueOf(2));
kdf3.init(map);
- map.put(UMacGenerator.INDEX, new Integer(3));
+ map.put(UMacGenerator.INDEX, Integer.valueOf(3));
kdf4.init(map);
-
// need to generate all bytes for use later in a Toepliz construction
byte[] L1Key = new byte[UMac32.L1_KEY_LEN + (streams - 1) * 16];
try
@@ -297,7 +233,6 @@ public class UHash32 extends BaseMac
x.printStackTrace(System.err);
throw new RuntimeException("KDF for L2Key reached limit");
}
-
byte[] k31 = new byte[64];
try
{
@@ -308,7 +243,6 @@ public class UHash32 extends BaseMac
x.printStackTrace(System.err);
throw new RuntimeException("KDF for L3Key1 reached limit");
}
-
byte[] k32 = new byte[4];
try
{
@@ -319,7 +253,6 @@ public class UHash32 extends BaseMac
x.printStackTrace(System.err);
throw new RuntimeException("KDF for L3Key2 reached limit");
}
-
L1Hash32 mac = new L1Hash32();
mac.init(k1, k2, k31, k32);
l1hash[i] = mac;
@@ -329,17 +262,13 @@ public class UHash32 extends BaseMac
public void update(byte b)
{
for (int i = 0; i < streams; i++)
- {
- l1hash[i].update(b);
- }
+ l1hash[i].update(b);
}
public void update(byte[] b, int offset, int len)
{
for (int i = 0; i < len; i++)
- {
- this.update(b[offset + i]);
- }
+ this.update(b[offset + i]);
}
public byte[] digest()
@@ -357,9 +286,7 @@ public class UHash32 extends BaseMac
public void reset()
{
for (int i = 0; i < streams; i++)
- {
- l1hash[i].reset();
- }
+ l1hash[i].reset();
}
public boolean selfTest()
@@ -367,38 +294,20 @@ public class UHash32 extends BaseMac
return true;
}
- // helper methods ----------------------------------------------------------
-
- // Inner classes
- // =========================================================================
-
/**
* First hash stage of the UHash32 algorithm.
*/
- class L1Hash32 implements Cloneable
+ class L1Hash32
+ implements Cloneable
{
-
- // Constants and variables
- // ----------------------------------------------------------------------
-
private int[] key; // key material as an array of 32-bit ints
-
private byte[] buffer; // work buffer L1_KEY_LEN long
-
private int count; // meaningful bytes in buffer
-
private ByteArrayOutputStream Y;
-
- // private byte[] y;
private long totalCount;
-
private L2Hash32 l2hash;
-
private L3Hash32 l3hash;
- // Constructor(s)
- // ----------------------------------------------------------------------
-
/** Trivial 0-arguments constructor. */
L1Hash32()
{
@@ -412,7 +321,7 @@ public class UHash32 extends BaseMac
}
/**
- * <p>Private constructor for cloning purposes.</p>
+ * Private constructor for cloning purposes.
*
* @param that the instance to clone.
*/
@@ -427,38 +336,23 @@ public class UHash32 extends BaseMac
this.Y.write(otherY, 0, otherY.length);
this.totalCount = that.totalCount;
if (that.l2hash != null)
- {
- this.l2hash = (L2Hash32) that.l2hash.clone();
- }
+ this.l2hash = (L2Hash32) that.l2hash.clone();
if (that.l3hash != null)
- {
- this.l3hash = (L3Hash32) that.l3hash.clone();
- }
+ this.l3hash = (L3Hash32) that.l3hash.clone();
}
- // Class methods
- // ----------------------------------------------------------------------
-
- // Instance methods
- // ----------------------------------------------------------------------
-
- // java.lang.Cloneable interface implementation -------------------------
-
public Object clone()
{
return new L1Hash32(this);
}
- // other instance methods -----------------------------------------------
-
public void init(byte[] k1, byte[] k2, byte[] k31, byte[] k32)
{
for (int i = 0, j = 0; i < (UMac32.L1_KEY_LEN / 4); i++)
- {
- key[i] = k1[j++] << 24 | (k1[j++] & 0xFF) << 16
- | (k1[j++] & 0xFF) << 8 | (k1[j++] & 0xFF);
- }
-
+ key[i] = k1[j++] << 24
+ | (k1[j++] & 0xFF) << 16
+ | (k1[j++] & 0xFF) << 8
+ | (k1[j++] & 0xFF);
l2hash = new L2Hash32(k2);
l3hash = new L3Hash32(k31, k32);
}
@@ -484,8 +378,8 @@ public class UHash32 extends BaseMac
// For each iteration, extract key and three-layer hash.
// If length(M) <= L1_KEY_LEN, then skip L2-HASH.
- if (Y.size() == 16)
- { // we already hashed twice L1_KEY_LEN
+ if (Y.size() == 16) // we already hashed twice L1_KEY_LEN
+ {
byte[] A = Y.toByteArray();
Y.reset();
l2hash.update(A, 0, 16);
@@ -508,19 +402,16 @@ public class UHash32 extends BaseMac
byte[] y = nh32(count);
Y.write(y, 0, 8);
}
-
byte[] A = Y.toByteArray();
Y.reset();
byte[] B;
if (totalCount <= UMac32.L1_KEY_LEN)
{
// we might have 'update'd the bytes already. check
- if (A.length == 0)
- { // we did
- B = l2hash.digest();
- }
- else
- { // did not
+ if (A.length == 0) // we did
+ B = l2hash.digest();
+ else // did not
+ {
B = new byte[16];
System.arraycopy(A, 0, B, 8, 8);
}
@@ -528,12 +419,9 @@ public class UHash32 extends BaseMac
else
{
if (A.length != 0)
- {
- l2hash.update(A, 0, A.length);
- }
+ l2hash.update(A, 0, A.length);
B = l2hash.digest();
}
-
byte[] result = l3hash.digest(B);
reset();
return result;
@@ -545,13 +433,9 @@ public class UHash32 extends BaseMac
Y.reset();
totalCount = 0L;
if (l2hash != null)
- {
- l2hash.reset();
- }
+ l2hash.reset();
}
- // helper methods -------------------------------------------------------
-
/**
* 5.1 NH-32: NH hashing with a 32-bit word size.
*
@@ -562,116 +446,87 @@ public class UHash32 extends BaseMac
{
// Break M and K into 4-byte chunks
int t = len / 4;
-
// Let M_1, M_2, ..., M_t be 4-byte strings
// so that M = M_1 || M_2 || .. || M_t.
// Let K_1, K_2, ..., K_t be 4-byte strings
// so that K_1 || K_2 || .. || K_t is a prefix of K.
int[] m = new int[t];
-
int i;
int j = 0;
for (i = 0, j = 0; i < t; i++)
- {
- m[i] = buffer[j++] << 24 | (buffer[j++] & 0xFF) << 16
- | (buffer[j++] & 0xFF) << 8 | (buffer[j++] & 0xFF);
- }
-
+ m[i] = buffer[j++] << 24
+ | (buffer[j++] & 0xFF) << 16
+ | (buffer[j++] & 0xFF) << 8
+ | (buffer[j++] & 0xFF);
// Perform NH hash on the chunks, pairing words for multiplication
// which are 4 apart to accommodate vector-parallelism.
long result = len * 8L;
for (i = 0; i < t; i += 8)
{
result += ((m[i + 0] + key[i + 0]) & 0xFFFFFFFFL)
- * ((m[i + 4] + key[i + 4]) & 0xFFFFFFFFL);
+ * ((m[i + 4] + key[i + 4]) & 0xFFFFFFFFL);
result += ((m[i + 1] + key[i + 1]) & 0xFFFFFFFFL)
- * ((m[i + 5] + key[i + 5]) & 0xFFFFFFFFL);
+ * ((m[i + 5] + key[i + 5]) & 0xFFFFFFFFL);
result += ((m[i + 2] + key[i + 2]) & 0xFFFFFFFFL)
- * ((m[i + 6] + key[i + 6]) & 0xFFFFFFFFL);
+ * ((m[i + 6] + key[i + 6]) & 0xFFFFFFFFL);
result += ((m[i + 3] + key[i + 3]) & 0xFFFFFFFFL)
- * ((m[i + 7] + key[i + 7]) & 0xFFFFFFFFL);
+ * ((m[i + 7] + key[i + 7]) & 0xFFFFFFFFL);
}
-
- return new byte[] { (byte) (result >>> 56), (byte) (result >>> 48),
- (byte) (result >>> 40), (byte) (result >>> 32),
- (byte) (result >>> 24), (byte) (result >>> 16),
- (byte) (result >>> 8), (byte) result };
+ return new byte[] {
+ (byte)(result >>> 56), (byte)(result >>> 48),
+ (byte)(result >>> 40), (byte)(result >>> 32),
+ (byte)(result >>> 24), (byte)(result >>> 16),
+ (byte)(result >>> 8), (byte) result };
}
}
- // =========================================================================
-
/**
- * <p>Second hash stage of the UHash32 algorithm.</p>
- *
- * 5.4 L2-HASH-32: Second-layer hash.<p>
+ * Second hash stage of the UHash32 algorithm.
+ * <p>
+ * 5.4 L2-HASH-32: Second-layer hash.
* <ul>
- * <li>Input:<br>
- * K string of length 24 bytes.<br>
- * M string of length less than 2^64 bytes.</li>
- * <li>Returns:<br>
- * Y, string of length 16 bytes.</li>
+ * <li>Input:<br>
+ * K string of length 24 bytes.<br>
+ * M string of length less than 2^64 bytes.</li>
+ * <li>Returns:<br>
+ * Y, string of length 16 bytes.</li>
* </ul>
*/
- class L2Hash32 implements Cloneable
+ class L2Hash32
+ implements Cloneable
{
-
- // Constants and variables
- // ----------------------------------------------------------------------
-
private BigInteger k64, k128;
-
private BigInteger y;
-
private boolean highBound;
-
private long bytesSoFar;
-
private ByteArrayOutputStream buffer;
- // Constructor(s)
- // ----------------------------------------------------------------------
-
L2Hash32(byte[] K)
{
super();
if (K.length != 24)
- {
- throw new ExceptionInInitializerError("K length is not 24");
- }
-
+ throw new ExceptionInInitializerError("K length is not 24");
// Extract keys and restrict to special key-sets
// Mask64 = uint2str(0x01FFFFFF01FFFFFF, 8);
// Mask128 = uint2str(0x01FFFFFF01FFFFFF01FFFFFF01FFFFFF, 16);
// k64 = str2uint(K[1..8] and Mask64);
// k128 = str2uint(K[9..24] and Mask128);
int i = 0;
- k64 = new BigInteger(1, new byte[] { (byte) (K[i++] & 0x01),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0x01),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0xFF) });
- k128 = new BigInteger(1, new byte[] { (byte) (K[i++] & 0x01),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0x01),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0x01),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0x01),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0xFF),
- (byte) (K[i++] & 0xFF) });
-
+ k64 = new BigInteger(1, new byte[] {
+ (byte)(K[i++] & 0x01), (byte)(K[i++] & 0xFF),
+ (byte)(K[i++] & 0xFF), (byte)(K[i++] & 0xFF),
+ (byte)(K[i++] & 0x01), (byte)(K[i++] & 0xFF),
+ (byte)(K[i++] & 0xFF), (byte)(K[i++] & 0xFF) });
+ k128 = new BigInteger(1, new byte[] {
+ (byte)(K[i++] & 0x01), (byte)(K[i++] & 0xFF),
+ (byte)(K[i++] & 0xFF), (byte)(K[i++] & 0xFF),
+ (byte)(K[i++] & 0x01), (byte)(K[i++] & 0xFF),
+ (byte)(K[i++] & 0xFF), (byte)(K[i++] & 0xFF),
+ (byte)(K[i++] & 0x01), (byte)(K[i++] & 0xFF),
+ (byte)(K[i++] & 0xFF), (byte)(K[i++] & 0xFF),
+ (byte)(K[i++] & 0x01), (byte)(K[i++] & 0xFF),
+ (byte)(K[i++] & 0xFF), (byte)(K[i++] & 0xFF) });
y = BigInteger.ONE;
highBound = false;
bytesSoFar = 0L;
@@ -694,36 +549,24 @@ public class UHash32 extends BaseMac
}
}
- // Class methods
- // ----------------------------------------------------------------------
-
- // Instance methods
- // ----------------------------------------------------------------------
-
- // java.lang.Cloneable interface implementation -------------------------
-
public Object clone()
{
return new L2Hash32(this);
}
- // other instance methods -----------------------------------------------
-
// this is called with either 8-bytes or 16-bytes
void update(byte[] b, int offset, int len)
{
if (len == 0)
- {
- return;
- }
+ return;
- if (!highBound)
- { // do the first (only?) 8-bytes
+ if (! highBound) // do the first (only?) 8-bytes
+ {
poly(64, LOWER_RANGE, k64, b, offset, 8);
bytesSoFar += 8L;
highBound = (bytesSoFar > BOUNDARY);
- if (highBound)
- { // if we just crossed the limit then process y
+ if (highBound) // if we just crossed the limit then process y
+ {
poly(128, UPPER_RANGE, k128, yTo16bytes(), 0, 16);
buffer = new ByteArrayOutputStream();
}
@@ -739,9 +582,7 @@ public class UHash32 extends BaseMac
byte[] bb = buffer.toByteArray();
poly(128, UPPER_RANGE, k128, bb, 0, 16);
if (bb.length > 16)
- {
- buffer.write(bb, 16, bb.length - 16);
- }
+ buffer.write(bb, 16, bb.length - 16);
}
}
}
@@ -751,19 +592,18 @@ public class UHash32 extends BaseMac
// If M no more than 2^17 bytes, hash under 64-bit prime,
// otherwise, hash first 2^17 bytes under 64-bit prime and
// remainder under 128-bit prime.
- if (!highBound)
- { // y is up-to-date
+ if (! highBound) // y is up-to-date
+ {
// do nothing
}
- else
- { // we may have some bytes in buffer
+ else // we may have some bytes in buffer
+ {
byte[] bb = buffer.toByteArray();
byte[] lastBlock = new byte[16];
System.arraycopy(bb, 0, lastBlock, 0, bb.length);
lastBlock[bb.length] = (byte) 0x80;
poly(128, UPPER_RANGE, k128, lastBlock, 0, 16);
}
-
byte[] result = yTo16bytes();
reset();
return result;
@@ -775,38 +615,29 @@ public class UHash32 extends BaseMac
highBound = false;
bytesSoFar = 0L;
if (buffer != null)
- {
- buffer.reset();
- }
+ buffer.reset();
}
- // helper methods -------------------------------------------------------
-
private byte[] yTo16bytes()
{
byte[] yy = y.toByteArray();
byte[] result = new byte[16];
if (yy.length > 16)
- {
- System.arraycopy(yy, yy.length - 16, result, 0, 16);
- }
+ System.arraycopy(yy, yy.length - 16, result, 0, 16);
else
- {
- System.arraycopy(yy, 0, result, 16 - yy.length, yy.length);
- }
+ System.arraycopy(yy, 0, result, 16 - yy.length, yy.length);
return result;
}
/**
- * 5.3 POLY: Polynomial hash
- * Function Name: POLY
- *
+ * 5.3 POLY: Polynomial hash Function Name: POLY
+ *
* @param wordbits positive integer divisible by 8: called with 64 or 128.
* @param maxwordrange positive integer less than 2**wordbits.
* @param k integer in the range 0 .. prime(wordbits) - 1.
- * @param M string with length divisible by (wordbits / 8) bytes.
- * return y, integer in the range 0 .. prime(wordbits) - 1.
+ * @param M string with length divisible by (wordbits / 8) bytes. return y,
+ * integer in the range 0 .. prime(wordbits) - 1.
*/
private void poly(int wordbits, BigInteger maxwordrange, BigInteger k,
byte[] M, int off, int len)
@@ -814,12 +645,9 @@ public class UHash32 extends BaseMac
byte[] mag = new byte[len];
System.arraycopy(M, off, mag, 0, len);
// Define constants used for fixing out-of-range words
- // int wordbytes = wordbits / 8;
-
BigInteger p = prime(wordbits);
BigInteger offset = TWO.pow(wordbits).subtract(p); // 2^wordbits - p;
BigInteger marker = p.subtract(BigInteger.ONE);
-
// Break M into chunks of length wordbytes bytes
// long n = M.length / wordbytes;
// Let M_1, M_2, ..., M_n be strings of length wordbytes bytes
@@ -829,48 +657,34 @@ public class UHash32 extends BaseMac
// then hash the words 'marker' and (m - offset), both in range.
// for (int i = 0; i < n; i++) {
BigInteger m = new BigInteger(1, mag);
- if (m.compareTo(maxwordrange) >= 0)
- { // m >= maxwordrange
+ if (m.compareTo(maxwordrange) >= 0) // m >= maxwordrange
+ {
y = y.multiply(k).add(marker).mod(p); // (k * y + marker) % p;
y = y.multiply(k).add(m.subtract(offset)).mod(p); // (k * y + (m - offset)) % p;
}
else
- {
- y = y.multiply(k).add(m).mod(p); // (k * y + m) % p;
- }
- // }
-
- // return y;
+ y = y.multiply(k).add(m).mod(p); // (k * y + m) % p;
}
}
- // =========================================================================
-
/**
* Third hash stage of the UHash32 algorithm.
- *
- * Input:
- * K1 string of length 64 bytes.
- * K2 string of length 4 bytes.
- * M string of length 16 bytes.
- * Returns:
- * Y, string of length 4 bytes.
+ * <ul>
+ * <li>Input:<br/>
+ * K1 string of length 64 bytes.<br/>
+ * K2 string of length 4 bytes.<br/>
+ * M string of length 16 bytes.</li>
+ * <li>Returns:<br/>
+ * Y, string of length 4 bytes.</li>
+ * </ul>
*/
- class L3Hash32 implements Cloneable
+ class L3Hash32
+ implements Cloneable
{
-
- // Constants and variables
- // ----------------------------------------------------------------------
-
private static final long PRIME_36 = 0x0000000FFFFFFFFBL;
-
private int[] k = new int[9];
- // Constructor(s)
- // ----------------------------------------------------------------------
-
/**
- *
* @param K1 string of length 64 bytes.
* @param K2 string of length 4 bytes.
*/
@@ -880,29 +694,26 @@ public class UHash32 extends BaseMac
// pre-conditions
if (K1.length != 64)
- {
- throw new ExceptionInInitializerError("K1 length is not 64");
- }
+ throw new ExceptionInInitializerError("K1 length is not 64");
if (K2.length != 4)
- {
- throw new ExceptionInInitializerError("K2 length is not 4");
- }
-
+ throw new ExceptionInInitializerError("K2 length is not 4");
// Break K1 into 8 chunks and convert to integers
- // int i = 0;
- // for (int j = 0; i < 8; ) {
for (int i = 0, j = 0; i < 8; i++)
{
- long kk = (K1[j++] & 0xFFL) << 56 | (K1[j++] & 0xFFL) << 48
- | (K1[j++] & 0xFFL) << 40 | (K1[j++] & 0xFFL) << 32
- | (K1[j++] & 0xFFL) << 24 | (K1[j++] & 0xFFL) << 16
- | (K1[j++] & 0xFFL) << 8 | (K1[j++] & 0xFFL);
- // k[i++] = (int)(kk % PRIME_36);
- k[i] = (int) (kk % PRIME_36);
+ long kk = (K1[j++] & 0xFFL) << 56
+ | (K1[j++] & 0xFFL) << 48
+ | (K1[j++] & 0xFFL) << 40
+ | (K1[j++] & 0xFFL) << 32
+ | (K1[j++] & 0xFFL) << 24
+ | (K1[j++] & 0xFFL) << 16
+ | (K1[j++] & 0xFFL) << 8
+ | (K1[j++] & 0xFFL);
+ k[i] = (int)(kk % PRIME_36);
}
- // k[i] = K2[0] << 24 | (K2[1] & 0xFF) << 16 | (K2[2] & 0xFF) << 8 | (K2[3] & 0xFF);
- k[8] = K2[0] << 24 | (K2[1] & 0xFF) << 16 | (K2[2] & 0xFF) << 8
- | (K2[3] & 0xFF);
+ k[8] = K2[0] << 24
+ | (K2[1] & 0xFF) << 16
+ | (K2[2] & 0xFF) << 8
+ | (K2[3] & 0xFF);
}
private L3Hash32(int[] k)
@@ -912,21 +723,11 @@ public class UHash32 extends BaseMac
this.k = k;
}
- // Class methods
- // ----------------------------------------------------------------------
-
- // Instance methods
- // ----------------------------------------------------------------------
-
- // java.lang.Cloneable interface implementation -------------------------
-
public Object clone()
{
return new L3Hash32((int[]) k.clone());
}
- // other instance methods -----------------------------------------------
-
/**
* @param M string of length 16 bytes.
* @return Y, string of length 4 bytes.
@@ -934,24 +735,24 @@ public class UHash32 extends BaseMac
byte[] digest(byte[] M)
{
if (M.length != 16)
- {
- throw new IllegalArgumentException("M length is not 16");
- }
+ throw new IllegalArgumentException("M length is not 16");
long m, y = 0L;
for (int i = 0, j = 0; i < 8; i++)
{
// Break M into 8 chunks and convert to integers
m = (M[j++] & 0xFFL) << 8 | (M[j++] & 0xFFL);
-
// Inner-product hash, extract last 32 bits and affine-translate
// y = (m_1 * k_1 + ... + m_8 * k_8) mod prime(36);
// y = y mod 2^32;
y += (m * (k[i] & 0xFFFFFFFFL)) % PRIME_36;
}
int Y = ((int) y) ^ k[8];
- return new byte[] { (byte) (Y >>> 24), (byte) (Y >>> 16),
- (byte) (Y >>> 8), (byte) Y };
+ return new byte[] {
+ (byte)(Y >>> 24),
+ (byte)(Y >>> 16),
+ (byte)(Y >>> 8),
+ (byte) Y };
}
}
-} \ No newline at end of file
+}
diff --git a/gnu/javax/crypto/mac/UMac32.java b/gnu/javax/crypto/mac/UMac32.java
index 013888856..8e913db71 100644
--- a/gnu/javax/crypto/mac/UMac32.java
+++ b/gnu/javax/crypto/mac/UMac32.java
@@ -53,123 +53,105 @@ import java.util.HashMap;
import java.util.Map;
/**
- * <p>The implementation of the <i>UMAC</i> (Universal Message Authentication
- * Code).</p>
- *
- * <p>The <i>UMAC</i> algorithms described are <i>parameterized</i>. This means
+ * The implementation of the <i>UMAC</i> (Universal Message Authentication
+ * Code).
+ * <p>
+ * The <i>UMAC</i> algorithms described are <i>parameterized</i>. This means
* that various low-level choices, like the endian convention and the underlying
* cryptographic primitive, have not been fixed. One must choose values for
* these parameters before the authentication tag generated by <i>UMAC</i> (for
- * a given message, key, and nonce) becomes fully-defined. In this document
- * we provide two collections of parameter settings, and have named the sets
- * <i>UMAC16</i> and <i>UMAC32</i>. The parameter sets have been chosen based on
- * experimentation and provide good performance on a wide variety of processors.
- * <i>UMAC16</i> is designed to excel on processors which provide small-scale
- * SIMD parallelism of the type found in Intel's MMX and Motorola's AltiVec
- * instruction sets, while <i>UMAC32</i> is designed to do well on processors
- * with good 32- and 64- bit support. <i>UMAC32</i> may take advantage of SIMD
- * parallelism in future processors.</p>
- *
- * <p><i>UMAC</i> has been designed to allow implementations which accommodate
- * <i>on-line</i> authentication. This means that pieces of the message may
- * be presented to <i>UMAC</i> at different times (but in correct order) and an
+ * a given message, key, and nonce) becomes fully-defined. In this document we
+ * provide two collections of parameter settings, and have named the sets
+ * <i>UMAC16</i> and <i>UMAC32</i>. The parameter sets have been chosen based
+ * on experimentation and provide good performance on a wide variety of
+ * processors. <i>UMAC16</i> is designed to excel on processors which provide
+ * small-scale SIMD parallelism of the type found in Intel's MMX and Motorola's
+ * AltiVec instruction sets, while <i>UMAC32</i> is designed to do well on
+ * processors with good 32- and 64- bit support. <i>UMAC32</i> may take
+ * advantage of SIMD parallelism in future processors.
+ * <p>
+ * <i>UMAC</i> has been designed to allow implementations which accommodate
+ * <i>on-line</i> authentication. This means that pieces of the message may be
+ * presented to <i>UMAC</i> at different times (but in correct order) and an
* on-line implementation will be able to process the message correctly without
* the need to buffer more than a few dozen bytes of the message. For
* simplicity, the algorithms in this specification are presented as if the
- * entire message being authenticated were available at once.</p>
- *
- * <p>To authenticate a message, <code>Msg</code>, one first applies the
+ * entire message being authenticated were available at once.
+ * <p>
+ * To authenticate a message, <code>Msg</code>, one first applies the
* universal hash function, resulting in a string which is typically much
- * shorter than the original message. The pseudorandom function is applied to a
+ * shorter than the original message. The pseudorandom function is applied to a
* nonce, and the result is used in the manner of a Vernam cipher: the
* authentication tag is the xor of the output from the hash function and the
* output from the pseudorandom function. Thus, an authentication tag is
- * generated as</p>
- *
+ * generated as
* <pre>
- * AuthTag = f(Nonce) xor h(Msg)
+ * AuthTag = f(Nonce) xor h(Msg)
* </pre>
- *
- * <p>Here <code>f</code> is the pseudorandom function shared between the sender
+ * <p>
+ * Here <code>f</code> is the pseudorandom function shared between the sender
* and the receiver, and h is a universal hash function shared by the sender and
* the receiver. In <i>UMAC</i>, a shared key is used to key the pseudorandom
* function <code>f</code>, and then <code>f</code> is used for both tag
* generation and internally to generate all of the bits needed by the universal
- * hash function.</p>
- *
- * <p>The universal hash function that we use is called <code>UHASH</code>. It
+ * hash function.
+ * <p>
+ * The universal hash function that we use is called <code>UHASH</code>. It
* combines several software-optimized algorithms into a multi-layered
* structure. The algorithm is moderately complex. Some of this complexity comes
- * from extensive speed optimizations.</p>
- *
- * <p>For the pseudorandom function we use the block cipher of the <i>Advanced
- * Encryption Standard</i> (AES).</p>
- *
- * <p>The UMAC32 parameters, considered in this implementation are:</p>
+ * from extensive speed optimizations.
+ * <p>
+ * For the pseudorandom function we use the block cipher of the <i>Advanced
+ * Encryption Standard</i> (AES).
+ * <p>
+ * The UMAC32 parameters, considered in this implementation are:
* <pre>
- * UMAC32
- * ------
- * WORD-LEN 4
- * UMAC-OUTPUT-LEN 8
- * L1-KEY-LEN 1024
- * UMAC-KEY-LEN 16
- * ENDIAN-FAVORITE BIG *
- * L1-OPERATIONS-SIGN UNSIGNED
+ * UMAC32
+ * ------
+ * WORD-LEN 4
+ * UMAC-OUTPUT-LEN 8
+ * L1-KEY-LEN 1024
+ * UMAC-KEY-LEN 16
+ * ENDIAN-FAVORITE BIG *
+ * L1-OPERATIONS-SIGN UNSIGNED
* </pre>
- *
- * <p>Please note that this UMAC32 differs from the one described in the paper
- * by the <i>ENDIAN-FAVORITE</i> value.</p>
- *
- * <p>References:</p>
- *
+ * <p>
+ * Please note that this UMAC32 differs from the one described in the paper by
+ * the <i>ENDIAN-FAVORITE</i> value.
+ * <p>
+ * References:
* <ol>
- * <li><a href="http://www.ietf.org/internet-drafts/draft-krovetz-umac-01.txt">
- * UMAC</a>: Message Authentication Code using Universal Hashing.<br>
- * T. Krovetz, J. Black, S. Halevi, A. Hevia, H. Krawczyk, and P. Rogaway.</li>
+ * <li><a href="http://www.ietf.org/internet-drafts/draft-krovetz-umac-01.txt">
+ * UMAC</a>: Message Authentication Code using Universal Hashing.<br>
+ * T. Krovetz, J. Black, S. Halevi, A. Hevia, H. Krawczyk, and P. Rogaway.</li>
* </ol>
*/
-public class UMac32 extends BaseMac
+public class UMac32
+ extends BaseMac
{
-
- // Constants and variables
- // -------------------------------------------------------------------------
-
/**
* Property name of the user-supplied <i>Nonce</i>. The value associated to
* this property name is taken to be a byte array.
*/
public static final String NONCE_MATERIAL = "gnu.crypto.umac.nonce.material";
-
/** Known test vector. */
- // private static final String TV1 = "3E5A0E09198B0F94";
- // private static final String TV1 = "5FD764A6D3A9FD9D";
- // private static final String TV1 = "48658DE1D9A70304";
+ // private static final String TV1 = "3E5A0E09198B0F94";
+ // private static final String TV1 = "5FD764A6D3A9FD9D";
+ // private static final String TV1 = "48658DE1D9A70304";
private static final String TV1 = "455ED214A6909F20";
-
private static final BigInteger MAX_NONCE_ITERATIONS = BigInteger.ONE.shiftLeft(16 * 8);
-
// UMAC32 parameters
static final int OUTPUT_LEN = 8;
-
static final int L1_KEY_LEN = 1024;
-
static final int KEY_LEN = 16;
-
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
-
private byte[] nonce;
-
private UHash32 uhash32;
-
private BigInteger nonceReuseCount;
-
/** The authentication key for this instance. */
private transient byte[] K;
- // Constructor(s)
- // -------------------------------------------------------------------------
-
/** Trivial 0-arguments constructor. */
public UMac32()
{
@@ -177,8 +159,8 @@ public class UMac32 extends BaseMac
}
/**
- * <p>Private constructor for cloning purposes.</p>
- *
+ * Private constructor for cloning purposes.
+ *
* @param that the instance to clone.
*/
private UMac32(UMac32 that)
@@ -186,136 +168,103 @@ public class UMac32 extends BaseMac
this();
if (that.K != null)
- {
- this.K = (byte[]) that.K.clone();
- }
+ this.K = (byte[]) that.K.clone();
if (that.nonce != null)
- {
- this.nonce = (byte[]) that.nonce.clone();
- }
+ this.nonce = (byte[]) that.nonce.clone();
if (that.uhash32 != null)
- {
- this.uhash32 = (UHash32) that.uhash32.clone();
- }
+ this.uhash32 = (UHash32) that.uhash32.clone();
this.nonceReuseCount = that.nonceReuseCount;
}
- // Class methods
- // -------------------------------------------------------------------------
-
- // Instance methods
- // -------------------------------------------------------------------------
-
- // java.lang.Cloneable interface implementation ----------------------------
-
public Object clone()
{
return new UMac32(this);
}
- // gnu.crypto.mac.IMac interface implementation ----------------------------
-
public int macSize()
{
return OUTPUT_LEN;
}
/**
- * <p>Initialising a <i>UMAC</i> instance consists of defining values for
- * the following parameters:</p>
- *
+ * Initialising a <i>UMAC</i> instance consists of defining values for the
+ * following parameters:
* <ol>
- * <li>Key Material: as the value of the attribute entry keyed by
- * {@link #MAC_KEY_MATERIAL}. The value is taken to be a byte array
- * containing the user-specified key material. The length of this array,
- * if/when defined SHOULD be exactly equal to {@link #KEY_LEN}.</li>
- *
- * <li>Nonce Material: as the value of the attribute entry keyed by
- * {@link #NONCE_MATERIAL}. The value is taken to be a byte array
- * containing the user-specified nonce material. The length of this array,
- * if/when defined SHOULD be (a) greater than zero, and (b) less or equal
- * to 16 (the size of the AES block).</li>
+ * <li>Key Material: as the value of the attribute entry keyed by
+ * {@link #MAC_KEY_MATERIAL}. The value is taken to be a byte array
+ * containing the user-specified key material. The length of this array,
+ * if/when defined SHOULD be exactly equal to {@link #KEY_LEN}.</li>
+ * <li>Nonce Material: as the value of the attribute entry keyed by
+ * {@link #NONCE_MATERIAL}. The value is taken to be a byte array containing
+ * the user-specified nonce material. The length of this array, if/when
+ * defined SHOULD be (a) greater than zero, and (b) less or equal to 16 (the
+ * size of the AES block).</li>
* </ol>
- *
- * <p>For convenience, this implementation accepts that not both parameters
- * be always specified.</p>
- *
+ * <p>
+ * For convenience, this implementation accepts that not both parameters be
+ * always specified.
* <ul>
- * <li>If the <i>Key Material</i> is specified, but the <i>Nonce Material</i>
- * is not, then this implementation, re-uses the previously set <i>Nonce
- * Material</i> after (a) converting the bytes to an unsigned integer,
- * (b) incrementing the number by one, and (c) converting it back to 16
- * bytes.</li>
- *
- * <li>If the <i>Nonce Material</i> is specified, but the <i>Key Material</i>
- * is not, then this implementation re-uses the previously set <i>Key
- * Material</i>.</li>
+ * <li>If the <i>Key Material</i> is specified, but the <i>Nonce Material</i>
+ * is not, then this implementation, re-uses the previously set <i>Nonce
+ * Material</i> after (a) converting the bytes to an unsigned integer, (b)
+ * incrementing the number by one, and (c) converting it back to 16 bytes.</li>
+ * <li>If the <i>Nonce Material</i> is specified, but the <i>Key Material</i>
+ * is not, then this implementation re-uses the previously set <i>Key Material</i>.
+ * </li>
* </ul>
- *
- * <p>This method throws an exception if no <i>Key Material</i> is specified
- * in the input map, and there is no previously set/defined <i>Key Material</i>
+ * <p>
+ * This method throws an exception if no <i>Key Material</i> is specified in
+ * the input map, and there is no previously set/defined <i>Key Material</i>
* (from an earlier invocation of this method). If a <i>Key Material</i> can
- * be used, but no <i>Nonce Material</i> is defined or previously set/defined,
- * then a default value of all-zeroes shall be used.</p>
- *
+ * be used, but no <i>Nonce Material</i> is defined or previously
+ * set/defined, then a default value of all-zeroes shall be used.
+ *
* @param attributes one or both of required parameters.
* @throws InvalidKeyException the key material specified is not of the
- * correct length.
+ * correct length.
*/
public void init(Map attributes) throws InvalidKeyException,
IllegalStateException
{
byte[] key = (byte[]) attributes.get(MAC_KEY_MATERIAL);
byte[] n = (byte[]) attributes.get(NONCE_MATERIAL);
-
boolean newKey = (key != null);
boolean newNonce = (n != null);
-
if (newKey)
{
if (key.length != KEY_LEN)
- {
- throw new InvalidKeyException("Key length: "
- + String.valueOf(key.length));
- }
+ throw new InvalidKeyException("Key length: "
+ + String.valueOf(key.length));
K = key;
}
else
{
if (K == null)
- {
- throw new InvalidKeyException("Null Key");
- }
+ throw new InvalidKeyException("Null Key");
}
-
if (newNonce)
{
if (n.length < 1 || n.length > 16)
+ throw new IllegalArgumentException("Invalid Nonce length: "
+ + String.valueOf(n.length));
+ if (n.length < 16) // pad with zeroes
{
- throw new IllegalArgumentException("Invalid Nonce length: "
- + String.valueOf(n.length));
- }
-
- if (n.length < 16)
- { // pad with zeroes
byte[] newN = new byte[16];
System.arraycopy(n, 0, newN, 0, n.length);
nonce = newN;
}
else
- {
- nonce = n;
- }
+ nonce = n;
nonceReuseCount = BigInteger.ZERO;
}
- else if (nonce == null)
- { // use all-0 nonce if 1st time
+ else if (nonce == null) // use all-0 nonce if 1st time
+ {
nonce = new byte[16];
nonceReuseCount = BigInteger.ZERO;
}
- else if (!newKey)
- { // increment nonce if still below max count
+ else if (! newKey) // increment nonce if still below max count
+ {
nonceReuseCount = nonceReuseCount.add(BigInteger.ONE);
if (nonceReuseCount.compareTo(MAX_NONCE_ITERATIONS) >= 0)
{
@@ -326,9 +275,7 @@ public class UMac32 extends BaseMac
N = N.add(BigInteger.ONE).mod(MAX_NONCE_ITERATIONS);
n = N.toByteArray();
if (n.length == 16)
- {
- nonce = n;
- }
+ nonce = n;
else if (n.length < 16)
{
nonce = new byte[16];
@@ -340,15 +287,11 @@ public class UMac32 extends BaseMac
System.arraycopy(n, n.length - 16, nonce, 0, 16);
}
}
- else
- { // do nothing, re-use old nonce value
- nonceReuseCount = BigInteger.ZERO;
- }
+ else // do nothing, re-use old nonce value
+ nonceReuseCount = BigInteger.ZERO;
if (uhash32 == null)
- {
- uhash32 = new UHash32();
- }
+ uhash32 = new UHash32();
Map map = new HashMap();
map.put(MAC_KEY_MATERIAL, K);
@@ -370,9 +313,7 @@ public class UMac32 extends BaseMac
byte[] result = uhash32.digest();
byte[] pad = pdf(); // pdf(K, nonce);
for (int i = 0; i < OUTPUT_LEN; i++)
- {
- result[i] = (byte) (result[i] ^ pad[i]);
- }
+ result[i] = (byte)(result[i] ^ pad[i]);
return result;
}
@@ -380,9 +321,7 @@ public class UMac32 extends BaseMac
public void reset()
{
if (uhash32 != null)
- {
- uhash32.reset();
- }
+ uhash32.reset();
}
public boolean selfTest()
@@ -412,43 +351,32 @@ public class UMac32 extends BaseMac
x.printStackTrace(System.err);
return false;
}
-
byte[] data = new byte[128];
data[0] = (byte) 0x80;
-
mac.update(data, 0, 128);
byte[] result = mac.digest();
- // System.out.println("UMAC test vector: "+Util.toString(result));
valid = Boolean.valueOf(TV1.equals(Util.toString(result)));
}
return valid.booleanValue();
}
- // helper methods ----------------------------------------------------------
-
/**
- *
* @return byte array of length 8 (or OUTPUT_LEN) bytes.
*/
private byte[] pdf()
{
// Make Nonce 16 bytes by prepending zeroes. done (see init())
-
// one AES invocation is enough for more than one PDF invocation
// number of index bits needed = 1
-
// Extract index bits and zero low bits of Nonce
BigInteger Nonce = new BigInteger(1, nonce);
int nlowbitsnum = Nonce.testBit(0) ? 1 : 0;
Nonce = Nonce.clearBit(0);
-
// Generate subkey, AES and extract indexed substring
IRandom kdf = new UMacGenerator();
Map map = new HashMap();
map.put(IBlockCipher.KEY_MATERIAL, K);
- // map.put(IBlockCipher.CIPHER_BLOCK_SIZE, new Integer(128/8));
- map.put(UMacGenerator.INDEX, new Integer(128));
- // map.put(UMacGenerator.CIPHER, Registry.AES_CIPHER);
+ map.put(UMacGenerator.INDEX, Integer.valueOf(128));
kdf.init(map);
byte[] Kp = new byte[KEY_LEN];
try
@@ -485,7 +413,6 @@ public class UMac32 extends BaseMac
aes.encryptBlock(nonce, 0, T, 0);
byte[] result = new byte[OUTPUT_LEN];
System.arraycopy(T, nlowbitsnum, result, 0, OUTPUT_LEN);
-
return result;
}
-} \ No newline at end of file
+}