Skip to content

Commit aa70711

Browse files
author
gefeili
committed
Update SparkleDigest
1 parent 34ccfb0 commit aa70711

File tree

8 files changed

+114
-126
lines changed

8 files changed

+114
-126
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ abstract class AsconBaseDigest
1616

1717
protected AsconBaseDigest()
1818
{
19+
super(ProcessingBufferType.Immediate, 8);
1920
DigestSize = 32;
20-
BlockSize = 8;
21-
m_buf = new byte[BlockSize];
2221
}
2322

2423
private void round(long C)

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class AsconXof128
1818
extends AsconBaseDigest
1919
implements Xof
2020
{
21-
private boolean m_squeezing = false;
21+
private boolean m_squeezing;
2222

2323
public AsconXof128()
2424
{
@@ -96,12 +96,6 @@ public int doFinal(byte[] output, int outOff, int outLen)
9696
return rlt;
9797
}
9898

99-
@Override
100-
public int getByteLength()
101-
{
102-
return 8;
103-
}
104-
10599
@Override
106100
public void reset()
107101
{

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

Lines changed: 94 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,94 @@
77
public abstract class BufferBaseDigest
88
implements ExtendedDigest
99
{
10+
protected enum ProcessingBufferType
11+
{
12+
Buffered,
13+
Immediate,
14+
}
15+
1016
protected int DigestSize;
1117
protected int BlockSize;
1218
protected byte[] m_buf;
1319
protected int m_bufPos;
1420
protected String algorithmName;
21+
protected ProcessingBuffer processor;
22+
23+
protected BufferBaseDigest(ProcessingBufferType type, int BlockSize)
24+
{
25+
this.BlockSize = BlockSize;
26+
m_buf = new byte[BlockSize];
27+
switch (type)
28+
{
29+
case Buffered:
30+
processor = new BufferedProcessor();
31+
break;
32+
case Immediate:
33+
processor = new ImmediateProcessor();
34+
break;
35+
}
36+
}
37+
38+
protected interface ProcessingBuffer
39+
{
40+
void update(byte input);
41+
42+
boolean isLengthWithinAvailableSpace(int len, int available);
43+
44+
boolean isLengthExceedingBlockSize(int len, int size);
45+
}
46+
47+
private class BufferedProcessor
48+
implements ProcessingBuffer
49+
{
50+
public void update(byte input)
51+
{
52+
if (m_bufPos == BlockSize)
53+
{
54+
processBytes(m_buf, 0);
55+
m_bufPos = 0;
56+
}
57+
m_buf[m_bufPos++] = input;
58+
}
59+
60+
@Override
61+
public boolean isLengthWithinAvailableSpace(int len, int available)
62+
{
63+
return len <= available;
64+
}
65+
66+
@Override
67+
public boolean isLengthExceedingBlockSize(int len, int size)
68+
{
69+
return len > size;
70+
}
71+
}
72+
73+
private class ImmediateProcessor
74+
implements ProcessingBuffer
75+
{
76+
public void update(byte input)
77+
{
78+
m_buf[m_bufPos] = input;
79+
if (++m_bufPos == BlockSize)
80+
{
81+
processBytes(m_buf, 0);
82+
m_bufPos = 0;
83+
}
84+
}
85+
86+
@Override
87+
public boolean isLengthWithinAvailableSpace(int len, int available)
88+
{
89+
return len < available;
90+
}
91+
92+
@Override
93+
public boolean isLengthExceedingBlockSize(int len, int size)
94+
{
95+
return len >= size;
96+
}
97+
}
1598

1699
@Override
17100
public String getAlgorithmName()
@@ -34,12 +117,7 @@ public int getByteLength()
34117
@Override
35118
public void update(byte in)
36119
{
37-
m_buf[m_bufPos] = in;
38-
if (++m_bufPos == BlockSize)
39-
{
40-
processBytes(m_buf, 0);
41-
m_bufPos = 0;
42-
}
120+
processor.update(in);
43121
}
44122

45123
@Override
@@ -50,27 +128,27 @@ public void update(byte[] input, int inOff, int len)
50128
throw new DataLengthException("input buffer too short");
51129
}
52130
int available = BlockSize - m_bufPos;
53-
if (len < available)
131+
if (processor.isLengthWithinAvailableSpace(len, available))
54132
{
55133
System.arraycopy(input, inOff, m_buf, m_bufPos, len);
56134
m_bufPos += len;
57135
return;
58136
}
59-
int inPos = 0;
60137
if (m_bufPos > 0)
61138
{
62139
System.arraycopy(input, inOff, m_buf, m_bufPos, available);
63-
inPos += available;
140+
inOff += available;
141+
len -= available;
64142
processBytes(m_buf, 0);
65143
}
66-
int remaining;
67-
while ((remaining = len - inPos) >= BlockSize)
144+
while (processor.isLengthExceedingBlockSize(len, BlockSize))
68145
{
69-
processBytes(input, inOff + inPos);
70-
inPos += BlockSize;
146+
processBytes(input, inOff);
147+
inOff += BlockSize;
148+
len -= BlockSize;
71149
}
72-
System.arraycopy(input, inOff + inPos, m_buf, 0, remaining);
73-
m_bufPos = remaining;
150+
System.arraycopy(input, inOff, m_buf, 0, len);
151+
m_bufPos = len;
74152
}
75153

76154
@Override
@@ -86,5 +164,6 @@ public int doFinal(byte[] output, int outOff)
86164
}
87165

88166
protected abstract void processBytes(byte[] input, int inOff);
167+
89168
protected abstract void finish(byte[] output, int outOff);
90169
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ public class ISAPDigest
1919

2020
public ISAPDigest()
2121
{
22+
super(ProcessingBufferType.Immediate, 8);
2223
DigestSize = 32;
23-
BlockSize = 8;
24-
m_buf = new byte[BlockSize];
2524
algorithmName = "ISAP Hash";
2625
reset();
2726
}

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,12 @@ public class PhotonBeetleDigest
4343

4444
public PhotonBeetleDigest()
4545
{
46+
super(ProcessingBufferType.Buffered, 4);
4647
state = new byte[STATE_INBYTES];
4748
state_2d = new byte[D][D];
4849
DigestSize = 32;
4950
algorithmName = "Photon-Beetle Hash";
50-
BlockSize = 4;
5151
blockCount = 0;
52-
m_buf = new byte[BlockSize];
5352
}
5453

5554
@Override
@@ -93,7 +92,7 @@ else if (blockCount == 4 && m_bufPos == 0)
9392
{
9493
state[m_bufPos] ^= 0x01; // ozs
9594
}
96-
state[STATE_INBYTES - 1] ^= (m_bufPos == 0 ? (byte)1 : (byte)2) << LAST_THREE_BITS_OFFSET;
95+
state[STATE_INBYTES - 1] ^= (m_bufPos % BlockSize == 0 ? (byte)1 : (byte)2) << LAST_THREE_BITS_OFFSET;
9796
}
9897
PHOTON_Permutation();
9998
int SQUEEZE_RATE_INBYTES = 16;

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

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

3-
import org.bouncycastle.crypto.DataLengthException;
4-
import org.bouncycastle.crypto.ExtendedDigest;
5-
import org.bouncycastle.crypto.OutputLengthException;
63
import org.bouncycastle.crypto.engines.SparkleEngine;
74
import org.bouncycastle.util.Arrays;
85
import org.bouncycastle.util.Integers;
@@ -14,7 +11,7 @@
1411
* Specification: https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/sparkle-spec-final.pdf
1512
*/
1613
public class SparkleDigest
17-
implements ExtendedDigest
14+
extends BufferBaseDigest
1815
{
1916
public static class Friend
2017
{
@@ -27,129 +24,54 @@ public enum SparkleParameters
2724
ESCH256,
2825
ESCH384
2926
}
30-
31-
private static final int RATE_BYTES = 16;
3227
private static final int RATE_WORDS = 4;
33-
34-
private String algorithmName;
3528
private final int[] state;
36-
private final byte[] m_buf = new byte[RATE_BYTES];
37-
private final int DIGEST_BYTES;
3829
private final int SPARKLE_STEPS_SLIM;
3930
private final int SPARKLE_STEPS_BIG;
4031
private final int STATE_WORDS;
4132

42-
private int m_bufPos = 0;
43-
4433
public SparkleDigest(SparkleParameters sparkleParameters)
4534
{
35+
super(ProcessingBufferType.Buffered, 16);
4636
switch (sparkleParameters)
4737
{
4838
case ESCH256:
4939
algorithmName = "ESCH-256";
50-
DIGEST_BYTES = 32;
40+
DigestSize = 32;
5141
SPARKLE_STEPS_SLIM = 7;
5242
SPARKLE_STEPS_BIG = 11;
5343
STATE_WORDS = 12;
5444
break;
5545
case ESCH384:
5646
algorithmName = "ESCH-384";
57-
DIGEST_BYTES = 48;
47+
DigestSize = 48;
5848
SPARKLE_STEPS_SLIM = 8;
5949
SPARKLE_STEPS_BIG = 12;
6050
STATE_WORDS = 16;
6151
break;
6252
default:
6353
throw new IllegalArgumentException("Invalid definition of SCHWAEMM instance");
6454
}
65-
6655
state = new int[STATE_WORDS];
6756
}
6857

6958
@Override
70-
public String getAlgorithmName()
71-
{
72-
return algorithmName;
73-
}
74-
75-
@Override
76-
public int getDigestSize()
77-
{
78-
return DIGEST_BYTES;
79-
}
80-
81-
@Override
82-
public int getByteLength()
83-
{
84-
return RATE_BYTES;
85-
}
86-
87-
@Override
88-
public void update(byte input)
89-
{
90-
if (m_bufPos == RATE_BYTES)
91-
{
92-
processBlock(m_buf, 0, SPARKLE_STEPS_SLIM);
93-
m_bufPos = 0;
94-
}
95-
96-
m_buf[m_bufPos++] = input;
97-
}
98-
99-
@Override
100-
public void update(byte[] in, int inOff, int len)
59+
protected void processBytes(byte[] input, int inOff)
10160
{
102-
if (inOff > in.length - len)
103-
{
104-
throw new DataLengthException(algorithmName + " input buffer too short");
105-
}
106-
107-
if (len < 1)
108-
return;
109-
110-
int available = RATE_BYTES - m_bufPos;
111-
if (len <= available)
112-
{
113-
System.arraycopy(in, inOff, m_buf, m_bufPos, len);
114-
m_bufPos += len;
115-
return;
116-
}
117-
118-
int inPos = 0;
119-
if (m_bufPos > 0)
120-
{
121-
System.arraycopy(in, inOff, m_buf, m_bufPos, available);
122-
processBlock(m_buf, 0, SPARKLE_STEPS_SLIM);
123-
inPos += available;
124-
}
125-
126-
int remaining;
127-
while ((remaining = len - inPos) > RATE_BYTES)
128-
{
129-
processBlock(in, inOff + inPos, SPARKLE_STEPS_SLIM);
130-
inPos += RATE_BYTES;
131-
}
132-
133-
System.arraycopy(in, inOff + inPos, m_buf, 0, remaining);
134-
m_bufPos = remaining;
61+
processBlock(input, inOff, SPARKLE_STEPS_SLIM);
13562
}
13663

13764
@Override
138-
public int doFinal(byte[] output, int outOff)
65+
protected void finish(byte[] output, int outOff)
13966
{
140-
if (outOff > output.length - DIGEST_BYTES)
141-
{
142-
throw new OutputLengthException(algorithmName + " input buffer too short");
143-
}
144-
14567
// addition of constant M1 or M2 to the state
146-
if (m_bufPos < RATE_BYTES)
68+
if (m_bufPos < BlockSize)
14769
{
14870
state[(STATE_WORDS >> 1) - 1] ^= 1 << 24;
14971

15072
// padding
15173
m_buf[m_bufPos] = (byte)0x80;
152-
while(++m_bufPos < RATE_BYTES)
74+
while(++m_bufPos < BlockSize)
15375
{
15476
m_buf[m_bufPos] = 0x00;
15577
}
@@ -175,9 +97,6 @@ public int doFinal(byte[] output, int outOff)
17597
SparkleEngine.sparkle_opt12(Friend.INSTANCE, state, SPARKLE_STEPS_SLIM);
17698
Pack.intToLittleEndian(state, 0, RATE_WORDS, output, outOff + 16);
17799
}
178-
179-
reset();
180-
return DIGEST_BYTES;
181100
}
182101

183102
@Override

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,9 @@ enum MODE
3131

3232
public XoodyakDigest()
3333
{
34+
super(ProcessingBufferType.Immediate, 16);
3435
DigestSize = 32;
3536
state = new byte[48];
36-
BlockSize = 16;
37-
m_buf = new byte[BlockSize];
3837
algorithmName = "Xoodyak Hash";
3938
reset();
4039
}

0 commit comments

Comments
 (0)