66import org .bouncycastle .crypto .DataLengthException ;
77import org .bouncycastle .crypto .InvalidCipherTextException ;
88import org .bouncycastle .crypto .OutputLengthException ;
9+ import org .bouncycastle .util .Arrays ;
910
1011/**
1112 * Photon-Beetle, https://www.isical.ac.in/~lightweight/beetle/
@@ -30,7 +31,9 @@ public enum PhotonBeetleParameters
3031 private byte [] state ;
3132 private byte [][] state_2d ;
3233 private boolean initialised ;
33- private final ByteArrayOutputStream aadData = new ByteArrayOutputStream ();
34+ private final byte [] aadData ;
35+ private int aadOff ;
36+ private int aadLen ;
3437 private final ByteArrayOutputStream message = new ByteArrayOutputStream ();
3538 private final int RATE_INBYTES ;
3639 private final int RATE_INBYTES_HALF ;
@@ -84,6 +87,7 @@ public PhotonBeetleEngine(PhotonBeetleParameters pbp)
8487 LAST_THREE_BITS_OFFSET = (STATE_INBITS - ((STATE_INBYTES - 1 ) << 3 ) - 3 );
8588 initialised = false ;
8689 algorithmName = "Photon-Beetle AEAD" ;
90+ aadData = new byte [RATE_INBYTES ];
8791 }
8892
8993 @ Override
@@ -103,7 +107,14 @@ public void init(boolean forEncryption, CipherParameters params)
103107 @ Override
104108 public void processAADByte (byte input )
105109 {
106- aadData .write (input );
110+ if (aadOff >= aadData .length )
111+ {
112+ PHOTON_Permutation ();
113+ XOR (aadData , 0 , RATE_INBYTES );
114+ aadOff = 0 ;
115+ }
116+ aadData [aadOff ++] = input ;
117+ aadLen ++;
107118 }
108119
109120 @ Override
@@ -113,7 +124,28 @@ public void processAADBytes(byte[] input, int inOff, int len)
113124 {
114125 throw new DataLengthException ("input buffer too short" );
115126 }
116- aadData .write (input , inOff , len );
127+ int tmp ;
128+ aadLen += len ;
129+ if (aadOff + len >= RATE_INBYTES )
130+ {
131+ tmp = RATE_INBYTES - aadOff ;
132+ System .arraycopy (input , inOff , aadData , aadOff , tmp );
133+ PHOTON_Permutation ();
134+ XOR (aadData , 0 , RATE_INBYTES );
135+ inOff += tmp ;
136+ len -= tmp ;
137+ aadOff = 0 ;
138+ }
139+ while (len >= RATE_INBYTES )
140+ {
141+ PHOTON_Permutation ();
142+ XOR (input , inOff , RATE_INBYTES );
143+ inOff += RATE_INBYTES ;
144+ len -= RATE_INBYTES ;
145+ }
146+ System .arraycopy (input , inOff , aadData , aadOff , len );
147+ aadOff += len ;
148+
117149 }
118150
119151 @ Override
@@ -144,29 +176,22 @@ public int doFinal(byte[] output, int outOff)
144176 }
145177 byte [] input = message .toByteArray ();
146178 int inOff = 0 ;
147- byte [] a = aadData . toByteArray ();
148- int adlen = a . length , i ;
149- if (adlen != 0 || len != 0 )
179+
180+ int i ;
181+ if (aadLen != 0 || len != 0 )
150182 {
151183 input_empty = false ;
152184 }
153- byte c0 = select ((len != 0 ), ((adlen % RATE_INBYTES ) == 0 ), (byte )3 , (byte )4 );
154- byte c1 = select ((adlen != 0 ), ((len % RATE_INBYTES ) == 0 ), (byte )5 , (byte )6 );
185+ byte c0 = select ((len != 0 ), ((aadLen % RATE_INBYTES ) == 0 ), (byte )3 , (byte )4 );
186+ byte c1 = select ((aadLen != 0 ), ((len % RATE_INBYTES ) == 0 ), (byte )5 , (byte )6 );
155187 int Dlen_inblocks , LastDBlocklen ;
156- if (adlen != 0 )
188+ if (aadLen != 0 )
157189 {
158- Dlen_inblocks = (adlen + RATE_INBYTES - 1 ) / RATE_INBYTES ;
159- for (i = 0 ; i < Dlen_inblocks - 1 ; i ++)
190+ if (aadOff != 0 )
160191 {
161192 PHOTON_Permutation ();
162- XOR (a , i * RATE_INBYTES , RATE_INBYTES );
163- }
164- PHOTON_Permutation ();
165- LastDBlocklen = adlen - i * RATE_INBYTES ;
166- XOR (a , i * RATE_INBYTES , LastDBlocklen );
167- if (LastDBlocklen < RATE_INBYTES )
168- {
169- state [LastDBlocklen ] ^= 0x01 ; // ozs
193+ XOR (aadData , 0 , aadOff );
194+ state [aadOff ] ^= 0x01 ; // ozs
170195 }
171196 state [STATE_INBYTES - 1 ] ^= c0 << LAST_THREE_BITS_OFFSET ;
172197 }
@@ -241,7 +266,9 @@ public void reset()
241266 protected void reset (boolean clearMac )
242267 {
243268 input_empty = true ;
244- aadData .reset ();
269+ Arrays .fill (aadData , (byte )0 );
270+ aadOff = 0 ;
271+ aadLen = 0 ;
245272 message .reset ();
246273 System .arraycopy (K , 0 , state , 0 , K .length );
247274 System .arraycopy (N , 0 , state , K .length , N .length );
0 commit comments