Skip to content

Commit f29c16b

Browse files
author
gefeili
committed
Refactor of Grain128AEADEngine
1 parent 81e40ca commit f29c16b

File tree

2 files changed

+60
-81
lines changed

2 files changed

+60
-81
lines changed

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

Lines changed: 58 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,7 @@ private void initGrain(int[] auth)
6565
{
6666
for (int remainder = 0; remainder < 32; ++remainder)
6767
{
68-
int output = getOutput();
69-
nfsr = shift(nfsr, (getOutputNFSR() ^ lfsr[0]) & 1);
70-
lfsr = shift(lfsr, (getOutputLFSR()) & 1);
68+
int output = getByteKeyStream();
7169
auth[quotient] |= output << remainder;
7270
}
7371
}
@@ -176,6 +174,12 @@ private int[] shift(int[] array, int val)
176174
return array;
177175
}
178176

177+
private void shift()
178+
{
179+
nfsr = shift(nfsr, (getOutputNFSR() ^ lfsr[0]) & 1);
180+
lfsr = shift(lfsr, (getOutputLFSR()) & 1);
181+
}
182+
179183
protected void reset(boolean clearMac)
180184
{
181185
this.aadOperator.reset();
@@ -208,59 +212,12 @@ private void updateInternalState(int input_i_j)
208212
int mask = -input_i_j;
209213
authAcc[0] ^= authSr[0] & mask;
210214
authAcc[1] ^= authSr[1] & mask;
211-
212-
authShift(getOutput());
213-
nfsr = shift(nfsr, (getOutputNFSR() ^ lfsr[0]) & 1);
214-
lfsr = shift(lfsr, (getOutputLFSR()) & 1);
215-
}
216-
217-
private void doProcessAADBytes(byte[] input, int len)
218-
{
219-
byte[] ader;
220-
int aderlen;
221-
//encodeDer
222-
if (len < 128)
223-
{
224-
ader = new byte[1 + len];
225-
ader[0] = (byte)len;
226-
aderlen = 0;
227-
}
228-
else
229-
{
230-
// aderlen is the highest bit position divided by 8
231-
aderlen = len_length(len);
232-
ader = new byte[1 + aderlen + len];
233-
ader[0] = (byte)(0x80 | aderlen);
234-
int tmp = len;
235-
for (int i = 0; i < aderlen; ++i)
236-
{
237-
ader[1 + i] = (byte)tmp;
238-
tmp >>>= 8;
239-
}
240-
}
241-
System.arraycopy(input, 0, ader, 1 + aderlen, len);
242-
243-
for (int i = 0; i < ader.length; ++i)
244-
{
245-
byte ader_i = ader[i];
246-
for (int j = 0; j < 8; ++j)
247-
{
248-
nfsr = shift(nfsr, (getOutputNFSR() ^ lfsr[0]) & 1);
249-
lfsr = shift(lfsr, (getOutputLFSR()) & 1);
250-
251-
int ader_i_j = (ader_i >> j) & 1;
252-
253-
updateInternalState(ader_i_j);
254-
}
255-
}
256-
}
257-
258-
private void authShift(int val)
259-
{
215+
int val = getByteKeyStream();
260216
authSr[0] = (authSr[0] >>> 1) | (authSr[1] << 31);
261217
authSr[1] = (authSr[1] >>> 1) | (val << 31);
262218
}
263219

220+
264221
public int getUpdateOutputSize(int len)
265222
{
266223
int total = processor.getUpdateOutputSize(len);
@@ -281,12 +238,6 @@ public int getUpdateOutputSize(int len)
281238
}
282239
return total;
283240
}
284-
//
285-
// public int getOutputSize(int len)
286-
// {
287-
// //the last 8 bytes are from AD
288-
// return len + MAC_SIZE;
289-
// }
290241

291242
@Override
292243
protected void finishAAD(State nextState, boolean isDoFinal)
@@ -327,7 +278,53 @@ protected void processBufferAAD(byte[] input, int inOff)
327278
@Override
328279
protected void processFinalAAD()
329280
{
330-
doProcessAADBytes(((StreamAADOperator)aadOperator).getBytes(), aadOperator.getLen());
281+
int len = aadOperator.getLen();
282+
byte[] input = ((StreamAADOperator)aadOperator).getBytes();
283+
byte[] ader;
284+
285+
//encodeDer
286+
if (len < 128)
287+
{
288+
ader = new byte[1];
289+
ader[0] = (byte)len;
290+
}
291+
else
292+
{
293+
// aderlen is the highest bit position divided by 8
294+
int aderlen = len_length(len);
295+
ader = new byte[1 + aderlen];
296+
ader[0] = (byte)(0x80 | aderlen);
297+
int tmp = len;
298+
for (int i = 0; i < aderlen; ++i)
299+
{
300+
ader[1 + i] = (byte)tmp;
301+
tmp >>>= 8;
302+
}
303+
}
304+
305+
absorbAadData(ader, ader.length);
306+
absorbAadData(input, len);
307+
}
308+
309+
private void absorbAadData(byte[] ader, int len)
310+
{
311+
for (int i = 0; i < len; ++i)
312+
{
313+
byte ader_i = ader[i];
314+
for (int j = 0; j < 8; ++j)
315+
{
316+
shift();
317+
int ader_i_j = (ader_i >> j) & 1;
318+
updateInternalState(ader_i_j);
319+
}
320+
}
321+
}
322+
323+
private int getByteKeyStream()
324+
{
325+
int rlt = getOutput();
326+
shift();
327+
return rlt;
331328
}
332329

333330
@Override
@@ -339,13 +336,8 @@ protected void processBufferEncrypt(byte[] input, int inOff, byte[] output, int
339336
byte cc = 0, input_i = input[inOff + i];
340337
for (int j = 0; j < 8; ++j)
341338
{
342-
int rlt = getOutput();
343-
nfsr = shift(nfsr, (getOutputNFSR() ^ lfsr[0]) & 1);
344-
lfsr = shift(lfsr, (getOutputLFSR()) & 1);
345-
346339
int input_i_j = (input_i >> j) & 1;
347-
cc |= (input_i_j ^ rlt) << j;
348-
340+
cc |= (input_i_j ^ getByteKeyStream()) << j;
349341
updateInternalState(input_i_j);
350342
}
351343
output[outOff + i] = cc;
@@ -361,13 +353,7 @@ protected void processBufferDecrypt(byte[] input, int inOff, byte[] output, int
361353
byte cc = 0, input_i = input[inOff + i];
362354
for (int j = 0; j < 8; ++j)
363355
{
364-
int rlt = getOutput();
365-
nfsr = shift(nfsr, (getOutputNFSR() ^ lfsr[0]) & 1);
366-
lfsr = shift(lfsr, (getOutputLFSR()) & 1);
367-
368-
int input_i_j = (input_i >> j) & 1;
369-
cc |= (input_i_j ^ rlt) << j;
370-
356+
cc |= (((input_i >> j) & 1) ^ getByteKeyStream()) << j;
371357
updateInternalState((cc >> j) & 1);
372358
}
373359
output[outOff + i] = cc;

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

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
package org.bouncycastle.crypto.test;
22

3-
import java.io.BufferedReader;
4-
import java.io.InputStream;
5-
import java.io.InputStreamReader;
63
import java.security.SecureRandom;
7-
import java.util.HashMap;
84

9-
import org.bouncycastle.crypto.CipherParameters;
105
import org.bouncycastle.crypto.InvalidCipherTextException;
116
import org.bouncycastle.crypto.engines.Grain128AEADEngine;
12-
import org.bouncycastle.crypto.engines.XoodyakEngine;
137
import org.bouncycastle.crypto.modes.AEADCipher;
148
import org.bouncycastle.crypto.params.KeyParameter;
159
import org.bouncycastle.crypto.params.ParametersWithIV;
16-
import org.bouncycastle.test.TestResourceFinder;
1710
import org.bouncycastle.util.Arrays;
1811
import org.bouncycastle.util.encoders.Hex;
1912
import org.bouncycastle.util.test.SimpleTest;
@@ -31,7 +24,7 @@ public String getName()
3124
public void performTest()
3225
throws Exception
3326
{
34-
27+
CipherTest.implTestVectorsEngine(new Grain128AEADEngine(), "crypto", "LWC_AEAD_KAT_128_96.txt", this);
3528
checkAEADCipherOutputSize(this, 16, 12, 8, new Grain128AEADEngine());
3629
CipherTest.checkCipher(32, 12, 100, 128, new CipherTest.Instance()
3730
{
@@ -43,7 +36,7 @@ public AEADCipher createInstance()
4336
});
4437
CipherTest.checkAEADCipherMultipleBlocks(this, 1024, 7, 100, 128, 12, new Grain128AEADEngine());
4538

46-
CipherTest.implTestVectorsEngine(new Grain128AEADEngine(), "crypto", "LWC_AEAD_KAT_128_96.txt", this);
39+
4740
CipherTest.checkAEADParemeter(this, 16, 12, 8, 16, new Grain128AEADEngine());
4841
testSplitUpdate();
4942
testExceptions();

0 commit comments

Comments
 (0)