11package org .bouncycastle .crypto .digests ;
22
3- import org .bouncycastle .crypto .DataLengthException ;
4- import org .bouncycastle .crypto .ExtendedDigest ;
53import org .bouncycastle .crypto .OutputLengthException ;
6- import org .bouncycastle .util .Arrays ;
7- import org .bouncycastle .util .Longs ;
4+ import org .bouncycastle .crypto .engines .AsconPermutationFriend ;
85
96abstract class AsconBaseDigest
10- implements ExtendedDigest
7+ extends BufferBaseDigest
118{
12- protected long x0 ;
13- protected long x1 ;
14- protected long x2 ;
15- protected long x3 ;
16- protected long x4 ;
17- protected final int CRYPTO_BYTES = 32 ;
18- protected final int ASCON_HASH_RATE = 8 ;
19- protected int ASCON_PB_ROUNDS = 12 ;
20- protected final byte [] m_buf = new byte [ASCON_HASH_RATE ];
21- protected int m_bufPos = 0 ;
22-
23-
24- private void round (long C )
9+ public static class Friend
2510 {
26- long t0 = x0 ^ x1 ^ x2 ^ x3 ^ C ^ (x1 & (x0 ^ x2 ^ x4 ^ C ));
27- long t1 = x0 ^ x2 ^ x3 ^ x4 ^ C ^ ((x1 ^ x2 ^ C ) & (x1 ^ x3 ));
28- long t2 = x1 ^ x2 ^ x4 ^ C ^ (x3 & x4 );
29- long t3 = x0 ^ x1 ^ x2 ^ C ^ ((~x0 ) & (x3 ^ x4 ));
30- long t4 = x1 ^ x3 ^ x4 ^ ((x0 ^ x4 ) & x1 );
31- x0 = t0 ^ Longs .rotateRight (t0 , 19 ) ^ Longs .rotateRight (t0 , 28 );
32- x1 = t1 ^ Longs .rotateRight (t1 , 39 ) ^ Longs .rotateRight (t1 , 61 );
33- x2 = ~(t2 ^ Longs .rotateRight (t2 , 1 ) ^ Longs .rotateRight (t2 , 6 ));
34- x3 = t3 ^ Longs .rotateRight (t3 , 10 ) ^ Longs .rotateRight (t3 , 17 );
35- x4 = t4 ^ Longs .rotateRight (t4 , 7 ) ^ Longs .rotateRight (t4 , 41 );
36- }
11+ private static final Friend INSTANCE = new Friend ();
3712
38- protected void p (int nr )
39- {
40- if (nr == 12 )
41- {
42- round (0xf0L );
43- round (0xe1L );
44- round (0xd2L );
45- round (0xc3L );
46- }
47- if (nr >= 8 )
13+ private Friend ()
4814 {
49- round (0xb4L );
50- round (0xa5L );
5115 }
52- round (0x96L );
53- round (0x87L );
54- round (0x78L );
55- round (0x69L );
56- round (0x5aL );
57- round (0x4bL );
5816 }
5917
18+ AsconPermutationFriend .AsconPermutation p ;
19+ protected int ASCON_PB_ROUNDS = 12 ;
20+
21+ protected AsconBaseDigest ()
22+ {
23+ super (ProcessingBufferType .Immediate , 8 );
24+ p = AsconPermutationFriend .getAsconPermutation (ISAPDigest .Friend .getFriend (Friend .INSTANCE ));
25+ DigestSize = 32 ;
26+ }
27+
28+
6029 protected abstract long pad (int i );
6130
6231 protected abstract long loadBytes (final byte [] bytes , int inOff );
@@ -67,106 +36,62 @@ protected void p(int nr)
6736
6837 protected abstract void setBytes (long w , byte [] bytes , int inOff , int n );
6938
70- @ Override
71- public int getDigestSize ()
72- {
73- return CRYPTO_BYTES ;
74- }
75-
76- @ Override
77- public int getByteLength ()
39+ protected void processBytes (byte [] input , int inOff )
7840 {
79- return ASCON_HASH_RATE ;
41+ p .x0 ^= loadBytes (input , inOff );
42+ p .p (ASCON_PB_ROUNDS );
8043 }
8144
82- @ Override
83- public void update (byte in )
45+ protected void finish (byte [] output , int outOff )
8446 {
85- m_buf [m_bufPos ] = in ;
86- if (++m_bufPos == ASCON_HASH_RATE )
87- {
88- x0 ^= loadBytes (m_buf , 0 );
89- p (ASCON_PB_ROUNDS );
90- m_bufPos = 0 ;
91- }
92- }
93-
94- @ Override
95- public void update (byte [] input , int inOff , int len )
96- {
97- if ((inOff + len ) > input .length )
98- {
99- throw new DataLengthException ("input buffer too short" );
100- }
101- int available = 8 - m_bufPos ;
102- if (len < available )
103- {
104- System .arraycopy (input , inOff , m_buf , m_bufPos , len );
105- m_bufPos += len ;
106- return ;
107- }
108- int inPos = 0 ;
109- if (m_bufPos > 0 )
110- {
111- System .arraycopy (input , inOff , m_buf , m_bufPos , available );
112- inPos += available ;
113- x0 ^= loadBytes (m_buf , 0 );
114- p (ASCON_PB_ROUNDS );
115- }
116- int remaining ;
117- while ((remaining = len - inPos ) >= 8 )
118- {
119- x0 ^= loadBytes (input , inOff + inPos );
120- p (ASCON_PB_ROUNDS );
121- inPos += 8 ;
122- }
123- System .arraycopy (input , inOff + inPos , m_buf , 0 , remaining );
124- m_bufPos = remaining ;
125- }
126-
127- @ Override
128- public int doFinal (byte [] output , int outOff )
129- {
130- return hash (output , outOff , CRYPTO_BYTES );
47+ padAndAbsorb ();
48+ /* squeeze full output blocks */
49+ squeeze (output , outOff , DigestSize );
13150 }
13251
13352 protected void padAndAbsorb ()
13453 {
135- x0 ^= loadBytes (m_buf , 0 , m_bufPos );
136- x0 ^= pad (m_bufPos );
137- p (12 );
54+ p .x0 ^= loadBytes (m_buf , 0 , m_bufPos ) ^ pad (m_bufPos );
55+ p .p (12 );
13856 }
13957
14058 protected void squeeze (byte [] output , int outOff , int len )
14159 {
14260 /* squeeze full output blocks */
143- while (len > ASCON_HASH_RATE )
61+ while (len > BlockSize )
14462 {
145- setBytes (x0 , output , outOff );
146- p (ASCON_PB_ROUNDS );
147- outOff += ASCON_HASH_RATE ;
148- len -= ASCON_HASH_RATE ;
63+ setBytes (p . x0 , output , outOff );
64+ p . p (ASCON_PB_ROUNDS );
65+ outOff += BlockSize ;
66+ len -= BlockSize ;
14967 }
15068 /* squeeze final output block */
151- setBytes (x0 , output , outOff , len );
69+ setBytes (p . x0 , output , outOff , len );
15270 reset ();
15371 }
15472
15573 protected int hash (byte [] output , int outOff , int outLen )
15674 {
157- if (CRYPTO_BYTES + outOff > output .length )
158- {
159- throw new OutputLengthException ("output buffer is too short" );
160- }
75+ ensureSufficientOutputBuffer (output , outOff , outLen );
16176 padAndAbsorb ();
16277 /* squeeze full output blocks */
16378 squeeze (output , outOff , outLen );
16479 return outLen ;
16580 }
16681
167- public void reset ( )
82+ protected void ensureSufficientOutputBuffer ( byte [] output , int outOff , int len )
16883 {
169- Arrays .clear (m_buf );
170- m_bufPos = 0 ;
84+ if (outOff + len > output .length )
85+ {
86+ throw new OutputLengthException ("output buffer is too short" );
87+ }
88+ }
89+
90+ protected void ensureNoAbsorbWhileSqueezing (boolean m_squeezing )
91+ {
92+ if (m_squeezing )
93+ {
94+ throw new IllegalArgumentException ("attempt to absorb while squeezing" );
95+ }
17196 }
17297}
0 commit comments