Skip to content

Commit 8a4cc61

Browse files
author
gefeili
committed
Update XoodyakDigest
1 parent f82e242 commit 8a4cc61

File tree

3 files changed

+32
-109
lines changed

3 files changed

+32
-109
lines changed

core/src/main/java/org/bouncycastle/crypto/digests/XoodyakDigest.java

Lines changed: 24 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package org.bouncycastle.crypto.digests;
22

3-
import java.io.ByteArrayOutputStream;
4-
5-
import org.bouncycastle.crypto.DataLengthException;
6-
import org.bouncycastle.crypto.Digest;
7-
import org.bouncycastle.crypto.OutputLengthException;
83
import org.bouncycastle.util.Arrays;
94
import org.bouncycastle.util.Integers;
105
import org.bouncycastle.util.Pack;
@@ -17,21 +12,16 @@
1712
*/
1813

1914
public class XoodyakDigest
20-
implements Digest
15+
extends BufferBaseDigest
2116
{
22-
private byte[] state;
17+
private final byte[] state;
2318
private int phase;
2419
private MODE mode;
25-
private int Rabsorb;
2620
private final int f_bPrime = 48;
27-
private final int Rhash = 16;
28-
private final int PhaseDown = 1;
2921
private final int PhaseUp = 2;
30-
private final int MAXROUNDS = 12;
31-
private final int TAGLEN = 16;
22+
private int Cd;
3223
private final int[] RC = {0x00000058, 0x00000038, 0x000003C0, 0x000000D0, 0x00000120, 0x00000014, 0x00000060,
3324
0x0000002C, 0x00000380, 0x000000F0, 0x000001A0, 0x00000012};
34-
private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
3525

3626
enum MODE
3727
{
@@ -41,69 +31,40 @@ enum MODE
4131

4232
public XoodyakDigest()
4333
{
34+
DigestSize = 32;
4435
state = new byte[48];
36+
BlockSize = 16;
37+
m_buf = new byte[BlockSize];
38+
algorithmName = "Xoodyak Hash";
4539
reset();
4640
}
4741

4842
@Override
49-
public String getAlgorithmName()
50-
{
51-
return "Xoodyak Hash";
52-
}
53-
54-
@Override
55-
public int getDigestSize()
56-
{
57-
return 32;
58-
}
59-
60-
@Override
61-
public void update(byte input)
62-
{
63-
buffer.write(input);
64-
}
65-
66-
@Override
67-
public void update(byte[] input, int inOff, int len)
43+
protected void processBytes(byte[] input, int inOff)
6844
{
69-
if ((inOff + len) > input.length)
45+
if (phase != PhaseUp)
7046
{
71-
throw new DataLengthException("input buffer too short");
47+
Up(null, 0, 0, 0);
7248
}
73-
buffer.write(input, inOff, len);
74-
49+
Down(input, inOff, BlockSize, Cd);
50+
Cd = 0;
7551
}
7652

7753
@Override
78-
public int doFinal(byte[] output, int outOff)
54+
protected void finish(byte[] output, int outOff)
7955
{
80-
if (32 + outOff > output.length)
81-
{
82-
throw new OutputLengthException("output buffer is too short");
83-
}
84-
byte[] input = buffer.toByteArray();
85-
int inOff = 0;
86-
int len = buffer.size();
87-
int Cd = 0x03;
88-
int splitLen;
89-
do
56+
if (m_bufPos != 0)
9057
{
9158
if (phase != PhaseUp)
9259
{
9360
Up(null, 0, 0, 0);
9461
}
95-
splitLen = Math.min(len, Rabsorb);
96-
Down(input, inOff, splitLen, Cd);
97-
Cd = 0;
98-
inOff += splitLen;
99-
len -= splitLen;
62+
Down(m_buf, 0, m_bufPos, Cd);
10063
}
101-
while (len != 0);
64+
int TAGLEN = 16;
10265
Up(output, outOff, TAGLEN, 0x40);
10366
Down(null, 0, 0, 0);
10467
Up(output, outOff + TAGLEN, TAGLEN, 0);
105-
reset();
106-
return 32;
10768
}
10869

10970
@Override
@@ -112,8 +73,9 @@ public void reset()
11273
Arrays.fill(state, (byte)0);
11374
phase = PhaseUp;
11475
mode = MODE.ModeHash;
115-
Rabsorb = Rhash;
116-
buffer.reset();
76+
Arrays.clear(m_buf);
77+
m_bufPos = 0;
78+
Cd = 0x03;
11779
}
11880

11981
private void Up(byte[] Yi, int YiOff, int YiLen, int Cu)
@@ -136,6 +98,7 @@ private void Up(byte[] Yi, int YiOff, int YiLen, int Cu)
13698
int a10 = Pack.littleEndianToInt(state, 40);
13799
int a11 = Pack.littleEndianToInt(state, 44);
138100

101+
int MAXROUNDS = 12;
139102
for (int i = 0; i < MAXROUNDS; ++i)
140103
{
141104
/* Theta: Column Parity Mixer */
@@ -164,7 +127,7 @@ private void Up(byte[] Yi, int YiOff, int YiLen, int Cu)
164127
a3 ^= e3;
165128
a7 ^= e3;
166129
a11 ^= e3;
167-
130+
168131
/* Rho-west: plane shift */
169132
int b0 = a0;
170133
int b1 = a1;
@@ -183,7 +146,7 @@ private void Up(byte[] Yi, int YiOff, int YiLen, int Cu)
183146

184147
/* Iota: round ant */
185148
b0 ^= RC[i];
186-
149+
187150
/* Chi: non linear layer */
188151
a0 = b0 ^ (~b4 & b8);
189152
a1 = b1 ^ (~b5 & b9);
@@ -199,7 +162,7 @@ private void Up(byte[] Yi, int YiOff, int YiLen, int Cu)
199162
b9 ^= (~b1 & b5);
200163
b10 ^= (~b2 & b6);
201164
b11 ^= (~b3 & b7);
202-
165+
203166
/* Rho-east: plane shift */
204167
a4 = Integers.rotateLeft(a4, 1);
205168
a5 = Integers.rotateLeft(a5, 1);
@@ -240,6 +203,6 @@ void Down(byte[] Xi, int XiOff, int XiLen, int Cd)
240203
}
241204
state[XiLen] ^= 0x01;
242205
state[f_bPrime - 1] ^= (mode == MODE.ModeHash) ? (Cd & 0x01) : Cd;
243-
phase = PhaseDown;
206+
phase = 1;
244207
}
245208
}

core/src/test/java/org/bouncycastle/crypto/test/DigestTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,11 +325,11 @@ static void implTestVectorsDigest(SimpleTest test, ExtendedDigest digest, String
325325
int a = line.indexOf('=');
326326
if (a < 0)
327327
{
328-
int count = Integer.parseInt(map.get("Count"));
329-
if (count != 6)
330-
{
331-
continue;
332-
}
328+
//int count = Integer.parseInt(map.get("Count"));
329+
// if (count != 17)
330+
// {
331+
// continue;
332+
// }
333333
byte[] ptByte = Hex.decode((String)map.get("Msg"));
334334
byte[] expected = Hex.decode((String)map.get("MD"));
335335

core/src/test/java/org/bouncycastle/crypto/test/XoodyakTest.java

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ public String getName()
3333
public void performTest()
3434
throws Exception
3535
{
36+
DigestTest.implTestVectorsDigest(this, new XoodyakDigest(), "crypto/xoodyak", "LWC_HASH_KAT_256.txt");
37+
DigestTest.checkDigestReset(this, new XoodyakDigest());
38+
DigestTest.implTestExceptionsAndParametersDigest(this, new XoodyakDigest(), 32);
3639
CipherTest.checkAEADCipherMultipleBlocks(this, 1024, 18, 100, 128, 16, new XoodyakEngine());
3740
testVectors();
3841
CipherTest.checkCipher(32, 16, 100, 128, new CipherTest.Instance()
@@ -43,8 +46,6 @@ public AEADCipher createInstance()
4346
return new XoodyakEngine();
4447
}
4548
});
46-
DigestTest.checkDigestReset(this, new XoodyakDigest());
47-
testVectorsHash();
4849

4950
XoodyakEngine xoodyak = new XoodyakEngine();
5051
testExceptions(xoodyak, xoodyak.getKeyBytesSize(), xoodyak.getIVBytesSize(), xoodyak.getBlockSize());
@@ -54,47 +55,6 @@ public AEADCipher createInstance()
5455
CipherTest.checkAEADParemeter(this, 16, 16, 16, 24, new XoodyakEngine());
5556
}
5657

57-
private void testVectorsHash()
58-
throws Exception
59-
{
60-
XoodyakDigest xoodyak = new XoodyakDigest();
61-
InputStream src = TestResourceFinder.findTestResource("crypto/xoodyak", "LWC_HASH_KAT_256.txt");
62-
BufferedReader bin = new BufferedReader(new InputStreamReader(src));
63-
String line;
64-
byte[] ptByte;
65-
HashMap<String, String> map = new HashMap<String, String>();
66-
while ((line = bin.readLine()) != null)
67-
{
68-
int a = line.indexOf('=');
69-
if (a < 0)
70-
{
71-
// if (!map.get("Count").equals("18"))
72-
// {
73-
// continue;
74-
// }
75-
xoodyak.reset();
76-
ptByte = Hex.decode((String)map.get("Msg"));
77-
xoodyak.update(ptByte, 0, ptByte.length);
78-
byte[] hash = new byte[32];
79-
xoodyak.doFinal(hash, 0);
80-
if (!areEqual(hash, Hex.decode((String)map.get("MD"))))
81-
{
82-
mismatch("Keystream " + map.get("Count"), (String)map.get("MD"), hash);
83-
}
84-
// else
85-
// {
86-
// System.out.println("Keystream " + map.get("Count") + " pass");
87-
// }
88-
map.clear();
89-
}
90-
else
91-
{
92-
map.put(line.substring(0, a).trim(), line.substring(a + 1).trim());
93-
}
94-
}
95-
// System.out.println("Xoodyak Hash pass");
96-
}
97-
9858
private void testVectors()
9959
throws Exception
10060
{

0 commit comments

Comments
 (0)