11package org .bouncycastle .crypto .digests ;
22
3- import java .io .ByteArrayOutputStream ;
4-
5- import org .bouncycastle .crypto .DataLengthException ;
6- import org .bouncycastle .crypto .Digest ;
7- import org .bouncycastle .crypto .OutputLengthException ;
83import org .bouncycastle .util .Arrays ;
94import org .bouncycastle .util .Integers ;
105import org .bouncycastle .util .Pack ;
1712 */
1813
1914public class XoodyakDigest
20- implements Digest
15+ extends BufferBaseDigest
2116{
22- private byte [] state ;
17+ private final byte [] state ;
2318 private int phase ;
2419 private MODE mode ;
25- private int Rabsorb ;
2620 private final int f_bPrime = 48 ;
27- private final int Rhash = 16 ;
28- private final int PhaseDown = 1 ;
2921 private final int PhaseUp = 2 ;
30- private final int MAXROUNDS = 12 ;
31- private final int TAGLEN = 16 ;
22+ private int Cd ;
3223 private final int [] RC = {0x00000058 , 0x00000038 , 0x000003C0 , 0x000000D0 , 0x00000120 , 0x00000014 , 0x00000060 ,
3324 0x0000002C , 0x00000380 , 0x000000F0 , 0x000001A0 , 0x00000012 };
34- private final ByteArrayOutputStream buffer = new ByteArrayOutputStream ();
3525
3626 enum MODE
3727 {
@@ -41,69 +31,40 @@ enum MODE
4131
4232 public XoodyakDigest ()
4333 {
34+ DigestSize = 32 ;
4435 state = new byte [48 ];
36+ BlockSize = 16 ;
37+ m_buf = new byte [BlockSize ];
38+ algorithmName = "Xoodyak Hash" ;
4539 reset ();
4640 }
4741
4842 @ Override
49- public String getAlgorithmName ()
50- {
51- return "Xoodyak Hash" ;
52- }
53-
54- @ Override
55- public int getDigestSize ()
56- {
57- return 32 ;
58- }
59-
60- @ Override
61- public void update (byte input )
62- {
63- buffer .write (input );
64- }
65-
66- @ Override
67- public void update (byte [] input , int inOff , int len )
43+ protected void processBytes (byte [] input , int inOff )
6844 {
69- if (( inOff + len ) > input . length )
45+ if (phase != PhaseUp )
7046 {
71- throw new DataLengthException ( "input buffer too short" );
47+ Up ( null , 0 , 0 , 0 );
7248 }
73- buffer . write (input , inOff , len );
74-
49+ Down (input , inOff , BlockSize , Cd );
50+ Cd = 0 ;
7551 }
7652
7753 @ Override
78- public int doFinal (byte [] output , int outOff )
54+ protected void finish (byte [] output , int outOff )
7955 {
80- if (32 + outOff > output .length )
81- {
82- throw new OutputLengthException ("output buffer is too short" );
83- }
84- byte [] input = buffer .toByteArray ();
85- int inOff = 0 ;
86- int len = buffer .size ();
87- int Cd = 0x03 ;
88- int splitLen ;
89- do
56+ if (m_bufPos != 0 )
9057 {
9158 if (phase != PhaseUp )
9259 {
9360 Up (null , 0 , 0 , 0 );
9461 }
95- splitLen = Math .min (len , Rabsorb );
96- Down (input , inOff , splitLen , Cd );
97- Cd = 0 ;
98- inOff += splitLen ;
99- len -= splitLen ;
62+ Down (m_buf , 0 , m_bufPos , Cd );
10063 }
101- while ( len != 0 ) ;
64+ int TAGLEN = 16 ;
10265 Up (output , outOff , TAGLEN , 0x40 );
10366 Down (null , 0 , 0 , 0 );
10467 Up (output , outOff + TAGLEN , TAGLEN , 0 );
105- reset ();
106- return 32 ;
10768 }
10869
10970 @ Override
@@ -112,8 +73,9 @@ public void reset()
11273 Arrays .fill (state , (byte )0 );
11374 phase = PhaseUp ;
11475 mode = MODE .ModeHash ;
115- Rabsorb = Rhash ;
116- buffer .reset ();
76+ Arrays .clear (m_buf );
77+ m_bufPos = 0 ;
78+ Cd = 0x03 ;
11779 }
11880
11981 private void Up (byte [] Yi , int YiOff , int YiLen , int Cu )
@@ -136,6 +98,7 @@ private void Up(byte[] Yi, int YiOff, int YiLen, int Cu)
13698 int a10 = Pack .littleEndianToInt (state , 40 );
13799 int a11 = Pack .littleEndianToInt (state , 44 );
138100
101+ int MAXROUNDS = 12 ;
139102 for (int i = 0 ; i < MAXROUNDS ; ++i )
140103 {
141104 /* Theta: Column Parity Mixer */
@@ -164,7 +127,7 @@ private void Up(byte[] Yi, int YiOff, int YiLen, int Cu)
164127 a3 ^= e3 ;
165128 a7 ^= e3 ;
166129 a11 ^= e3 ;
167-
130+
168131 /* Rho-west: plane shift */
169132 int b0 = a0 ;
170133 int b1 = a1 ;
@@ -183,7 +146,7 @@ private void Up(byte[] Yi, int YiOff, int YiLen, int Cu)
183146
184147 /* Iota: round ant */
185148 b0 ^= RC [i ];
186-
149+
187150 /* Chi: non linear layer */
188151 a0 = b0 ^ (~b4 & b8 );
189152 a1 = b1 ^ (~b5 & b9 );
@@ -199,7 +162,7 @@ private void Up(byte[] Yi, int YiOff, int YiLen, int Cu)
199162 b9 ^= (~b1 & b5 );
200163 b10 ^= (~b2 & b6 );
201164 b11 ^= (~b3 & b7 );
202-
165+
203166 /* Rho-east: plane shift */
204167 a4 = Integers .rotateLeft (a4 , 1 );
205168 a5 = Integers .rotateLeft (a5 , 1 );
@@ -240,6 +203,6 @@ void Down(byte[] Xi, int XiOff, int XiLen, int Cd)
240203 }
241204 state [XiLen ] ^= 0x01 ;
242205 state [f_bPrime - 1 ] ^= (mode == MODE .ModeHash ) ? (Cd & 0x01 ) : Cd ;
243- phase = PhaseDown ;
206+ phase = 1 ;
244207 }
245208}
0 commit comments