Skip to content

Commit e0ba6c2

Browse files
author
gefeili
committed
Fix the bugs that ASCON Xof does not support multi-part outputs based on the code from #2030 .
1 parent eb6bf9c commit e0ba6c2

File tree

7 files changed

+156
-132
lines changed

7 files changed

+156
-132
lines changed

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

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ protected AsconBaseDigest()
2525
DigestSize = 32;
2626
}
2727

28-
2928
protected abstract long pad(int i);
3029

3130
protected abstract long loadBytes(final byte[] bytes, int inOff);
@@ -85,12 +84,4 @@ protected void ensureSufficientOutputBuffer(byte[] output, int outOff, int len)
8584
throw new OutputLengthException("output buffer is too short");
8685
}
8786
}
88-
89-
protected void ensureNoAbsorbWhileSqueezing(boolean m_squeezing)
90-
{
91-
if (m_squeezing)
92-
{
93-
throw new IllegalArgumentException("attempt to absorb while squeezing");
94-
}
95-
}
9687
}

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

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.bouncycastle.crypto.digests;
22

33
import org.bouncycastle.crypto.DataLengthException;
4-
import org.bouncycastle.crypto.Xof;
54
import org.bouncycastle.util.Pack;
65

76
/**
@@ -16,10 +15,8 @@
1615
* </p>
1716
*/
1817
public class AsconCXof128
19-
extends AsconBaseDigest
20-
implements Xof
18+
extends AsconXofBase
2119
{
22-
private boolean m_squeezing = false;
2320
private final long z0, z1, z2, z3, z4;
2421

2522
public AsconCXof128()
@@ -49,20 +46,6 @@ public AsconCXof128(byte[] s, int off, int len)
4946
z4 = p.x4;
5047
}
5148

52-
@Override
53-
public void update(byte in)
54-
{
55-
ensureNoAbsorbWhileSqueezing(m_squeezing);
56-
super.update(in);
57-
}
58-
59-
@Override
60-
public void update(byte[] input, int inOff, int len)
61-
{
62-
ensureNoAbsorbWhileSqueezing(m_squeezing);
63-
super.update(input, inOff, len);
64-
}
65-
6649
protected long pad(int i)
6750
{
6851
return 0x01L << (i << 3);
@@ -88,35 +71,10 @@ protected void setBytes(long w, byte[] bytes, int inOff, int n)
8871
Pack.longToLittleEndian(w, bytes, inOff, n);
8972
}
9073

91-
protected void padAndAbsorb()
92-
{
93-
m_squeezing = true;
94-
super.padAndAbsorb();
95-
}
96-
97-
@Override
98-
public int doOutput(byte[] output, int outOff, int outLen)
99-
{
100-
ensureSufficientOutputBuffer(output, outOff, outLen);
101-
padAndAbsorb();
102-
/* squeeze full output blocks */
103-
squeeze(output, outOff, outLen);
104-
return outLen;
105-
}
106-
107-
@Override
108-
public int doFinal(byte[] output, int outOff, int outLen)
109-
{
110-
int rlt = doOutput(output, outOff, outLen);
111-
reset();
112-
return rlt;
113-
}
114-
11574
@Override
11675
public void reset()
11776
{
11877
super.reset();
119-
m_squeezing = false;
12078
/* initialize */
12179
p.set(z0, z1, z2, z3, z4);
12280
}
@@ -129,7 +87,7 @@ private void initState(byte[] z, int zOff, int zLen)
12987
p.p(12);
13088
update(z, zOff, zLen);
13189
padAndAbsorb();
132-
m_squeezing = false;
90+
super.reset();
13391
}
13492
}
13593

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

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.bouncycastle.crypto.digests;
22

3-
import org.bouncycastle.crypto.Xof;
43
import org.bouncycastle.util.Pack;
54

65
/**
@@ -13,8 +12,7 @@
1312
* @deprecated Now superseded - please use AsconXof128
1413
*/
1514
public class AsconXof
16-
extends AsconBaseDigest
17-
implements Xof
15+
extends AsconXofBase
1816
{
1917
public enum AsconParameters
2018
{
@@ -44,28 +42,6 @@ public AsconXof(AsconXof.AsconParameters parameters)
4442
reset();
4543
}
4644

47-
private boolean m_squeezing = false;
48-
49-
@Override
50-
public void update(byte in)
51-
{
52-
ensureNoAbsorbWhileSqueezing(m_squeezing);
53-
super.update(in);
54-
}
55-
56-
@Override
57-
public void update(byte[] input, int inOff, int len)
58-
{
59-
ensureNoAbsorbWhileSqueezing(m_squeezing);
60-
super.update(input, inOff, len);
61-
}
62-
63-
protected void padAndAbsorb()
64-
{
65-
m_squeezing = true;
66-
super.padAndAbsorb();
67-
}
68-
6945
protected long pad(int i)
7046
{
7147
return 0x80L << (56 - (i << 3));
@@ -91,25 +67,10 @@ protected void setBytes(long w, byte[] bytes, int inOff, int n)
9167
Pack.longToBigEndian(w, bytes, inOff, n);
9268
}
9369

94-
@Override
95-
public int doOutput(byte[] output, int outOff, int outLen)
96-
{
97-
return hash(output, outOff, outLen);
98-
}
99-
100-
@Override
101-
public int doFinal(byte[] output, int outOff, int outLen)
102-
{
103-
int rlt = doOutput(output, outOff, outLen);
104-
reset();
105-
return rlt;
106-
}
107-
10870
@Override
10971
public void reset()
11072
{
11173
super.reset();
112-
m_squeezing = false;
11374
/* initialize */
11475
switch (asconParameters)
11576
{

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

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.bouncycastle.crypto.digests;
22

3-
import org.bouncycastle.crypto.Xof;
43
import org.bouncycastle.util.Pack;
54

65
/**
@@ -15,10 +14,8 @@
1514
* </p>
1615
*/
1716
public class AsconXof128
18-
extends AsconBaseDigest
19-
implements Xof
17+
extends AsconXofBase
2018
{
21-
private boolean m_squeezing;
2219

2320
public AsconXof128()
2421
{
@@ -51,44 +48,9 @@ protected void setBytes(long w, byte[] bytes, int inOff, int n)
5148
Pack.longToLittleEndian(w, bytes, inOff, n);
5249
}
5350

54-
protected void padAndAbsorb()
55-
{
56-
m_squeezing = true;
57-
super.padAndAbsorb();
58-
}
59-
60-
@Override
61-
public void update(byte in)
62-
{
63-
ensureNoAbsorbWhileSqueezing(m_squeezing);
64-
super.update(in);
65-
}
66-
67-
@Override
68-
public void update(byte[] input, int inOff, int len)
69-
{
70-
ensureNoAbsorbWhileSqueezing(m_squeezing);
71-
super.update(input, inOff, len);
72-
}
73-
74-
@Override
75-
public int doOutput(byte[] output, int outOff, int outLen)
76-
{
77-
return hash(output, outOff, outLen);
78-
}
79-
80-
@Override
81-
public int doFinal(byte[] output, int outOff, int outLen)
82-
{
83-
int rlt = doOutput(output, outOff, outLen);
84-
reset();
85-
return rlt;
86-
}
87-
8851
@Override
8952
public void reset()
9053
{
91-
m_squeezing = false;
9254
super.reset();
9355
/* initialize */
9456
p.set(-2701369817892108309L, -3711838248891385495L, -1778763697082575311L, 1072114354614917324L, -2282070310009238562L);
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package org.bouncycastle.crypto.digests;
2+
3+
import org.bouncycastle.crypto.Xof;
4+
5+
abstract class AsconXofBase
6+
extends AsconBaseDigest
7+
implements Xof
8+
{
9+
private boolean m_squeezing;
10+
private final byte[] buffer = new byte[BlockSize];
11+
private int bytesInBuffer;
12+
13+
@Override
14+
public void update(byte in)
15+
{
16+
ensureNoAbsorbWhileSqueezing(m_squeezing);
17+
super.update(in);
18+
}
19+
20+
@Override
21+
public void update(byte[] input, int inOff, int len)
22+
{
23+
ensureNoAbsorbWhileSqueezing(m_squeezing);
24+
super.update(input, inOff, len);
25+
}
26+
27+
@Override
28+
public int doOutput(byte[] output, int outOff, int outLen)
29+
{
30+
ensureSufficientOutputBuffer(output, outOff, outLen);
31+
32+
/* Use buffered output first */
33+
int bytesOutput = 0;
34+
if (bytesInBuffer != 0)
35+
{
36+
int startPos = BlockSize - bytesInBuffer;
37+
int bytesToOutput = Math.min(outLen, bytesInBuffer);
38+
System.arraycopy(buffer, startPos, output, outOff, bytesToOutput);
39+
bytesInBuffer -= bytesToOutput;
40+
bytesOutput += bytesToOutput;
41+
}
42+
43+
int available = outLen - bytesOutput;
44+
/* If we still need to output data */
45+
if (available >= BlockSize)
46+
{
47+
/* Output full blocks */
48+
int bytesToOutput = available - available % BlockSize;
49+
bytesOutput += hash(output, outOff + bytesOutput, bytesToOutput);
50+
}
51+
52+
/* If we need to output a partial buffer */
53+
if (bytesOutput < outLen)
54+
{
55+
/* Access the next buffer's worth of data */
56+
hash(buffer, 0, BlockSize);
57+
58+
/* Copy required length of data */
59+
int bytesToOutput = outLen - bytesOutput;
60+
System.arraycopy(buffer, 0, output, outOff + bytesOutput, bytesToOutput);
61+
bytesInBuffer = buffer.length - bytesToOutput;
62+
bytesOutput += bytesToOutput;
63+
}
64+
65+
/* return the length of data output */
66+
return bytesOutput;
67+
}
68+
69+
@Override
70+
public int doFinal(byte[] output, int outOff, int outLen)
71+
{
72+
int rlt = doOutput(output, outOff, outLen);
73+
reset();
74+
return rlt;
75+
}
76+
77+
@Override
78+
public void reset()
79+
{
80+
m_squeezing = false;
81+
bytesInBuffer = 0;
82+
super.reset();
83+
}
84+
85+
@Override
86+
protected void padAndAbsorb()
87+
{
88+
if (!m_squeezing)
89+
{
90+
m_squeezing = true;
91+
super.padAndAbsorb();
92+
}
93+
else
94+
{
95+
p.p(ASCON_PB_ROUNDS);
96+
}
97+
}
98+
99+
private void ensureNoAbsorbWhileSqueezing(boolean m_squeezing)
100+
{
101+
if (m_squeezing)
102+
{
103+
throw new IllegalArgumentException("attempt to absorb while squeezing");
104+
}
105+
}
106+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.io.BufferedReader;
44
import java.io.InputStream;
55
import java.io.InputStreamReader;
6+
import java.security.SecureRandom;
67
import java.util.HashMap;
78
import java.util.Random;
89

@@ -44,6 +45,11 @@ public String getName()
4445
public void performTest()
4546
throws Exception
4647
{
48+
DigestTest.checkXof(new AsconXof128(), 1429, 317, new SecureRandom(), this);
49+
DigestTest.checkXof(new AsconCXof128(), 1429, 317, new SecureRandom(), this);
50+
DigestTest.checkXof(new AsconXof(AsconXof.AsconParameters.AsconXof), 1429, 317, new SecureRandom(), this);
51+
DigestTest.checkXof(new AsconXof(AsconXof.AsconParameters.AsconXofA), 1429, 317, new SecureRandom(), this);
52+
4753
testVectorsEngine_asconaead128();
4854
testVectorsDigest_AsconHash256();
4955
testVectorsXof_AsconXof128();

0 commit comments

Comments
 (0)