Skip to content

Commit

Permalink
Merge branch 'xipki-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
peterdettman committed Dec 15, 2017
2 parents a00b684 + 1fd166c commit e38777f
Showing 1 changed file with 111 additions and 201 deletions.
312 changes: 111 additions & 201 deletions core/src/main/java/org/bouncycastle/crypto/digests/KeccakDigest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,70 +12,15 @@
public class KeccakDigest
implements ExtendedDigest
{
private static long[] KeccakRoundConstants = keccakInitializeRoundConstants();

private static int[] KeccakRhoOffsets = keccakInitializeRhoOffsets();

private static long[] keccakInitializeRoundConstants()
{
long[] keccakRoundConstants = new long[24];
byte[] LFSRstate = new byte[1];

LFSRstate[0] = 0x01;
int i, j, bitPosition;

for (i = 0; i < 24; i++)
{
keccakRoundConstants[i] = 0;
for (j = 0; j < 7; j++)
{
bitPosition = (1 << j) - 1;
if (LFSR86540(LFSRstate))
{
keccakRoundConstants[i] ^= 1L << bitPosition;
}
}
}

return keccakRoundConstants;
}

private static boolean LFSR86540(byte[] LFSR)
{
boolean result = (((LFSR[0]) & 0x01) != 0);
if (((LFSR[0]) & 0x80) != 0)
{
LFSR[0] = (byte)(((LFSR[0]) << 1) ^ 0x71);
}
else
{
LFSR[0] <<= 1;
}

return result;
}

private static int[] keccakInitializeRhoOffsets()
{
int[] keccakRhoOffsets = new int[25];
int x, y, t, newX, newY;

keccakRhoOffsets[(((0) % 5) + 5 * ((0) % 5))] = 0;
x = 1;
y = 0;
for (t = 0; t < 24; t++)
{
keccakRhoOffsets[(((x) % 5) + 5 * ((y) % 5))] = ((t + 1) * (t + 2) / 2) % 64;
newX = (0 * x + 1 * y) % 5;
newY = (2 * x + 3 * y) % 5;
x = newX;
y = newY;
}
return keccakRhoOffsets;
}

protected long[] state = new long[(1600 / 64)];
protected byte[] dataQueue = new byte[(1536 / 8)];
private static long[] KeccakRoundConstants = new long[]{ 0x0000000000000001L, 0x0000000000008082L,
0x800000000000808aL, 0x8000000080008000L, 0x000000000000808bL, 0x0000000080000001L, 0x8000000080008081L,
0x8000000000008009L, 0x000000000000008aL, 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000aL,
0x000000008000808bL, 0x800000000000008bL, 0x8000000000008089L, 0x8000000000008003L, 0x8000000000008002L,
0x8000000000000080L, 0x000000000000800aL, 0x800000008000000aL, 0x8000000080008081L, 0x8000000000008080L,
0x0000000080000001L, 0x8000000080008008L };

protected long[] state = new long[25];
protected byte[] dataQueue = new byte[192];
protected int rate;
protected int bitsInQueue;
protected int fixedOutputLength;
Expand Down Expand Up @@ -292,11 +237,9 @@ private void padAndSwitchToSqueezingPhase()

KeccakPermutation();

// displayIntermediateValues.displayText(1, "--- Switching to squeezing phase ---");
KeccakExtract();
bitsInQueue = rate;

// displayIntermediateValues.displayBytes(1, "Block available for squeezing", dataQueue, bitsInQueue / 8);
squeezing = true;
}

Expand All @@ -319,7 +262,6 @@ protected void squeeze(byte[] output, int offset, long outputLength)
KeccakPermutation();
KeccakExtract();
bitsInQueue = rate;
// displayIntermediateValues.displayBytes(1, "Block available for squeezing", dataQueue, bitsAvailableForSqueezing / 8);
}
int partialBlock = (int)Math.min((long)bitsInQueue, outputLength - i);
System.arraycopy(dataQueue, (rate - bitsInQueue) / 8, output, offset + (int)(i / 8), partialBlock / 8);
Expand Down Expand Up @@ -347,143 +289,111 @@ private void KeccakExtract()

private void KeccakPermutation()
{
// displayIntermediateValues.displayStateAs64bitWords(3, "Same, with lanes as 64-bit words", state);
long[] A = state;

for (int i = 0; i < 24; i++)
{
// displayIntermediateValues.displayRoundNumber(3, i);

theta(state);
// displayIntermediateValues.displayStateAs64bitWords(3, "After theta", state);

rho(state);
// displayIntermediateValues.displayStateAs64bitWords(3, "After rho", state);

pi(state);
// displayIntermediateValues.displayStateAs64bitWords(3, "After pi", state);

chi(state);
// displayIntermediateValues.displayStateAs64bitWords(3, "After chi", state);

iota(state, i);
// displayIntermediateValues.displayStateAs64bitWords(3, "After iota", state);
}
}

private static long leftRotate(long v, int r)
{
return (v << r) | (v >>> -r);
}

private static void theta(long[] A)
{
long C0 = A[0 + 0] ^ A[0 + 5] ^ A[0 + 10] ^ A[0 + 15] ^ A[0 + 20];
long C1 = A[1 + 0] ^ A[1 + 5] ^ A[1 + 10] ^ A[1 + 15] ^ A[1 + 20];
long C2 = A[2 + 0] ^ A[2 + 5] ^ A[2 + 10] ^ A[2 + 15] ^ A[2 + 20];
long C3 = A[3 + 0] ^ A[3 + 5] ^ A[3 + 10] ^ A[3 + 15] ^ A[3 + 20];
long C4 = A[4 + 0] ^ A[4 + 5] ^ A[4 + 10] ^ A[4 + 15] ^ A[4 + 20];

long dX = leftRotate(C1, 1) ^ C4;

A[0] ^= dX;
A[5] ^= dX;
A[10] ^= dX;
A[15] ^= dX;
A[20] ^= dX;

dX = leftRotate(C2, 1) ^ C0;

A[1] ^= dX;
A[6] ^= dX;
A[11] ^= dX;
A[16] ^= dX;
A[21] ^= dX;

dX = leftRotate(C3, 1) ^ C1;

A[2] ^= dX;
A[7] ^= dX;
A[12] ^= dX;
A[17] ^= dX;
A[22] ^= dX;

dX = leftRotate(C4, 1) ^ C2;

A[3] ^= dX;
A[8] ^= dX;
A[13] ^= dX;
A[18] ^= dX;
A[23] ^= dX;

dX = leftRotate(C0, 1) ^ C3;

A[4] ^= dX;
A[9] ^= dX;
A[14] ^= dX;
A[19] ^= dX;
A[24] ^= dX;
}
long a00 = A[ 0], a01 = A[ 1], a02 = A[ 2], a03 = A[ 3], a04 = A[ 4];
long a05 = A[ 5], a06 = A[ 6], a07 = A[ 7], a08 = A[ 8], a09 = A[ 9];
long a10 = A[10], a11 = A[11], a12 = A[12], a13 = A[13], a14 = A[14];
long a15 = A[15], a16 = A[16], a17 = A[17], a18 = A[18], a19 = A[19];
long a20 = A[20], a21 = A[21], a22 = A[22], a23 = A[23], a24 = A[24];

private static void rho(long[] A)
{
// KeccakRhoOffsets[0] == 0
for (int x = 1; x < 25; x++)
{
A[x] = leftRotate(A[x], KeccakRhoOffsets[x]);
}
}

private static void pi(long[] A)
{
long a1 = A[1];
A[1] = A[6];
A[6] = A[9];
A[9] = A[22];
A[22] = A[14];
A[14] = A[20];
A[20] = A[2];
A[2] = A[12];
A[12] = A[13];
A[13] = A[19];
A[19] = A[23];
A[23] = A[15];
A[15] = A[4];
A[4] = A[24];
A[24] = A[21];
A[21] = A[8];
A[8] = A[16];
A[16] = A[5];
A[5] = A[3];
A[3] = A[18];
A[18] = A[17];
A[17] = A[11];
A[11] = A[7];
A[7] = A[10];
A[10] = a1;
}

private static void chi(long[] A)
{
long chiC0, chiC1, chiC2, chiC3, chiC4;

for (int yBy5 = 0; yBy5 < 25; yBy5 += 5)
for (int i = 0; i < 24; i++)
{
chiC0 = A[0 + yBy5] ^ ((~A[(((0 + 1) % 5) + yBy5)]) & A[(((0 + 2) % 5) + yBy5)]);
chiC1 = A[1 + yBy5] ^ ((~A[(((1 + 1) % 5) + yBy5)]) & A[(((1 + 2) % 5) + yBy5)]);
chiC2 = A[2 + yBy5] ^ ((~A[(((2 + 1) % 5) + yBy5)]) & A[(((2 + 2) % 5) + yBy5)]);
chiC3 = A[3 + yBy5] ^ ((~A[(((3 + 1) % 5) + yBy5)]) & A[(((3 + 2) % 5) + yBy5)]);
chiC4 = A[4 + yBy5] ^ ((~A[(((4 + 1) % 5) + yBy5)]) & A[(((4 + 2) % 5) + yBy5)]);

A[0 + yBy5] = chiC0;
A[1 + yBy5] = chiC1;
A[2 + yBy5] = chiC2;
A[3 + yBy5] = chiC3;
A[4 + yBy5] = chiC4;
// theta
long c0 = a00 ^ a05 ^ a10 ^ a15 ^ a20;
long c1 = a01 ^ a06 ^ a11 ^ a16 ^ a21;
long c2 = a02 ^ a07 ^ a12 ^ a17 ^ a22;
long c3 = a03 ^ a08 ^ a13 ^ a18 ^ a23;
long c4 = a04 ^ a09 ^ a14 ^ a19 ^ a24;

long d1 = (c1 << 1 | c1 >>> -1) ^ c4;
long d2 = (c2 << 1 | c2 >>> -1) ^ c0;
long d3 = (c3 << 1 | c3 >>> -1) ^ c1;
long d4 = (c4 << 1 | c4 >>> -1) ^ c2;
long d0 = (c0 << 1 | c0 >>> -1) ^ c3;

a00 ^= d1; a05 ^= d1; a10 ^= d1; a15 ^= d1; a20 ^= d1;
a01 ^= d2; a06 ^= d2; a11 ^= d2; a16 ^= d2; a21 ^= d2;
a02 ^= d3; a07 ^= d3; a12 ^= d3; a17 ^= d3; a22 ^= d3;
a03 ^= d4; a08 ^= d4; a13 ^= d4; a18 ^= d4; a23 ^= d4;
a04 ^= d0; a09 ^= d0; a14 ^= d0; a19 ^= d0; a24 ^= d0;

// rho/pi
c1 = a01 << 1 | a01 >>> 63;
a01 = a06 << 44 | a06 >>> 20;
a06 = a09 << 20 | a09 >>> 44;
a09 = a22 << 61 | a22 >>> 3;
a22 = a14 << 39 | a14 >>> 25;
a14 = a20 << 18 | a20 >>> 46;
a20 = a02 << 62 | a02 >>> 2;
a02 = a12 << 43 | a12 >>> 21;
a12 = a13 << 25 | a13 >>> 39;
a13 = a19 << 8 | a19 >>> 56;
a19 = a23 << 56 | a23 >>> 8;
a23 = a15 << 41 | a15 >>> 23;
a15 = a04 << 27 | a04 >>> 37;
a04 = a24 << 14 | a24 >>> 50;
a24 = a21 << 2 | a21 >>> 62;
a21 = a08 << 55 | a08 >>> 9;
a08 = a16 << 45 | a16 >>> 19;
a16 = a05 << 36 | a05 >>> 28;
a05 = a03 << 28 | a03 >>> 36;
a03 = a18 << 21 | a18 >>> 43;
a18 = a17 << 15 | a17 >>> 49;
a17 = a11 << 10 | a11 >>> 54;
a11 = a07 << 6 | a07 >>> 58;
a07 = a10 << 3 | a10 >>> 61;
a10 = c1;

// chi
c0 = a00 ^ (~a01 & a02);
c1 = a01 ^ (~a02 & a03);
a02 ^= ~a03 & a04;
a03 ^= ~a04 & a00;
a04 ^= ~a00 & a01;
a00 = c0;
a01 = c1;

c0 = a05 ^ (~a06 & a07);
c1 = a06 ^ (~a07 & a08);
a07 ^= ~a08 & a09;
a08 ^= ~a09 & a05;
a09 ^= ~a05 & a06;
a05 = c0;
a06 = c1;

c0 = a10 ^ (~a11 & a12);
c1 = a11 ^ (~a12 & a13);
a12 ^= ~a13 & a14;
a13 ^= ~a14 & a10;
a14 ^= ~a10 & a11;
a10 = c0;
a11 = c1;

c0 = a15 ^ (~a16 & a17);
c1 = a16 ^ (~a17 & a18);
a17 ^= ~a18 & a19;
a18 ^= ~a19 & a15;
a19 ^= ~a15 & a16;
a15 = c0;
a16 = c1;

c0 = a20 ^ (~a21 & a22);
c1 = a21 ^ (~a22 & a23);
a22 ^= ~a23 & a24;
a23 ^= ~a24 & a20;
a24 ^= ~a20 & a21;
a20 = c0;
a21 = c1;

// iota
a00 ^= KeccakRoundConstants[i];
}
}

private static void iota(long[] A, int indexRound)
{
A[0] ^= KeccakRoundConstants[indexRound];

A[ 0] = a00; A[ 1] = a01; A[ 2] = a02; A[ 3] = a03; A[ 4] = a04;
A[ 5] = a05; A[ 6] = a06; A[ 7] = a07; A[ 8] = a08; A[ 9] = a09;
A[10] = a10; A[11] = a11; A[12] = a12; A[13] = a13; A[14] = a14;
A[15] = a15; A[16] = a16; A[17] = a17; A[18] = a18; A[19] = a19;
A[20] = a20; A[21] = a21; A[22] = a22; A[23] = a23; A[24] = a24;
}
}

0 comments on commit e38777f

Please sign in to comment.