@@ -45,7 +45,7 @@ public String getName()
4545 public void performTest ()
4646 throws Exception
4747 {
48- testDecryptionFailureCounter ();
48+ testCounter ();
4949 testVectorsAsconCXof128_512 ();
5050 DigestTest .checkXof (new AsconXof128 (), 1429 , 317 , new SecureRandom (), this );
5151 DigestTest .checkXof (new AsconCXof128 (), 1429 , 317 , new SecureRandom (), this );
@@ -1357,7 +1357,7 @@ private static void initEngine(AEADCipher ascon, boolean forEncryption)
13571357 ascon .init (forEncryption , parameters );
13581358 }
13591359
1360- protected static class DecryptionFailureCounter
1360+ protected static class Counter
13611361 {
13621362 int n ;
13631363 int [] counter ;
@@ -1396,7 +1396,56 @@ public boolean increment()
13961396 return false ;
13971397 }
13981398 }
1399- return counter [0 ] != ((n & 31 ) == 0 ? 0 : 1 << (n & 31 ));
1399+ return counter [0 ] == 1 << (n & 31 );
1400+ }
1401+
1402+ public boolean increment (int delta )
1403+ {
1404+ // Convert to long to handle unsigned arithmetic
1405+ long carry = delta & 0xFFFFFFFFL ;
1406+ boolean limitReached = false ;
1407+
1408+ // Process each word starting from LSB
1409+ for (int i = counter .length - 1 ; i >= 0 && carry != 0 ; --i )
1410+ {
1411+ long sum = (counter [i ] & 0xFFFFFFFFL ) + carry ;
1412+ counter [i ] = (int )sum ;
1413+ carry = sum >>> 32 ;
1414+
1415+ // Check if we've passed the limit during carry propagation
1416+ if (carry != 0 && i == counter .length - 1 )
1417+ {
1418+ limitReached = true ;
1419+ }
1420+ }
1421+
1422+ // Final limit check if we didn't overflow
1423+ return limitReached || checkLimit ();
1424+ }
1425+
1426+ private boolean checkLimit ()
1427+ {
1428+ int bitIndex = n & 31 ;
1429+ long bound = 1L << bitIndex ;
1430+ long val = counter [0 ] & 0xFFFFFFFFL ;
1431+ if (val > bound )
1432+ {
1433+ return true ;
1434+ }
1435+ if (val < bound )
1436+ {
1437+ return false ;
1438+ }
1439+ // Check if we've reached/exceeded 2^n
1440+ for (int i = 1 ; i < counter .length ; ++i )
1441+ {
1442+ val = counter [i ] & 0xFFFFFFFFL ;
1443+ if (val > 0 )
1444+ {
1445+ return true ;
1446+ }
1447+ }
1448+ return true ; // Exactly equal to 2^n
14001449 }
14011450
14021451 public void reset ()
@@ -1405,24 +1454,34 @@ public void reset()
14051454 }
14061455 }
14071456
1408- public void testDecryptionFailureCounter ()
1409- {
1410- int n = 34 ;
1411- DecryptionFailureCounter counter = new DecryptionFailureCounter ();
1412- counter .init (n );
1413- counter .counter [counter .counter .length - 1 ] = -2 ;
1414- counter .counter [0 ] = 1 ;
1415- isTrue (!counter .increment ());
1416- isTrue (counter .increment ());
1417-
1418- counter .init (32 );
1419- counter .counter [counter .counter .length - 1 ] = -1 ;
1420- isTrue (!counter .increment ());
1421- isTrue (counter .increment ());
1457+ public void testCounter ()
1458+ {
1459+ // int n = 33;
1460+ Counter counter = new Counter ();
1461+ // counter.init(33);
1462+ // isTrue(!counter.increment(-1));
1463+ // isTrue(!counter.increment());
1464+ // isTrue(!counter.increment(-1));
1465+ // isTrue(counter.increment());
1466+ //
1467+ // counter.init(32);
1468+ // isTrue(!counter.increment(-1));
1469+ // isTrue(counter.increment());
1470+ // counter.reset();
1471+ // isTrue(!counter.increment());
1472+ // counter.reset();
1473+ // isTrue(!counter.increment(-1));
1474+ // isTrue(counter.increment(1));
1475+ //
1476+ // counter.init(31);
1477+ // isTrue(!counter.increment(1 << 30));
1478+ // isTrue(counter.increment());
1479+ // counter.reset();
1480+ // isTrue(!counter.increment(1 << 30));
1481+ // isTrue(counter.increment(1 << 30));
14221482
14231483 counter .init (5 );
1424- counter .counter [counter .counter .length - 1 ] = (1 << 5 ) - 1 ;
1425- isTrue (!counter .increment ());
1484+ isTrue (!counter .increment ((1 << 5 ) - 1 ));
14261485 isTrue (counter .increment ());
14271486 }
14281487}
0 commit comments