Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8273162

AbstractSplittableWithBrineGenerator does not create a random salt

    XMLWordPrintable

Details

    • b15
    • generic
    • generic
    • Verified

    Backports

      Description

        A DESCRIPTION OF THE PROBLEM :
        Class: java.base/jdk/internal/util/random/RandomSupport.java
        Internal Class: RandomSupport.AbstractSplittableWithBrineGenerator
        Method: makeSplitsSpliterator

        This method is intending to create a salt from a random long. The salt should have random letters of size 4 for each consecutive 4 bits and then the last 4 bits as ff, i.e. all bits set.

        However the loop is never executed, the random bits are not used and the salt is always the same.

        This condition is false on the first execution:

        long multiplier = (1L << SALT_SHIFT) - 1;
        long salt = multiplier << (64 - SALT_SHIFT);
        while ((salt & multiplier) != 0) {

        multiplier == 0xffL
        salt == 0xff00_0000_0000_0000L

        The bitwise AND returns false and the salt is kept as the initial value.

        I believe the intention is to keep shifting the ff digit in the salt to the right while appending random 4 bit digits at the top of the salt. When the initial ff digit reaches the least significant bits then this is detected and the loop stops.

        This can be corrected by changing:

        while ((salt & multiplier) != 0) {

        to

        while ((salt & multiplier) == 0) {




        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        I am not familiar with how to make this bug manifest in code. It will apply to splittable generators. I believe the intention is that a call to 'SplittableGenerator#splits()' will create a stream of generators that will have a distinct state cycle (because the salt is random and unique). However the salt will not be random and so successive calls to splits() will create streams of generators that are all using the same state cycle. However given that the salt is only part of the seed state then the output from the generators will still be random and different.

        Here is test code for the salt generation:

          @Test
          public void testSalt() {
            SplittableRandom rng = new SplittableRandom(42L);
            for (int shift = 3; shift <= 5; shift++) {
              for (int i = 0; i < 10; i++) {
                long bits = rng.nextLong();
                System.out.printf("%d %22d -> %22d or %22d%n", shift, bits, getSalt1(shift, bits), getSalt2(shift, bits));
              }
            }
          }

          private static long getSalt1(int SALT_SHIFT, long bits) {
            long multiplier = (1L << SALT_SHIFT) - 1;
            long salt = multiplier << (64 - SALT_SHIFT);
            while ((salt & multiplier) != 0) {
              long digit = Math.multiplyHigh(bits, multiplier);
              salt = (salt >>> SALT_SHIFT) | (digit << (64 - SALT_SHIFT));
              bits *= multiplier;
            }
            return salt;
          }

          private static long getSalt2(int SALT_SHIFT, long bits) {
            long multiplier = (1L << SALT_SHIFT) - 1;
            long salt = multiplier << (64 - SALT_SHIFT);
            while ((salt & multiplier) == 0) {
              long digit = Math.multiplyHigh(bits, multiplier);
              salt = (salt >>> SALT_SHIFT) | (digit << (64 - SALT_SHIFT));
              bits *= multiplier;
            }
            return salt;
          }

        This will output the same salt using the current implementation or a random salt using the updated version:

        3 -4767286540954276203 -> -2305843009213693952 or 4349124269383043310
        3 2949826092126892291 -> -2305843009213693952 or 8945531224453011486
        3 5139283748462763858 -> -2305843009213693952 or 517819905960023966
        3 6349198060258255764 -> -2305843009213693952 or -6659264277579162322
        3 701532786141963250 -> -2305843009213693952 or 5085857321298041998
        3 -2430762948046562554 -> -2305843009213693952 or -7817602704379359106
        3 4028864712777624925 -> -2305843009213693952 or -2622394274348337634
        3 -3677692746721775708 -> -2305843009213693952 or 2708571132827182830
        3 6270620877612482005 -> -2305843009213693952 or 5716212649416045870
        3 -7037763681458882642 -> -2305843009213693952 or -2998217625047725730
        4 3779771651426294207 -> -1152921504606846976 or 212116472798449983
        4 9094045341461139646 -> -1152921504606846976 or -3440073421829053057
        4 -8976257307478440218 -> -1152921504606846976 or -7620503532181156977
        4 -8854191821003330121 -> -1152921504606846976 or 8417340289440550287
        4 -6176718654468026660 -> -1152921504606846976 or -5759382560450891857
        4 3752715396868486130 -> -1152921504606846976 or 1725956634110967871
        4 1910607418205583989 -> -1152921504606846976 or 2729220554143385887
        4 9140336935745592861 -> -1152921504606846976 or -7417744488025262465
        4 1723436047706647047 -> -1152921504606846976 or 7718206646484469279
        4 -5737926661510088608 -> -1152921504606846976 or 4401412089535661503
        5 -787210419263134744 -> -576460752303423488 or 8568385709579009520
        5 1347604182271487641 -> -576460752303423488 or -1429488610206153232
        5 -7382086223805147691 -> -576460752303423488 or -737100742167566352
        5 -7013100964912248687 -> -576460752303423488 or -5246235741689107984
        5 1368025501988796752 -> -576460752303423488 or 3035404726796699120
        5 5120214421805786385 -> -576460752303423488 or -7156035961266843152
        5 -4759641710321948619 -> -576460752303423488 or -4432805587863457296
        5 -3956836574347814625 -> -576460752303423488 or 7601807688214426608
        5 -1071251766013039353 -> -576460752303423488 or 4194725726029200880
        5 -5641428018500444605 -> -576460752303423488 or 1152243442133003760





        ---------- BEGIN SOURCE ----------
        Given that the salt member variable is package private it should be possible to construct a RandomSplitsSpliteratorWithSalt class using the AbstractSplittableWithBrineGenerator.makeSplitsSpliterator method and assert that the salt is always the same.


        ---------- END SOURCE ----------

        Attachments

          Issue Links

            Activity

              People

                jlaskey Jim Laskey
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: