Skip to content

Commit 620a01a

Browse files
author
gefeili
committed
Change XoodyakEngine.message from ByteArrayOutputStream to byte[]
1 parent ced3d33 commit 620a01a

File tree

2 files changed

+66
-37
lines changed

2 files changed

+66
-37
lines changed

core/src/main/java/org/bouncycastle/crypto/engines/XoodyakEngine.java

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ public class XoodyakEngine
3636
private boolean encrypted;
3737
private boolean initialised = false;
3838
private final ByteArrayOutputStream aadData = new ByteArrayOutputStream();
39-
private final ByteArrayOutputStream message = new ByteArrayOutputStream();
39+
private byte[] message;
40+
private int messageOff;
4041

4142
enum MODE
4243
{
@@ -62,6 +63,8 @@ public void init(boolean forEncryption, CipherParameters params)
6263
state = new byte[48];
6364
mac = new byte[MAC_SIZE];
6465
initialised = true;
66+
message = new byte[forEncryption ? Rkout : Rkout + MAC_SIZE];
67+
messageOff = 0;
6568
reset();
6669
}
6770

@@ -70,7 +73,7 @@ public void processAADByte(byte input)
7073
{
7174
if (aadFinished)
7275
{
73-
throw new IllegalArgumentException("AAD cannot be added after reading a full block(" + getBlockSize() +
76+
throw new IllegalArgumentException("AAD cannot be added after reading a full block(" + Rkout +
7477
" bytes) of input for " + (forEncryption ? "encryption" : "decryption"));
7578
}
7679
aadData.write(input);
@@ -81,7 +84,7 @@ public void processAADBytes(byte[] input, int inOff, int len)
8184
{
8285
if (aadFinished)
8386
{
84-
throw new IllegalArgumentException("AAD cannot be added after reading a full block(" + getBlockSize() +
87+
throw new IllegalArgumentException("AAD cannot be added after reading a full block(" + Rkout +
8588
" bytes) of input for " + (forEncryption ? "encryption" : "decryption"));
8689
}
8790
if ((inOff + len) > input.length)
@@ -96,7 +99,7 @@ private void processAAD()
9699
if (!aadFinished)
97100
{
98101
byte[] ad = aadData.toByteArray();
99-
AbsorbAny(ad, 0, ad.length, Rabsorb, 0x03);
102+
AbsorbAny(ad, ad.length, Rabsorb, 0x03);
100103
aadFinished = true;
101104
}
102105
}
@@ -117,27 +120,34 @@ public int processBytes(byte[] input, int inOff, int len, byte[] output, int out
117120
{
118121
throw new DataLengthException("input buffer too short");
119122
}
120-
message.write(input, inOff, len);
121-
int blockLen = message.size() - (forEncryption ? 0 : MAC_SIZE);
122-
if (blockLen >= getBlockSize())
123+
int blockLen = len + messageOff - (forEncryption ? 0 : MAC_SIZE);
124+
if (blockLen / Rkout * Rkout + outOff > output.length)
123125
{
124-
byte[] blocks = message.toByteArray();
125-
len = blockLen / getBlockSize() * getBlockSize();
126-
if (len + outOff > output.length)
127-
{
128-
throw new OutputLengthException("output buffer is too short");
129-
}
126+
throw new OutputLengthException("output buffer is too short");
127+
}
128+
int rv = 0;
129+
int originalInOff = inOff;
130+
while (blockLen >= Rkout)
131+
{
132+
int copyLen = Math.min(len, Rkout - messageOff);
133+
System.arraycopy(input, inOff, message, messageOff, copyLen);
130134
processAAD();
131-
encrypt(blocks, 0, len, output, outOff);
132-
message.reset();
133-
message.write(blocks, len, blocks.length - len);
134-
return len;
135+
encrypt(message, Rkout, output, outOff);
136+
messageOff = 0;
137+
outOff += Rkout;
138+
rv += Rkout;
139+
blockLen -= Rkout;
140+
inOff += copyLen;
135141
}
136-
return 0;
142+
len -= inOff - originalInOff;
143+
System.arraycopy(input, inOff, message, messageOff, len);
144+
messageOff = len;
145+
return rv;
137146
}
138147

139-
private int encrypt(byte[] input, int inOff, int len, byte[] output, int outOff)
148+
private void encrypt(byte[] input, int len, byte[] output, int outOff)
140149
{
150+
int inOff = 0;
141151
int IOLen = len;
142152
int splitLen;
143153
byte[] P = new byte[Rkout];
@@ -168,7 +178,6 @@ private int encrypt(byte[] input, int inOff, int len, byte[] output, int outOff)
168178
IOLen -= splitLen;
169179
encrypted = true;
170180
}
171-
return len;
172181
}
173182

174183
@Override
@@ -179,8 +188,9 @@ public int doFinal(byte[] output, int outOff)
179188
{
180189
throw new IllegalArgumentException("Need call init function before encryption/decryption");
181190
}
182-
byte[] blocks = message.toByteArray();
183-
int len = message.size();
191+
byte[] blocks = message;
192+
Arrays.fill(blocks, messageOff, message.length, (byte)0);
193+
int len = messageOff;
184194
if ((forEncryption && len + MAC_SIZE + outOff > output.length) || (!forEncryption && len - MAC_SIZE + outOff > output.length))
185195
{
186196
throw new OutputLengthException("output buffer too short");
@@ -189,7 +199,7 @@ public int doFinal(byte[] output, int outOff)
189199
int rv = 0;
190200
if (forEncryption)
191201
{
192-
encrypt(blocks, 0, len, output, outOff);
202+
encrypt(blocks, len, output, outOff);
193203
outOff += len;
194204
mac = new byte[MAC_SIZE];
195205
Up(mac, MAC_SIZE, 0x40);
@@ -198,9 +208,14 @@ public int doFinal(byte[] output, int outOff)
198208
}
199209
else
200210
{
201-
int inOff = len - MAC_SIZE;
202-
rv = inOff;
203-
encrypt(blocks, 0, inOff, output, outOff);
211+
int inOff = 0;
212+
if (len >= MAC_SIZE)
213+
{
214+
inOff = len - MAC_SIZE;
215+
rv = inOff;
216+
encrypt(blocks, inOff, output, outOff);
217+
}
218+
204219
mac = new byte[MAC_SIZE];
205220
Up(mac, MAC_SIZE, 0x40);
206221
for (int i = 0; i < MAC_SIZE; ++i)
@@ -218,14 +233,14 @@ public int doFinal(byte[] output, int outOff)
218233
@Override
219234
public int getUpdateOutputSize(int len)
220235
{
221-
int total = Math.max(0, len + message.size() + (forEncryption ? 0 : -MAC_SIZE));
236+
int total = Math.max(0, len + messageOff + (forEncryption ? 0 : -MAC_SIZE));
222237
return total - total % Rkout;
223238
}
224239

225240
@Override
226241
public int getOutputSize(int len)
227242
{
228-
return Math.max(0, len + message.size() + (forEncryption ? MAC_SIZE : -MAC_SIZE));
243+
return Math.max(0, len + messageOff + (forEncryption ? MAC_SIZE : -MAC_SIZE));
229244
}
230245

231246
@Override
@@ -244,7 +259,8 @@ protected void reset(boolean clearMac)
244259
aadFinished = false;
245260
encrypted = false;
246261
phase = PhaseUp;
247-
message.reset();
262+
Arrays.fill(message, (byte)0);
263+
messageOff = 0;
248264
aadData.reset();
249265
//Absorb key
250266
int KLen = K.length;
@@ -255,12 +271,13 @@ protected void reset(boolean clearMac)
255271
System.arraycopy(K, 0, KID, 0, KLen);
256272
System.arraycopy(iv, 0, KID, KLen, IDLen);
257273
KID[KLen + IDLen] = (byte)IDLen;
258-
AbsorbAny(KID, 0, KLen + IDLen + 1, Rabsorb, 0x02);
274+
AbsorbAny(KID, KLen + IDLen + 1, Rabsorb, 0x02);
259275
super.reset(clearMac);
260276
}
261277

262-
private void AbsorbAny(byte[] X, int Xoff, int XLen, int r, int Cd)
278+
private void AbsorbAny(byte[] X, int XLen, int r, int Cd)
263279
{
280+
int Xoff = 0;
264281
int splitLen;
265282
do
266283
{
@@ -297,9 +314,6 @@ private void Up(byte[] Yi, int YiLen, int Cu)
297314
int a10 = Pack.littleEndianToInt(state, 40);
298315
int a11 = Pack.littleEndianToInt(state, 44);
299316

300-
// private final int NLANES = 12;
301-
// private final int NROWS = 3;
302-
// private final int NCOLUMS = 4;
303317
int MAXROUNDS = 12;
304318
for (int i = 0; i < MAXROUNDS; ++i)
305319
{
@@ -349,7 +363,7 @@ private void Up(byte[] Yi, int YiLen, int Cu)
349363
/* Iota: round ant */
350364
b0 ^= RC[i];
351365

352-
/* Chi: non linear layer */
366+
/* Chi: non-linear layer */
353367
a0 = b0 ^ (~b4 & b8);
354368
a1 = b1 ^ (~b5 & b9);
355369
a2 = b2 ^ (~b6 & b10);
@@ -403,10 +417,13 @@ void Down(byte[] Xi, int XiOff, int XiLen, int Cd)
403417
{
404418
state[i] ^= Xi[XiOff++];
405419
}
420+
if (XiLen == -16)
421+
{
422+
System.out.println();
423+
}
406424
state[XiLen] ^= 0x01;
407425
state[f_bPrime - 1] ^= (mode == MODE.ModeHash) ? (Cd & 0x01) : Cd;
408-
int phaseDown = 1;
409-
phase = phaseDown;
426+
phase = 1;
410427
}
411428

412429
public int getBlockSize()

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ public String getName()
3232
public void performTest()
3333
throws Exception
3434
{
35+
CipherTest.checkCipher(32, 16, 100, 128, new CipherTest.Instance()
36+
{
37+
@Override
38+
public AEADCipher createInstance()
39+
{
40+
return new XoodyakEngine();
41+
}
42+
});
3543
DigestTest.checkDigestReset(this, new XoodyakDigest());
3644
testVectorsHash();
3745
testVectors();
@@ -99,6 +107,9 @@ private void testVectors()
99107
int a = line.indexOf('=');
100108
if (a < 0)
101109
{
110+
// if(map.get("Count").equals("793")){
111+
// System.out.println();
112+
// }
102113
byte[] key = Hex.decode(map.get("Key"));
103114
byte[] nonce = Hex.decode(map.get("Nonce"));
104115
byte[] ad = Hex.decode(map.get("AD"));
@@ -128,6 +139,7 @@ private void testVectors()
128139
mismatch("Reccover Keystream " + map.get("Count"), (String)map.get("PT"), pt_recovered);
129140
}
130141
xoodyak.reset();
142+
//System.out.println(map.get("Count") +" pass");
131143
map.clear();
132144
}
133145
else

0 commit comments

Comments
 (0)