summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/gnu/javax/crypto/mac/UHash32.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/javax/crypto/mac/UHash32.java')
-rw-r--r--libjava/classpath/gnu/javax/crypto/mac/UHash32.java499
1 files changed, 150 insertions, 349 deletions
diff --git a/libjava/classpath/gnu/javax/crypto/mac/UHash32.java b/libjava/classpath/gnu/javax/crypto/mac/UHash32.java
index 8abb0255ed4..737e9ce24ec 100644
--- a/libjava/classpath/gnu/javax/crypto/mac/UHash32.java
+++ b/libjava/classpath/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
+}
OpenPOWER on IntegriCloud