1
$\begingroup$

I run an open source project implementing some RipeMD and SHA hashes, one day I got nerdy and threw together my own Sponge function. I have now tested it with the dieharder 3.31.1 test suite. Is it acceptable to use as an PRNG for cryptography? This is the results:

> dieharder -a -f IdeaProjects/angelos-project-crypt/sponge.bin 
#=============================================================================#
#            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
#=============================================================================#
   rng_name    |           filename             |rands/second|
        mt19937|IdeaProjects/angelos-project-crypt/sponge.bin|  1.54e+08  |
#=============================================================================#
        test_name   |ntup| tsamples |psamples|  p-value |Assessment
#=============================================================================#
   diehard_birthdays|   0|       100|     100|0.29741314|  PASSED  
      diehard_operm5|   0|   1000000|     100|0.90355675|  PASSED  
  diehard_rank_32x32|   0|     40000|     100|0.09680105|  PASSED  
    diehard_rank_6x8|   0|    100000|     100|0.88497509|  PASSED  
   diehard_bitstream|   0|   2097152|     100|0.51462962|  PASSED  
        diehard_opso|   0|   2097152|     100|0.89314254|  PASSED  
        diehard_oqso|   0|   2097152|     100|0.53780624|  PASSED  
         diehard_dna|   0|   2097152|     100|0.36760105|  PASSED  
diehard_count_1s_str|   0|    256000|     100|0.69366264|  PASSED  
diehard_count_1s_byt|   0|    256000|     100|0.66152108|  PASSED  
 diehard_parking_lot|   0|     12000|     100|0.32092307|  PASSED  
    diehard_2dsphere|   2|      8000|     100|0.71844281|  PASSED  
    diehard_3dsphere|   3|      4000|     100|0.37909585|  PASSED  
     diehard_squeeze|   0|    100000|     100|0.20023243|  PASSED  
        diehard_sums|   0|       100|     100|0.62144443|  PASSED  
        diehard_runs|   0|    100000|     100|0.77236221|  PASSED  
        diehard_runs|   0|    100000|     100|0.94063879|  PASSED  
       diehard_craps|   0|    200000|     100|0.19105781|  PASSED  
       diehard_craps|   0|    200000|     100|0.92211531|  PASSED  
 marsaglia_tsang_gcd|   0|  10000000|     100|0.79178970|  PASSED  
 marsaglia_tsang_gcd|   0|  10000000|     100|0.03659520|  PASSED  
         sts_monobit|   1|    100000|     100|0.83442684|  PASSED  
            sts_runs|   2|    100000|     100|0.09095137|  PASSED  
          sts_serial|   1|    100000|     100|0.40236648|  PASSED  
          sts_serial|   2|    100000|     100|0.87652788|  PASSED  
          sts_serial|   3|    100000|     100|0.49927519|  PASSED  
          sts_serial|   3|    100000|     100|0.77902061|  PASSED  
          sts_serial|   4|    100000|     100|0.55240161|  PASSED  
          sts_serial|   4|    100000|     100|0.73160126|  PASSED  
          sts_serial|   5|    100000|     100|0.87317097|  PASSED  
          sts_serial|   5|    100000|     100|0.28445531|  PASSED  
          sts_serial|   6|    100000|     100|0.76610989|  PASSED  
          sts_serial|   6|    100000|     100|0.03522221|  PASSED  
          sts_serial|   7|    100000|     100|0.58197692|  PASSED  
          sts_serial|   7|    100000|     100|0.53187944|  PASSED  
          sts_serial|   8|    100000|     100|0.83115449|  PASSED  
          sts_serial|   8|    100000|     100|0.64294087|  PASSED  
          sts_serial|   9|    100000|     100|0.94770237|  PASSED  
          sts_serial|   9|    100000|     100|0.56747611|  PASSED  
          sts_serial|  10|    100000|     100|0.94722485|  PASSED  
          sts_serial|  10|    100000|     100|0.34604921|  PASSED  
          sts_serial|  11|    100000|     100|0.71566033|  PASSED  
          sts_serial|  11|    100000|     100|0.99317603|  PASSED  
          sts_serial|  12|    100000|     100|0.99568394|   WEAK   
          sts_serial|  12|    100000|     100|0.84314212|  PASSED  
          sts_serial|  13|    100000|     100|0.67188110|  PASSED  
          sts_serial|  13|    100000|     100|0.33426603|  PASSED  
          sts_serial|  14|    100000|     100|0.55951121|  PASSED  
          sts_serial|  14|    100000|     100|0.61895131|  PASSED  
          sts_serial|  15|    100000|     100|0.63782432|  PASSED  
          sts_serial|  15|    100000|     100|0.60490933|  PASSED  
          sts_serial|  16|    100000|     100|0.24365935|  PASSED  
          sts_serial|  16|    100000|     100|0.01825019|  PASSED  
         rgb_bitdist|   1|    100000|     100|0.25511084|  PASSED  
         rgb_bitdist|   2|    100000|     100|0.78160123|  PASSED  
         rgb_bitdist|   3|    100000|     100|0.86346874|  PASSED  
         rgb_bitdist|   4|    100000|     100|0.21934989|  PASSED  
         rgb_bitdist|   5|    100000|     100|0.06051574|  PASSED  
         rgb_bitdist|   6|    100000|     100|0.69356798|  PASSED  
         rgb_bitdist|   7|    100000|     100|0.25615210|  PASSED  
         rgb_bitdist|   8|    100000|     100|0.99313684|  PASSED  
         rgb_bitdist|   9|    100000|     100|0.12193544|  PASSED  
         rgb_bitdist|  10|    100000|     100|0.40998421|  PASSED  
         rgb_bitdist|  11|    100000|     100|0.79477040|  PASSED  
         rgb_bitdist|  12|    100000|     100|0.47304485|  PASSED  
rgb_minimum_distance|   2|     10000|    1000|0.95942258|  PASSED  
rgb_minimum_distance|   3|     10000|    1000|0.52655847|  PASSED  
rgb_minimum_distance|   4|     10000|    1000|0.32272802|  PASSED  
rgb_minimum_distance|   5|     10000|    1000|0.31016307|  PASSED  
    rgb_permutations|   2|    100000|     100|0.25521657|  PASSED  
    rgb_permutations|   3|    100000|     100|0.39659659|  PASSED  
    rgb_permutations|   4|    100000|     100|0.58523664|  PASSED  
    rgb_permutations|   5|    100000|     100|0.99143517|  PASSED  
      rgb_lagged_sum|   0|   1000000|     100|0.92651784|  PASSED  
      rgb_lagged_sum|   1|   1000000|     100|0.87079304|  PASSED  
      rgb_lagged_sum|   2|   1000000|     100|0.22619148|  PASSED  
      rgb_lagged_sum|   3|   1000000|     100|0.34505477|  PASSED  
      rgb_lagged_sum|   4|   1000000|     100|0.18581204|  PASSED  
      rgb_lagged_sum|   5|   1000000|     100|0.60116499|  PASSED  
      rgb_lagged_sum|   6|   1000000|     100|0.98932222|  PASSED  
      rgb_lagged_sum|   7|   1000000|     100|0.04374118|  PASSED  
      rgb_lagged_sum|   8|   1000000|     100|0.33544339|  PASSED  
      rgb_lagged_sum|   9|   1000000|     100|0.90441273|  PASSED  
      rgb_lagged_sum|  10|   1000000|     100|0.22257880|  PASSED  
      rgb_lagged_sum|  11|   1000000|     100|0.66960544|  PASSED  
      rgb_lagged_sum|  12|   1000000|     100|0.27262357|  PASSED  
      rgb_lagged_sum|  13|   1000000|     100|0.52498198|  PASSED  
      rgb_lagged_sum|  14|   1000000|     100|0.37751496|  PASSED  
      rgb_lagged_sum|  15|   1000000|     100|0.76524735|  PASSED  
      rgb_lagged_sum|  16|   1000000|     100|0.87963412|  PASSED  
      rgb_lagged_sum|  17|   1000000|     100|0.78610111|  PASSED  
      rgb_lagged_sum|  18|   1000000|     100|0.65942432|  PASSED  
      rgb_lagged_sum|  19|   1000000|     100|0.92103411|  PASSED  
      rgb_lagged_sum|  20|   1000000|     100|0.20000362|  PASSED  
      rgb_lagged_sum|  21|   1000000|     100|0.63948529|  PASSED  
      rgb_lagged_sum|  22|   1000000|     100|0.82132269|  PASSED  
      rgb_lagged_sum|  23|   1000000|     100|0.35830568|  PASSED  
      rgb_lagged_sum|  24|   1000000|     100|0.13945365|  PASSED  
      rgb_lagged_sum|  25|   1000000|     100|0.29604927|  PASSED  
      rgb_lagged_sum|  26|   1000000|     100|0.66900002|  PASSED  
      rgb_lagged_sum|  27|   1000000|     100|0.35142717|  PASSED  
      rgb_lagged_sum|  28|   1000000|     100|0.97404828|  PASSED  
      rgb_lagged_sum|  29|   1000000|     100|0.40686983|  PASSED  
      rgb_lagged_sum|  30|   1000000|     100|0.70110560|  PASSED  
      rgb_lagged_sum|  31|   1000000|     100|0.94398652|  PASSED  
      rgb_lagged_sum|  32|   1000000|     100|0.03111049|  PASSED  
     rgb_kstest_test|   0|     10000|    1000|0.07793768|  PASSED  
     dab_bytedistrib|   0|  51200000|       1|0.66122968|  PASSED  
             dab_dct| 256|     50000|       1|0.06893023|  PASSED  
Preparing to run test 207.  ntuple = 0
        dab_filltree|  32|  15000000|       1|0.53679563|  PASSED  
        dab_filltree|  32|  15000000|       1|0.64155528|  PASSED  
Preparing to run test 208.  ntuple = 0
       dab_filltree2|   0|   5000000|       1|0.25169708|  PASSED  
       dab_filltree2|   1|   5000000|       1|0.82549244|  PASSED  
Preparing to run test 209.  ntuple = 0
        dab_monobit2|  12|  65000000|       1|0.51036954|  PASSED
$\endgroup$
2
  • 4
    $\begingroup$ Validating a PRNG for cryptographic use based on result of statistical tests of it's output is an erroneous design methodology (in a nutshell: because statistical tests make no use of the internal structure of the generator, that they are not even given; when the opposite assumption is made in attacks on PRNG in cryptography, since Kerckhoffs). That many have used that design methodology does not make it less wrong. While the sponge structure is a sound framework, there are still possible pitfalls, e.g. in the sponge design itself. $\endgroup$
    – fgrieu
    Dec 22, 2023 at 21:24
  • $\begingroup$ Well, I am not a mathematician, so presumably there could be pitfalls, do you know where to go from here $\endgroup$ Dec 23, 2023 at 21:58

1 Answer 1

1
$\begingroup$

My code for the Sponge can be found in my repository back in time, about a week. Here

The Sponge is in the file PaulssonSponge.kt, then an abstract class in AbstractPaulssonSponge.kt and finally an application in PaulssonHash.kt

A unit test can be found here.

The binary data was generated from the squeeze function and stored in a not checked in UnitTest, I have it on my Linux machine. I compared the dieharder with the result from Linux /dev/urandom which had two weaknesses, my Sponge had one weakness, so needed to ask questions. Just a nerdy side project.

$\endgroup$
5
  • $\begingroup$ 1.) What drove the decision to construct the sponge function in terms of whole bytes/longs, rather than individual bits as Keccak does? 2.) Where do the initialisation constants for entropyState come from? Just wonderin'. $\endgroup$
    – Paul Uszak
    Dec 23, 2023 at 19:49
  • 1
    $\begingroup$ 1) Actually I was implementing keccak for private use, then I had seen so many permutation functions from Sha1, Sha2 and RipeMD, so I got the idea to experiment with different similar things, technically the Sponge is shuffled according to a pattern, the words are rotated based on the first 16 primes and then there is an Invert and every second Negate which I guess generates a bunch of entropy by itself. $\endgroup$ Dec 23, 2023 at 21:27
  • 1
    $\begingroup$ 2)entropyState could actually be empty (zeros), I did first set them to high 64-bit primes generated with OpenSSL, I then took the values after 10 000 000 000 iterations of MonteCarlo testing, so they are just a later state of the early primes I used. $\endgroup$ Dec 23, 2023 at 21:32
  • $\begingroup$ I perused your source code but couldn't see any non linear components. Do you also include some form of non linearity like a LFSR? $\endgroup$
    – Paul Uszak
    Dec 24, 2023 at 1:36
  • $\begingroup$ I had to read up on LFSR and NLFSR I'm not sure whether there is any of those but there is a bunch of XOR and rotateLeft. The magic happens in the cycle function. By the way I visited your website, very interesting topic. $\endgroup$ Dec 24, 2023 at 10:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.