Skip to content

Commit fce766c

Browse files
author
gefeili
committed
Pass AsconHash256Digest and AsconXof128
1 parent 5815000 commit fce766c

File tree

4 files changed

+382
-6
lines changed

4 files changed

+382
-6
lines changed
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
package org.bouncycastle.crypto.digests;
2+
3+
import java.io.ByteArrayOutputStream;
4+
5+
import org.bouncycastle.crypto.DataLengthException;
6+
import org.bouncycastle.crypto.OutputLengthException;
7+
import org.bouncycastle.crypto.Xof;
8+
import org.bouncycastle.util.Pack;
9+
10+
/**
11+
* ASCON v1.2 XOF, https://ascon.iaik.tugraz.at/ .
12+
* <p>
13+
* https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/ascon-spec-final.pdf
14+
* <p>
15+
* ASCON v1.2 XOF with reference to C Reference Impl from: https://github.com/ascon/ascon-c .
16+
*/
17+
public class AsconCxof128
18+
implements Xof
19+
{
20+
public AsconCxof128()
21+
{
22+
reset();
23+
}
24+
25+
private final String algorithmName = "Ascon-XOF-128";
26+
private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
27+
28+
private final ByteArrayOutputStream customizedString = new ByteArrayOutputStream();
29+
private long x0;
30+
private long x1;
31+
private long x2;
32+
private long x3;
33+
private long x4;
34+
private final int CRYPTO_BYTES = 32;
35+
private final int ASCON_PB_ROUNDS = 12;
36+
private final int ASCON_HASH_RATE = 8;
37+
38+
private long ROR(long x, int n)
39+
{
40+
return x >>> n | x << (64 - n);
41+
}
42+
43+
private void ROUND(long C)
44+
{
45+
long t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
46+
long t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
47+
long t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
48+
long t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
49+
long t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
50+
x0 = t0 ^ ROR(t0, 19) ^ ROR(t0, 28);
51+
x1 = t1 ^ ROR(t1, 39) ^ ROR(t1, 61);
52+
x2 = ~(t2 ^ ROR(t2, 1) ^ ROR(t2, 6));
53+
x3 = t3 ^ ROR(t3, 10) ^ ROR(t3, 17);
54+
x4 = t4 ^ ROR(t4, 7) ^ ROR(t4, 41);
55+
}
56+
57+
private void P(int nr)
58+
{
59+
if (nr == 12)
60+
{
61+
ROUND(0xf0L);
62+
ROUND(0xe1L);
63+
ROUND(0xd2L);
64+
ROUND(0xc3L);
65+
}
66+
if (nr >= 8)
67+
{
68+
ROUND(0xb4L);
69+
ROUND(0xa5L);
70+
}
71+
ROUND(0x96L);
72+
ROUND(0x87L);
73+
ROUND(0x78L);
74+
ROUND(0x69L);
75+
ROUND(0x5aL);
76+
ROUND(0x4bL);
77+
}
78+
79+
private long PAD(int i)
80+
{
81+
return 0x01L << (i << 3);
82+
}
83+
84+
@Override
85+
public String getAlgorithmName()
86+
{
87+
return algorithmName;
88+
}
89+
90+
@Override
91+
public int getDigestSize()
92+
{
93+
return CRYPTO_BYTES;
94+
}
95+
96+
public void updateCustomizedString(byte in)
97+
{
98+
customizedString.write(in);
99+
}
100+
101+
public void updateCustomizedString(byte[] input, int inOff, int len)
102+
{
103+
if ((inOff + len) > input.length)
104+
{
105+
throw new DataLengthException("input buffer too short");
106+
}
107+
customizedString.write(input, inOff, len);
108+
}
109+
110+
@Override
111+
public void update(byte in)
112+
{
113+
buffer.write(in);
114+
}
115+
116+
@Override
117+
public void update(byte[] input, int inOff, int len)
118+
{
119+
if ((inOff + len) > input.length)
120+
{
121+
throw new DataLengthException("input buffer too short");
122+
}
123+
buffer.write(input, inOff, len);
124+
}
125+
126+
@Override
127+
public int doOutput(byte[] output, int outOff, int outLen)
128+
{
129+
if (CRYPTO_BYTES + outOff > output.length)
130+
{
131+
throw new OutputLengthException("output buffer is too short");
132+
}
133+
int customizedStringLen = customizedString.size();
134+
if (customizedStringLen > 2048)
135+
{
136+
throw new DataLengthException("customized string is too long");
137+
}
138+
absorb(customizedString.toByteArray(), customizedStringLen);
139+
absorb(buffer.toByteArray(), buffer.size());
140+
/* squeeze full output blocks */
141+
int len = CRYPTO_BYTES;
142+
while (len > ASCON_HASH_RATE)
143+
{
144+
Pack.longToLittleEndian(x0, output, outOff, 8);
145+
P(ASCON_PB_ROUNDS);
146+
outOff += ASCON_HASH_RATE;
147+
len -= ASCON_HASH_RATE;
148+
}
149+
/* squeeze final output block */
150+
Pack.longToLittleEndian(x0, output, outOff, len);
151+
reset();
152+
return CRYPTO_BYTES;
153+
}
154+
155+
private void absorb(byte[] input, int len)
156+
{
157+
int inOff = 0;
158+
/* absorb full plaintext blocks */
159+
while (len >= ASCON_HASH_RATE)
160+
{
161+
x0 ^= Pack.littleEndianToLong(input, inOff, 8);
162+
P(ASCON_PB_ROUNDS);
163+
inOff += ASCON_HASH_RATE;
164+
len -= ASCON_HASH_RATE;
165+
}
166+
/* absorb final plaintext block */
167+
x0 ^= Pack.littleEndianToLong(input, inOff, len);
168+
x0 ^= PAD(len);
169+
P(12);
170+
}
171+
172+
@Override
173+
public int doFinal(byte[] output, int outOff)
174+
{
175+
return doOutput(output, outOff, getDigestSize());
176+
}
177+
178+
@Override
179+
public int doFinal(byte[] output, int outOff, int outLen)
180+
{
181+
return doOutput(output, outOff, outLen);
182+
}
183+
184+
@Override
185+
public int getByteLength()
186+
{
187+
return 8;
188+
}
189+
190+
@Override
191+
public void reset()
192+
{
193+
buffer.reset();
194+
/* initialize */
195+
x0 = 7445901275803737603L;
196+
x1 = 4886737088792722364L;
197+
x2 = -1616759365661982283L;
198+
x3 = 3076320316797452470L;
199+
x4 = -8124743304765850554L;
200+
}
201+
}
202+

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
import org.bouncycastle.crypto.ExtendedDigest;
77
import org.bouncycastle.crypto.OutputLengthException;
88

9-
/* ASCON v1.2 Digest, https://ascon.iaik.tugraz.at/ .
9+
/** ASCON v1.2 Digest, https://ascon.iaik.tugraz.at/ .
1010
* <p>
1111
* https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/ascon-spec-final.pdf
1212
* <p>
1313
* ASCON v1.2 Digest with reference to C Reference Impl from: https://github.com/ascon/ascon-c .
14+
* @deprecated use Ascon Hash 256 Digest
1415
*/
1516
public class AsconDigest
1617
implements ExtendedDigest
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package org.bouncycastle.crypto.digests;
2+
3+
import java.io.ByteArrayOutputStream;
4+
5+
import org.bouncycastle.crypto.DataLengthException;
6+
import org.bouncycastle.crypto.ExtendedDigest;
7+
import org.bouncycastle.crypto.OutputLengthException;
8+
import org.bouncycastle.util.Pack;
9+
10+
/**
11+
* ASCON v1.2 Digest, https://ascon.iaik.tugraz.at/ .
12+
* <p>
13+
* https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/documents/finalist-round/updated-spec-doc/ascon-spec-final.pdf
14+
* <p>
15+
* ASCON v1.2 Digest with reference to C Reference Impl from: https://github.com/ascon/ascon-c .
16+
*
17+
*/
18+
public class AsconHash256Digest
19+
implements ExtendedDigest
20+
{
21+
public AsconHash256Digest()
22+
{
23+
reset();
24+
}
25+
26+
private final String algorithmName = "Ascon Hash 256";
27+
private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
28+
private long x0;
29+
private long x1;
30+
private long x2;
31+
private long x3;
32+
private long x4;
33+
private final int CRYPTO_BYTES = 32;
34+
private final int ASCON_PB_ROUNDS = 12;
35+
36+
private long ROR(long x, int n)
37+
{
38+
return x >>> n | x << (64 - n);
39+
}
40+
41+
private void ROUND(long C)
42+
{
43+
long t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C));
44+
long t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C) & (x1 ^ x3));
45+
long t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4);
46+
long t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0) & (x3 ^ x4));
47+
long t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4) & x1);
48+
x0 = t0 ^ ROR(t0, 19) ^ ROR(t0, 28);
49+
x1 = t1 ^ ROR(t1, 39) ^ ROR(t1, 61);
50+
x2 = ~(t2 ^ ROR(t2, 1) ^ ROR(t2, 6));
51+
x3 = t3 ^ ROR(t3, 10) ^ ROR(t3, 17);
52+
x4 = t4 ^ ROR(t4, 7) ^ ROR(t4, 41);
53+
}
54+
55+
private void P(int nr)
56+
{
57+
if (nr == 12)
58+
{
59+
ROUND(0xf0L);
60+
ROUND(0xe1L);
61+
ROUND(0xd2L);
62+
ROUND(0xc3L);
63+
}
64+
if (nr >= 8)
65+
{
66+
ROUND(0xb4L);
67+
ROUND(0xa5L);
68+
}
69+
ROUND(0x96L);
70+
ROUND(0x87L);
71+
ROUND(0x78L);
72+
ROUND(0x69L);
73+
ROUND(0x5aL);
74+
ROUND(0x4bL);
75+
}
76+
77+
private long PAD(int i)
78+
{
79+
return 0x01L << (i << 3);
80+
}
81+
82+
@Override
83+
public String getAlgorithmName()
84+
{
85+
return algorithmName;
86+
}
87+
88+
@Override
89+
public int getDigestSize()
90+
{
91+
return CRYPTO_BYTES;
92+
}
93+
94+
@Override
95+
public int getByteLength()
96+
{
97+
return 8;
98+
}
99+
100+
@Override
101+
public void update(byte in)
102+
{
103+
buffer.write(in);
104+
}
105+
106+
@Override
107+
public void update(byte[] input, int inOff, int len)
108+
{
109+
if ((inOff + len) > input.length)
110+
{
111+
throw new DataLengthException("input buffer too short");
112+
}
113+
buffer.write(input, inOff, len);
114+
}
115+
116+
@Override
117+
public int doFinal(byte[] output, int outOff)
118+
{
119+
if (CRYPTO_BYTES + outOff > output.length)
120+
{
121+
throw new OutputLengthException("output buffer is too short");
122+
}
123+
byte[] input = buffer.toByteArray();
124+
int len = buffer.size();
125+
int inOff = 0;
126+
/* absorb full plaintext blocks */
127+
int ASCON_HASH_RATE = 8;
128+
while (len >= ASCON_HASH_RATE)
129+
{
130+
x0 ^= Pack.littleEndianToLong(input, inOff, 8);
131+
P(ASCON_PB_ROUNDS);
132+
inOff += ASCON_HASH_RATE;
133+
len -= ASCON_HASH_RATE;
134+
}
135+
/* absorb final plaintext block */
136+
x0 ^= Pack.littleEndianToLong(input, inOff, len);
137+
x0 ^= PAD(len);
138+
P(12);
139+
/* squeeze full output blocks */
140+
len = CRYPTO_BYTES;
141+
while (len > ASCON_HASH_RATE)
142+
{
143+
Pack.longToLittleEndian(x0, output, outOff, 8);
144+
P(ASCON_PB_ROUNDS);
145+
outOff += ASCON_HASH_RATE;
146+
len -= ASCON_HASH_RATE;
147+
}
148+
/* squeeze final output block */
149+
Pack.longToLittleEndian(x0, output, outOff, len);
150+
reset();
151+
return CRYPTO_BYTES;
152+
}
153+
154+
@Override
155+
public void reset()
156+
{
157+
buffer.reset();
158+
/* initialize */
159+
x0 = -7269279749984954751L;
160+
x1 = 5459383224871899602L;
161+
x2 = -5880230600644446182L;
162+
x3 = 4359436768738168243L;
163+
x4 = 1899470422303676269L;
164+
}
165+
}

0 commit comments

Comments
 (0)