mirror of
https://github.com/moparisthebest/xAuth
synced 2024-12-22 15:18:52 -05:00
restored to original file state
This commit is contained in:
parent
1716232374
commit
77804cd530
@ -1,11 +1,82 @@
|
|||||||
package com.cypherx.xauth;
|
/**
|
||||||
|
* The Whirlpool hashing function.
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* <b>References</b>
|
||||||
|
*
|
||||||
|
* <P>
|
||||||
|
* The Whirlpool algorithm was developed by
|
||||||
|
* <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
|
||||||
|
* <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
|
||||||
|
*
|
||||||
|
* See
|
||||||
|
* P.S.L.M. Barreto, V. Rijmen,
|
||||||
|
* ``The Whirlpool hashing function,''
|
||||||
|
* First NESSIE workshop, 2000 (tweaked version, 2003),
|
||||||
|
* <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
|
||||||
|
*
|
||||||
|
* @author Paulo S.L.M. Barreto
|
||||||
|
* @author Vincent Rijmen.
|
||||||
|
*
|
||||||
|
* @version 3.0 (2003.03.12)
|
||||||
|
*
|
||||||
|
* =============================================================================
|
||||||
|
*
|
||||||
|
* Differences from version 2.1:
|
||||||
|
*
|
||||||
|
* - Suboptimal diffusion matrix replaced by cir(1, 1, 4, 1, 8, 5, 2, 9).
|
||||||
|
*
|
||||||
|
* =============================================================================
|
||||||
|
*
|
||||||
|
* Differences from version 2.0:
|
||||||
|
*
|
||||||
|
* - Generation of ISO/IEC 10118-3 test vectors.
|
||||||
|
* - Bug fix: nonzero carry was ignored when tallying the data length
|
||||||
|
* (this bug apparently only manifested itself when feeding data
|
||||||
|
* in pieces rather than in a single chunk at once).
|
||||||
|
*
|
||||||
|
* Differences from version 1.0:
|
||||||
|
*
|
||||||
|
* - Original S-box replaced by the tweaked, hardware-efficient version.
|
||||||
|
*
|
||||||
|
* =============================================================================
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
class Whirlpool {
|
class Whirlpool {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message digest size (in bits)
|
||||||
|
*/
|
||||||
public static final int DIGESTBITS = 512;
|
public static final int DIGESTBITS = 512;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message digest size (in bytes)
|
||||||
|
*/
|
||||||
public static final int DIGESTBYTES = DIGESTBITS >>> 3;
|
public static final int DIGESTBYTES = DIGESTBITS >>> 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of rounds of the internal dedicated block cipher.
|
||||||
|
*/
|
||||||
protected static final int R = 10;
|
protected static final int R = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The substitution box.
|
||||||
|
*/
|
||||||
private static final String sbox =
|
private static final String sbox =
|
||||||
"\u1823\uc6E8\u87B8\u014F\u36A6\ud2F5\u796F\u9152" +
|
"\u1823\uc6E8\u87B8\u014F\u36A6\ud2F5\u796F\u9152" +
|
||||||
"\u60Bc\u9B8E\uA30c\u7B35\u1dE0\ud7c2\u2E4B\uFE57" +
|
"\u60Bc\u9B8E\uA30c\u7B35\u1dE0\ud7c2\u2E4B\uFE57" +
|
||||||
@ -45,17 +116,43 @@ class Whirlpool {
|
|||||||
v8 ^= 0x11dL;
|
v8 ^= 0x11dL;
|
||||||
}
|
}
|
||||||
long v9 = v8 ^ v1;
|
long v9 = v8 ^ v1;
|
||||||
|
/*
|
||||||
|
* build the circulant table C[0][x] = S[x].[1, 1, 4, 1, 8, 5, 2, 9]:
|
||||||
|
*/
|
||||||
C[0][x] =
|
C[0][x] =
|
||||||
(v1 << 56) | (v1 << 48) | (v4 << 40) | (v1 << 32) |
|
(v1 << 56) | (v1 << 48) | (v4 << 40) | (v1 << 32) |
|
||||||
(v8 << 24) | (v5 << 16) | (v2 << 8) | (v9 );
|
(v8 << 24) | (v5 << 16) | (v2 << 8) | (v9 );
|
||||||
|
/*
|
||||||
|
* build the remaining circulant tables C[t][x] = C[0][x] rotr t
|
||||||
|
*/
|
||||||
for (int t = 1; t < 8; t++) {
|
for (int t = 1; t < 8; t++) {
|
||||||
C[t][x] = (C[t - 1][x] >>> 8) | ((C[t - 1][x] << 56));
|
C[t][x] = (C[t - 1][x] >>> 8) | ((C[t - 1][x] << 56));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
for (int t = 0; t < 8; t++) {
|
||||||
|
System.out.println("static const u64 C" + t + "[256] = {");
|
||||||
|
for (int i = 0; i < 64; i++) {
|
||||||
|
System.out.print(" ");
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
String v = Long.toHexString(C[t][4*i + j]);
|
||||||
|
while (v.length() < 16) {
|
||||||
|
v = "0" + v;
|
||||||
|
}
|
||||||
|
System.out.print(" LL(0x" + v + "),");
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
System.out.println("};");
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
//*/
|
||||||
|
|
||||||
rc[0] = 0L;
|
/*
|
||||||
|
* build the round constants:
|
||||||
|
*/
|
||||||
|
rc[0] = 0L; /* not used (assigment kept only to properly initialize all variables) */
|
||||||
for (int r = 1; r <= R; r++) {
|
for (int r = 1; r <= R; r++) {
|
||||||
int i = 8*(r - 1);
|
int i = 8*(r - 1);
|
||||||
rc[r] =
|
rc[r] =
|
||||||
@ -68,21 +165,59 @@ class Whirlpool {
|
|||||||
(C[6][i + 6] & 0x000000000000ff00L) ^
|
(C[6][i + 6] & 0x000000000000ff00L) ^
|
||||||
(C[7][i + 7] & 0x00000000000000ffL);
|
(C[7][i + 7] & 0x00000000000000ffL);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
System.out.println("static const u64 rc[R + 1] = {");
|
||||||
|
for (int r = 0; r <= R; r++) {
|
||||||
|
String v = Long.toHexString(rc[r]);
|
||||||
|
while (v.length() < 16) {
|
||||||
|
v = "0" + v;
|
||||||
|
}
|
||||||
|
System.out.println(" LL(0x" + v + "),");
|
||||||
|
}
|
||||||
|
System.out.println("};");
|
||||||
|
System.out.println();
|
||||||
|
//*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global number of hashed bits (256-bit counter).
|
||||||
|
*/
|
||||||
protected byte[] bitLength = new byte[32];
|
protected byte[] bitLength = new byte[32];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer of data to hash.
|
||||||
|
*/
|
||||||
protected byte[] buffer = new byte[64];
|
protected byte[] buffer = new byte[64];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current number of bits on the buffer.
|
||||||
|
*/
|
||||||
protected int bufferBits = 0;
|
protected int bufferBits = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current (possibly incomplete) byte slot on the buffer.
|
||||||
|
*/
|
||||||
protected int bufferPos = 0;
|
protected int bufferPos = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hashing state.
|
||||||
|
*/
|
||||||
protected long[] hash = new long[8];
|
protected long[] hash = new long[8];
|
||||||
protected long[] K = new long[8];
|
protected long[] K = new long[8]; // the round key
|
||||||
protected long[] L = new long[8];
|
protected long[] L = new long[8];
|
||||||
protected long[] block = new long[8];
|
protected long[] block = new long[8]; // mu(buffer)
|
||||||
protected long[] state = new long[8];
|
protected long[] state = new long[8]; // the cipher state
|
||||||
|
|
||||||
public Whirlpool() {}
|
public Whirlpool() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The core Whirlpool transform.
|
||||||
|
*/
|
||||||
protected void processBuffer() {
|
protected void processBuffer() {
|
||||||
|
/*
|
||||||
|
* map the buffer to a block:
|
||||||
|
*/
|
||||||
for (int i = 0, j = 0; i < 8; i++, j += 8) {
|
for (int i = 0, j = 0; i < 8; i++, j += 8) {
|
||||||
block[i] =
|
block[i] =
|
||||||
(((long)buffer[j ] ) << 56) ^
|
(((long)buffer[j ] ) << 56) ^
|
||||||
@ -94,12 +229,19 @@ class Whirlpool {
|
|||||||
(((long)buffer[j + 6] & 0xffL) << 8) ^
|
(((long)buffer[j + 6] & 0xffL) << 8) ^
|
||||||
(((long)buffer[j + 7] & 0xffL) );
|
(((long)buffer[j + 7] & 0xffL) );
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* compute and apply K^0 to the cipher state:
|
||||||
|
*/
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
state[i] = block[i] ^ (K[i] = hash[i]);
|
state[i] = block[i] ^ (K[i] = hash[i]);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* iterate over all rounds:
|
||||||
|
*/
|
||||||
for (int r = 1; r <= R; r++) {
|
for (int r = 1; r <= R; r++) {
|
||||||
|
/*
|
||||||
|
* compute K^r from K^{r-1}:
|
||||||
|
*/
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
L[i] = 0L;
|
L[i] = 0L;
|
||||||
for (int t = 0, s = 56; t < 8; t++, s -= 8) {
|
for (int t = 0, s = 56; t < 8; t++, s -= 8) {
|
||||||
@ -110,7 +252,9 @@ class Whirlpool {
|
|||||||
K[i] = L[i];
|
K[i] = L[i];
|
||||||
}
|
}
|
||||||
K[0] ^= rc[r];
|
K[0] ^= rc[r];
|
||||||
|
/*
|
||||||
|
* apply the r-th round transformation:
|
||||||
|
*/
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
L[i] = K[i];
|
L[i] = K[i];
|
||||||
for (int t = 0, s = 56; t < 8; t++, s -= 8) {
|
for (int t = 0, s = 56; t < 8; t++, s -= 8) {
|
||||||
@ -121,24 +265,50 @@ class Whirlpool {
|
|||||||
state[i] = L[i];
|
state[i] = L[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* apply the Miyaguchi-Preneel compression function:
|
||||||
|
*/
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
hash[i] ^= state[i] ^ block[i];
|
hash[i] ^= state[i] ^ block[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the hashing state.
|
||||||
|
*/
|
||||||
public void NESSIEinit() {
|
public void NESSIEinit() {
|
||||||
Arrays.fill(bitLength, (byte)0);
|
Arrays.fill(bitLength, (byte)0);
|
||||||
bufferBits = bufferPos = 0;
|
bufferBits = bufferPos = 0;
|
||||||
buffer[0] = 0;
|
buffer[0] = 0; // it's only necessary to cleanup buffer[bufferPos].
|
||||||
Arrays.fill(hash, 0L);
|
Arrays.fill(hash, 0L); // initial value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delivers input data to the hashing algorithm.
|
||||||
|
*
|
||||||
|
* @param source plaintext data to hash.
|
||||||
|
* @param sourceBits how many bits of plaintext to process.
|
||||||
|
*
|
||||||
|
* This method maintains the invariant: bufferBits < 512
|
||||||
|
*/
|
||||||
public void NESSIEadd(byte[] source, long sourceBits) {
|
public void NESSIEadd(byte[] source, long sourceBits) {
|
||||||
int sourcePos = 0;
|
/*
|
||||||
int sourceGap = (8 - ((int)sourceBits & 7)) & 7;
|
sourcePos
|
||||||
int bufferRem = bufferBits & 7;
|
|
|
||||||
|
+-------+-------+-------
|
||||||
|
||||||||||||||||||||| source
|
||||||
|
+-------+-------+-------
|
||||||
|
+-------+-------+-------+-------+-------+-------
|
||||||
|
|||||||||||||||||||||| buffer
|
||||||
|
+-------+-------+-------+-------+-------+-------
|
||||||
|
|
|
||||||
|
bufferPos
|
||||||
|
*/
|
||||||
|
int sourcePos = 0; // index of leftmost source byte containing data (1 to 8 bits).
|
||||||
|
int sourceGap = (8 - ((int)sourceBits & 7)) & 7; // space on source[sourcePos].
|
||||||
|
int bufferRem = bufferBits & 7; // occupied bits on buffer[bufferPos].
|
||||||
int b;
|
int b;
|
||||||
|
// tally the length of the added data:
|
||||||
long value = sourceBits;
|
long value = sourceBits;
|
||||||
for (int i = 31, carry = 0; i >= 0; i--) {
|
for (int i = 31, carry = 0; i >= 0; i--) {
|
||||||
carry += (bitLength[i] & 0xff) + ((int)value & 0xff);
|
carry += (bitLength[i] & 0xff) + ((int)value & 0xff);
|
||||||
@ -146,38 +316,51 @@ class Whirlpool {
|
|||||||
carry >>>= 8;
|
carry >>>= 8;
|
||||||
value >>>= 8;
|
value >>>= 8;
|
||||||
}
|
}
|
||||||
|
// process data in chunks of 8 bits:
|
||||||
while (sourceBits > 8) {
|
while (sourceBits > 8) { // at least source[sourcePos] and source[sourcePos+1] contain data.
|
||||||
|
// take a byte from the source:
|
||||||
b = ((source[sourcePos] << sourceGap) & 0xff) |
|
b = ((source[sourcePos] << sourceGap) & 0xff) |
|
||||||
((source[sourcePos + 1] & 0xff) >>> (8 - sourceGap));
|
((source[sourcePos + 1] & 0xff) >>> (8 - sourceGap));
|
||||||
if (b < 0 || b >= 256) {
|
if (b < 0 || b >= 256) {
|
||||||
throw new RuntimeException("LOGIC ERROR");
|
throw new RuntimeException("LOGIC ERROR");
|
||||||
}
|
}
|
||||||
|
// process this byte:
|
||||||
buffer[bufferPos++] |= b >>> bufferRem;
|
buffer[bufferPos++] |= b >>> bufferRem;
|
||||||
bufferBits += 8 - bufferRem;
|
bufferBits += 8 - bufferRem; // bufferBits = 8*bufferPos;
|
||||||
if (bufferBits == 512) {
|
if (bufferBits == 512) {
|
||||||
|
// process data block:
|
||||||
processBuffer();
|
processBuffer();
|
||||||
|
// reset buffer:
|
||||||
bufferBits = bufferPos = 0;
|
bufferBits = bufferPos = 0;
|
||||||
}
|
}
|
||||||
buffer[bufferPos] = (byte)((b << (8 - bufferRem)) & 0xff);
|
buffer[bufferPos] = (byte)((b << (8 - bufferRem)) & 0xff);
|
||||||
bufferBits += bufferRem;
|
bufferBits += bufferRem;
|
||||||
|
// proceed to remaining data:
|
||||||
sourceBits -= 8;
|
sourceBits -= 8;
|
||||||
sourcePos++;
|
sourcePos++;
|
||||||
}
|
}
|
||||||
|
// now 0 <= sourceBits <= 8;
|
||||||
|
// furthermore, all data (if any is left) is in source[sourcePos].
|
||||||
if (sourceBits > 0) {
|
if (sourceBits > 0) {
|
||||||
b = (source[sourcePos] << sourceGap) & 0xff;
|
b = (source[sourcePos] << sourceGap) & 0xff; // bits are left-justified on b.
|
||||||
|
// process the remaining bits:
|
||||||
buffer[bufferPos] |= b >>> bufferRem;
|
buffer[bufferPos] |= b >>> bufferRem;
|
||||||
} else {
|
} else {
|
||||||
b = 0;
|
b = 0;
|
||||||
}
|
}
|
||||||
if (bufferRem + sourceBits < 8) {
|
if (bufferRem + sourceBits < 8) {
|
||||||
|
// all remaining data fits on buffer[bufferPos], and there still remains some space.
|
||||||
bufferBits += sourceBits;
|
bufferBits += sourceBits;
|
||||||
} else {
|
} else {
|
||||||
|
// buffer[bufferPos] is full:
|
||||||
bufferPos++;
|
bufferPos++;
|
||||||
bufferBits += 8 - bufferRem;
|
bufferBits += 8 - bufferRem; // bufferBits = 8*bufferPos;
|
||||||
sourceBits -= 8 - bufferRem;
|
sourceBits -= 8 - bufferRem;
|
||||||
|
// now 0 <= sourceBits < 8; furthermore, all data is in source[sourcePos].
|
||||||
if (bufferBits == 512) {
|
if (bufferBits == 512) {
|
||||||
|
// process data block:
|
||||||
processBuffer();
|
processBuffer();
|
||||||
|
// reset buffer:
|
||||||
bufferBits = bufferPos = 0;
|
bufferBits = bufferPos = 0;
|
||||||
}
|
}
|
||||||
buffer[bufferPos] = (byte)((b << (8 - bufferRem)) & 0xff);
|
buffer[bufferPos] = (byte)((b << (8 - bufferRem)) & 0xff);
|
||||||
@ -185,21 +368,33 @@ class Whirlpool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the hash value from the hashing state.
|
||||||
|
*
|
||||||
|
* This method uses the invariant: bufferBits < 512
|
||||||
|
*/
|
||||||
public void NESSIEfinalize(byte[] digest) {
|
public void NESSIEfinalize(byte[] digest) {
|
||||||
|
// append a '1'-bit:
|
||||||
buffer[bufferPos] |= 0x80 >>> (bufferBits & 7);
|
buffer[bufferPos] |= 0x80 >>> (bufferBits & 7);
|
||||||
bufferPos++;
|
bufferPos++; // all remaining bits on the current byte are set to zero.
|
||||||
|
// pad with zero bits to complete 512N + 256 bits:
|
||||||
if (bufferPos > 32) {
|
if (bufferPos > 32) {
|
||||||
while (bufferPos < 64) {
|
while (bufferPos < 64) {
|
||||||
buffer[bufferPos++] = 0;
|
buffer[bufferPos++] = 0;
|
||||||
}
|
}
|
||||||
|
// process data block:
|
||||||
processBuffer();
|
processBuffer();
|
||||||
|
// reset buffer:
|
||||||
bufferPos = 0;
|
bufferPos = 0;
|
||||||
}
|
}
|
||||||
while (bufferPos < 32) {
|
while (bufferPos < 32) {
|
||||||
buffer[bufferPos++] = 0;
|
buffer[bufferPos++] = 0;
|
||||||
}
|
}
|
||||||
|
// append bit length of hashed data:
|
||||||
System.arraycopy(bitLength, 0, buffer, 32, 32);
|
System.arraycopy(bitLength, 0, buffer, 32, 32);
|
||||||
|
// process data block:
|
||||||
processBuffer();
|
processBuffer();
|
||||||
|
// return the completed message digest:
|
||||||
for (int i = 0, j = 0; i < 8; i++, j += 8) {
|
for (int i = 0, j = 0; i < 8; i++, j += 8) {
|
||||||
long h = hash[i];
|
long h = hash[i];
|
||||||
digest[j ] = (byte)(h >>> 56);
|
digest[j ] = (byte)(h >>> 56);
|
||||||
@ -213,6 +408,13 @@ class Whirlpool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delivers string input data to the hashing algorithm.
|
||||||
|
*
|
||||||
|
* @param source plaintext data to hash (ASCII text string).
|
||||||
|
*
|
||||||
|
* This method maintains the invariant: bufferBits < 512
|
||||||
|
*/
|
||||||
public void NESSIEadd(String source) {
|
public void NESSIEadd(String source) {
|
||||||
if (source.length() > 0) {
|
if (source.length() > 0) {
|
||||||
byte[] data = new byte[source.length()];
|
byte[] data = new byte[source.length()];
|
||||||
@ -223,7 +425,7 @@ class Whirlpool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static String display(byte[] array) {
|
private static String display(byte[] array) {
|
||||||
char[] val = new char[2*array.length];
|
char[] val = new char[2*array.length];
|
||||||
String hex = "0123456789ABCDEF";
|
String hex = "0123456789ABCDEF";
|
||||||
for (int i = 0; i < array.length; i++) {
|
for (int i = 0; i < array.length; i++) {
|
||||||
@ -233,4 +435,123 @@ class Whirlpool {
|
|||||||
}
|
}
|
||||||
return String.valueOf(val);
|
return String.valueOf(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final int LONG_ITERATION = 100000000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the NESSIE test vector set for Whirlpool.
|
||||||
|
*
|
||||||
|
* The test consists of:
|
||||||
|
* 1. hashing all bit strings containing only zero bits
|
||||||
|
* for all lengths from 0 to 1023;
|
||||||
|
* 2. hashing all 512-bit strings containing a single set bit;
|
||||||
|
* 3. the iterated hashing of the 512-bit string of zero bits a large number of times.
|
||||||
|
*/
|
||||||
|
public static void makeNESSIETestVectors() {
|
||||||
|
Whirlpool w = new Whirlpool();
|
||||||
|
byte[] digest = new byte[64];
|
||||||
|
byte[] data = new byte[128];
|
||||||
|
Arrays.fill(data, (byte)0);
|
||||||
|
System.out.println("Message digests of strings of 0-bits and length L:");
|
||||||
|
for (int i = 0; i < 1024; i++) {
|
||||||
|
w.NESSIEinit();
|
||||||
|
w.NESSIEadd(data, i);
|
||||||
|
w.NESSIEfinalize(digest);
|
||||||
|
String s = Integer.toString(i);
|
||||||
|
s = " ".substring(s.length()) + s;
|
||||||
|
System.out.println(" L =" + s + ": " + display(digest));
|
||||||
|
}
|
||||||
|
System.out.println("Message digests of all 512-bit strings S containing a single 1-bit:");
|
||||||
|
data = new byte[512/8];
|
||||||
|
Arrays.fill(data, (byte)0);
|
||||||
|
for (int i = 0; i < 512; i++) {
|
||||||
|
// set bit i:
|
||||||
|
data[i/8] |= 0x80 >>> (i % 8);
|
||||||
|
w.NESSIEinit();
|
||||||
|
w.NESSIEadd(data, 512);
|
||||||
|
w.NESSIEfinalize(digest);
|
||||||
|
System.out.println(" S = " + display(data) + ": " + display(digest));
|
||||||
|
// reset bit i:
|
||||||
|
data[i/8] = 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < digest.length; i++) {
|
||||||
|
digest[i] = 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < LONG_ITERATION; i++) {
|
||||||
|
w.NESSIEinit();
|
||||||
|
w.NESSIEadd(digest, 512);
|
||||||
|
w.NESSIEfinalize(digest);
|
||||||
|
}
|
||||||
|
System.out.println("Iterated message digest computation (" + LONG_ITERATION + " times): " + display(digest));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the ISO/IEC 10118-3 test vector set for Whirlpool.
|
||||||
|
*/
|
||||||
|
public static void makeISOTestVectors() {
|
||||||
|
Whirlpool w = new Whirlpool();
|
||||||
|
byte[] digest = new byte[DIGESTBYTES];
|
||||||
|
byte[] data = new byte[1000000];
|
||||||
|
|
||||||
|
Arrays.fill(data, (byte)0);
|
||||||
|
|
||||||
|
System.out.println("1. In this example the data-string is the empty string, i.e. the string of length zero.\n");
|
||||||
|
w.NESSIEinit();
|
||||||
|
w.NESSIEfinalize(digest);
|
||||||
|
System.out.println("The hash-code is the following 512-bit string.\n\n" + display(digest) + "\n");
|
||||||
|
|
||||||
|
System.out.println("2. In this example the data-string consists of a single byte, namely the ASCII-coded version of the letter 'a'.\n");
|
||||||
|
w.NESSIEinit();
|
||||||
|
w.NESSIEadd("a");
|
||||||
|
w.NESSIEfinalize(digest);
|
||||||
|
System.out.println("The hash-code is the following 512-bit string.\n\n" + display(digest) + "\n");
|
||||||
|
|
||||||
|
System.out.println("3. In this example the data-string is the three-byte string consisting of the ASCII-coded version of 'abc'.\n");
|
||||||
|
w.NESSIEinit();
|
||||||
|
w.NESSIEadd("abc");
|
||||||
|
w.NESSIEfinalize(digest);
|
||||||
|
System.out.println("The hash-code is the following 512-bit string.\n\n" + display(digest) + "\n");
|
||||||
|
|
||||||
|
System.out.println("4. In this example the data-string is the 14-byte string consisting of the ASCII-coded version of 'message digest'.\n");
|
||||||
|
w.NESSIEinit();
|
||||||
|
w.NESSIEadd("message digest");
|
||||||
|
w.NESSIEfinalize(digest);
|
||||||
|
System.out.println("The hash-code is the following 512-bit string.\n\n" + display(digest) + "\n");
|
||||||
|
|
||||||
|
System.out.println("5. In this example the data-string is the 26-byte string consisting of the ASCII-coded version of 'abcdefghijklmnopqrstuvwxyz'.\n");
|
||||||
|
w.NESSIEinit();
|
||||||
|
w.NESSIEadd("abcdefghijklmnopqrstuvwxyz");
|
||||||
|
w.NESSIEfinalize(digest);
|
||||||
|
System.out.println("The hash-code is the following 512-bit string.\n\n" + display(digest) + "\n");
|
||||||
|
|
||||||
|
System.out.println("6. In this example the data-string is the 62-byte string consisting of the ASCII-coded version of 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.\n");
|
||||||
|
w.NESSIEinit();
|
||||||
|
w.NESSIEadd("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
|
||||||
|
w.NESSIEfinalize(digest);
|
||||||
|
System.out.println("The hash-code is the following 512-bit string.\n\n" + display(digest) + "\n");
|
||||||
|
|
||||||
|
System.out.println("7. In this example the data-string is the 80-byte string consisting of the ASCII-coded version of eight repetitions of '1234567890'.\n");
|
||||||
|
w.NESSIEinit();
|
||||||
|
w.NESSIEadd("12345678901234567890123456789012345678901234567890123456789012345678901234567890");
|
||||||
|
w.NESSIEfinalize(digest);
|
||||||
|
System.out.println("The hash-code is the following 512-bit string.\n\n" + display(digest) + "\n");
|
||||||
|
|
||||||
|
System.out.println("8. In this example the data-string is the 32-byte string consisting of the ASCII-coded version of 'abcdbcdecdefdefgefghfghighijhijk'.\n");
|
||||||
|
w.NESSIEinit();
|
||||||
|
w.NESSIEadd("abcdbcdecdefdefgefghfghighijhijk");
|
||||||
|
w.NESSIEfinalize(digest);
|
||||||
|
System.out.println("The hash-code is the following 512-bit string.\n\n" + display(digest) + "\n");
|
||||||
|
|
||||||
|
Arrays.fill(data, (byte)'a');
|
||||||
|
System.out.println("9. In this example the data-string is the 1000000-byte string consisting of the ASCII-coded version of 'a' repeated 10^6 times.\n");
|
||||||
|
w.NESSIEinit();
|
||||||
|
w.NESSIEadd(data, 8*1000000);
|
||||||
|
w.NESSIEfinalize(digest);
|
||||||
|
System.out.println("The hash-code is the following 512-bit string.\n\n" + display(digest) + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
//makeNESSIETestVectors();
|
||||||
|
makeISOTestVectors();
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user