@@ -69,8 +69,7 @@ private enum State
6969 private final ByteArrayOutputStream aadData = new ByteArrayOutputStream ();
7070 private int inputOff ;
7171 private byte [] inputMessage ;
72- private final byte [] previous_outputMessage ;
73- private final byte [] outputMessage ;
72+ private int messageLen ;
7473
7574 private final byte [] sBoxLayer = {
7675 (byte )0xee , (byte )0xed , (byte )0xeb , (byte )0xe0 , (byte )0xe2 , (byte )0xe1 , (byte )0xe4 , (byte )0xef , (byte )0xe7 , (byte )0xea , (byte )0xe8 , (byte )0xe5 , (byte )0xe9 , (byte )0xec , (byte )0xe3 , (byte )0xe6 ,
@@ -100,6 +99,7 @@ private enum State
10099
101100 public ElephantEngine (ElephantParameters parameters )
102101 {
102+
103103 switch (parameters )
104104 {
105105 case elephant160 :
@@ -117,14 +117,14 @@ public ElephantEngine(ElephantParameters parameters)
117117 nSBox = 22 ;
118118 nRounds = 90 ;
119119 lfsrIV = 0x45 ;
120- CRYPTO_ABYTES = 8 ;
121120 algorithmName = "Elephant 176 AEAD" ;
121+ CRYPTO_ABYTES = 8 ;
122122 break ;
123123 case elephant200 :
124124 BLOCK_SIZE = 25 ;
125125 nRounds = 18 ;
126- CRYPTO_ABYTES = 16 ;
127126 algorithmName = "Elephant 200 AEAD" ;
127+ CRYPTO_ABYTES = 16 ;
128128 break ;
129129 default :
130130 throw new IllegalArgumentException ("Invalid parameter settings for Elephant" );
@@ -135,8 +135,6 @@ public ElephantEngine(ElephantParameters parameters)
135135 current_mask = new byte [BLOCK_SIZE ];
136136 next_mask = new byte [BLOCK_SIZE ];
137137 buffer = new byte [BLOCK_SIZE ];
138- previous_outputMessage = new byte [BLOCK_SIZE ];
139- outputMessage = new byte [BLOCK_SIZE ];
140138 initialised = false ;
141139 reset (false );
142140 }
@@ -303,16 +301,16 @@ private void get_c_block(byte[] output, byte[] c, int cOff, int clen, int i)
303301 // Fill with ciphertext if available
304302 if (BLOCK_SIZE <= r_clen )
305303 { // enough ciphertext
306- System .arraycopy (c , cOff , output , 0 , BLOCK_SIZE );
304+ System .arraycopy (c , cOff + block_offset , output , 0 , BLOCK_SIZE );
307305 }
308306 else
309307 { // not enough ciphertext, need to pad
310308 if (r_clen > 0 ) // c might be nullptr
311309 {
312- System .arraycopy (c , cOff , output , 0 , r_clen );
310+ System .arraycopy (c , cOff + block_offset , output , 0 , r_clen );
311+ Arrays .fill (output , r_clen , BLOCK_SIZE , (byte )0 );
312+ output [r_clen ] = 0x01 ;
313313 }
314- Arrays .fill (output , r_clen , BLOCK_SIZE , (byte )0 );
315- output [r_clen ] = 0x01 ;
316314 }
317315 }
318316
@@ -390,32 +388,25 @@ public int processBytes(byte[] input, int inOff, int len, byte[] output, int out
390388 {
391389 throw new DataLengthException ("input buffer too short" );
392390 }
393- byte [] ad = aadData .toByteArray ();
394-
395391
396392 if (inputOff + len - (forEncryption ? 0 : CRYPTO_ABYTES ) >= BLOCK_SIZE )
397393 {
398- switch (m_state )
399- {
400- case EncInit :
401- case DecInit :
402- processAADBytes (tag_buffer );
403- break ;
404- }
405394 int mlen = inputOff + len - (forEncryption ? 0 : CRYPTO_ABYTES );
406- int adlen = ad . length ;
407- int nblocks_c = mlen / BLOCK_SIZE ;
408- int nblocks_m = 1 + ((mlen % BLOCK_SIZE ) != 0 ? nblocks_c : nblocks_c - 1 );
395+ int adlen = processAADBytes () ;
396+ int nblocks_c = 1 + mlen / BLOCK_SIZE ;
397+ int nblocks_m = ((mlen % BLOCK_SIZE ) != 0 ? nblocks_c : nblocks_c - 1 );
409398 int nblocks_ad = 1 + (CRYPTO_NPUBBYTES + adlen ) / BLOCK_SIZE ;
399+ int nb_it = Math .max (nblocks_c + 1 , nblocks_ad - 1 );
410400 byte [] tempInput = new byte [Math .max (nblocks_c , 1 ) * BLOCK_SIZE ];
411401 System .arraycopy (inputMessage , 0 , tempInput , 0 , inputOff );
412- int templen = tempInput .length - inputOff ;
413- System .arraycopy (input , inOff , tempInput , inputOff , tempInput .length - inputOff );
414- processBytes (tempInput , output , outOff , nblocks_c , nblocks_m , nblocks_c , mlen , nblocks_ad );
415- inputOff = len - templen ;
416- System .arraycopy (input , inOff + templen , inputMessage , 0 , inputOff );
417- nb_its += nblocks_c ;
418- return nblocks_c * BLOCK_SIZE ;
402+ System .arraycopy (input , inOff , tempInput , inputOff , Math .min (len , tempInput .length ));
403+ int rv = processBytes (tempInput , output , outOff , nb_it , nblocks_m , nblocks_c , mlen , nblocks_ad );
404+ int copyLen = rv - inputOff ;
405+ inputOff = inputOff + len - rv ;
406+ System .arraycopy (input , inOff + copyLen , inputMessage , 0 , inputOff );
407+ nb_its += nblocks_c + 1 ;
408+ messageLen += rv ;
409+ return rv ;
419410 }
420411 else
421412 {
@@ -439,16 +430,8 @@ public int doFinal(byte[] output, int outOff)
439430 {
440431 throw new OutputLengthException ("output buffer is too short" );
441432 }
442- byte [] ad = aadData .toByteArray ();
443- switch (m_state )
444- {
445- case EncInit :
446- case DecInit :
447- processAADBytes (tag_buffer );
448- break ;
449- }
450- int mlen = len + nb_its * BLOCK_SIZE - (forEncryption ? 0 : CRYPTO_ABYTES );
451- int adlen = ad .length ;
433+ int mlen = len + messageLen - (forEncryption ? 0 : CRYPTO_ABYTES );
434+ int adlen = processAADBytes ();
452435 int nblocks_c = 1 + mlen / BLOCK_SIZE ;
453436 int nblocks_m = (mlen % BLOCK_SIZE ) != 0 ? nblocks_c : nblocks_c - 1 ;
454437 int nblocks_ad = 1 + (CRYPTO_NPUBBYTES + adlen ) / BLOCK_SIZE ;
@@ -527,6 +510,19 @@ public void reset()
527510 reset (true );
528511 }
529512
513+ private int processAADBytes ()
514+ {
515+ byte [] ad = aadData .toByteArray ();
516+ switch (m_state )
517+ {
518+ case EncInit :
519+ case DecInit :
520+ processAADBytes (tag_buffer );
521+ break ;
522+ }
523+ return ad .length ;
524+ }
525+
530526 private void reset (boolean clearMac )
531527 {
532528 if (clearMac )
@@ -538,6 +534,7 @@ private void reset(boolean clearMac)
538534 inputOff = 0 ;
539535 nb_its = 0 ;
540536 adOff = -1 ;
537+ messageLen = 0 ;
541538 }
542539
543540 public int getKeyBytesSize ()
@@ -645,6 +642,7 @@ private int processBytes(byte[] m, byte[] output, int outOff, int nb_it, int nbl
645642 int nblocks_ad )
646643 {
647644 int rv = 0 ;
645+ int original_outOff = outOff ;
648646 for (int i = nb_its ; i < nb_it ; ++i )
649647 {
650648 // Compute mask for the next message
@@ -660,22 +658,22 @@ private int processBytes(byte[] m, byte[] output, int outOff, int nb_it, int nbl
660658 xor_block (buffer , current_mask , 0 , BLOCK_SIZE );
661659 xor_block (buffer , next_mask , 0 , BLOCK_SIZE );
662660 int r_size = (i == nblocks_m - 1 ) ? mlen - i * BLOCK_SIZE : BLOCK_SIZE ;
663- xor_block (buffer , m , 0 , r_size );
661+ xor_block (buffer , m , rv , r_size );
664662 System .arraycopy (buffer , 0 , output , outOff , r_size );
663+ outOff += r_size ;
664+ rv += r_size ;
665+ }
666+ if (i > 0 && i <= nblocks_c )
667+ {
668+ // Compute tag for ciphertext block
665669 if (forEncryption )
666670 {
667- System . arraycopy (buffer , 0 , outputMessage , 0 , r_size );
671+ get_c_block (buffer , output , original_outOff , mlen , i - 1 );
668672 }
669673 else
670674 {
671- System . arraycopy ( m , 0 , outputMessage , 0 , r_size );
675+ get_c_block ( buffer , m , 0 , mlen , i - 1 );
672676 }
673- rv += r_size ;
674- }
675- if (i > 0 && i <= nblocks_c )
676- {
677- // Compute tag for ciphertext block
678- get_c_block (buffer , previous_outputMessage , 0 , mlen , i - 1 );
679677 xor_block (buffer , previous_mask , 0 , BLOCK_SIZE );
680678 xor_block (buffer , next_mask , 0 , BLOCK_SIZE );
681679 permutation (buffer );
@@ -698,7 +696,6 @@ private int processBytes(byte[] m, byte[] output, int outOff, int nb_it, int nbl
698696 previous_mask = current_mask ;
699697 current_mask = next_mask ;
700698 next_mask = temp ;
701- System .arraycopy (outputMessage , 0 , previous_outputMessage , 0 , BLOCK_SIZE );
702699 }
703700 return rv ;
704701 }
0 commit comments