DHKeyGenerator comment nit and discussion on minimum random key size
Bernd Eckenfels
ecki at zusammenkunft.net
Sun Aug 21 14:40:56 UTC 2016
Hello,
to answer myself, it can be done with setBit. I have discussed it here:
http://crypto.stackexchange.com/questions/39498/generating-dh-key-with-minimum-size
an optimized loop would then look like:
do {
// generate random x between 2^(lSize-1) and (2^lSize)-1
x = new BigInteger(lSize - 1, random);
x = x.setBit(lSize);
} while (x.compareTo(pMinus1) >= 0);
BTW: the sentence "Repeat if either of the followings does not hold"
is wrong, this is not mandated in PKCS3. It is different if l is
specified or not and it does not require a loop of the condition can be
satisifed in another way.
Gruss
Bernd
Am Sun, 21 Aug 2016 14:51:05 +0200
schrieb Bernd Eckenfels <ecki at zusammenkunft.net>:
> Hallo,
>
> I have noticed in DHKeyGenerator, that there is a comment which is not
> totally correct:
>
> http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/496a116876a3/src/java.base/share/classes/com/sun/crypto/provider/DHKeyPairGenerator.java#l192
>
> 192 // generate random x up to 2^lSize bits long
> 193 x = new BigInteger(lSize, random);
>
> I think the comment should read
>
> // generate random x up to lsize bits long
>
> however, the comment adds more value if it refers to the BigInteger
> spec:
>
> // generate random 0 <= x <= (2^lsize)-1
>
>
> While finding this, I also noticed that the code has changed in JDK8.
> The old form used the simple rule of applied crypto handbook:
>
>
> 170 // Handbook of Applied Cryptography: Menezes, et.al.
> 171 // Repeat if the following does not hold:
> 172 // 1 <= x <= p-2
> 173 //
> 174 do {
> 175 // generate random x up to 2^lSize bits long
> 176 x = new BigInteger(lSize, random);
> 177 } while ((x.compareTo(BigInteger.ONE) < 0) ||
> 178 ((x.compareTo(pMinus2) > 0)));
>
> (Which I always wondered if it is not to simple). This code uses p-2
> as the upper bound.
>
>
> The current code specifies it uses PKCS rules where
>
> 186 // PKCS#3 section 7.1 "Private-value generation"
> 187 // Repeat if either of the followings does not hold:
> 188 // 0 < x < p-1
> 189 // 2^(lSize-1) <= x < 2^(lSize)
> 190 //
> 191 do {
> 192 // generate random x up to 2^lSize bits long
> 193 x = new BigInteger(lSize, random);
> 194 } while ((x.compareTo(BigInteger.ONE) < 0) ||
> 195 ((x.compareTo(pMinus2) > 0)) || (x.bitLength() !=
> lSize));
>
> IMHO It should either mention that the check is equivalent to x <= p-2
> or use the x.compareTo(pMinus1) >= 0 instead.
>
> The lower bound 2^(lSize-1) <= x (represented as x.bitLength) is
> always stricter than 0<x, therefore I guess this check can be removed
> in the while condition.
>
> this results in:
>
> while ((x.bitLength() != lSize) || (x.compareTo(pMinus1) >= 0))
>
>
> BTW1: would it be a good addition to BigInteger or an helper to
> generate a random number with a minimum number of bitlength as well?
> This way situations where a minimum bit length is mandated it can be
> used instead of an additional loop.
>
> new BigInteger(minLen, maxLen, random)
>
> which ensures the higest bit is always set, consequently returning
> random numbers between (2^minLen-1) and (2^maxLen)-1.
>
> BTW2: I was not aware that the key genration in JDK8 changed
> http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/6e2a5637b286 - that
> change only talks about interop. MAybe a documentation that key
> generation was changed can be backfilled? (instinctively one can say
> the key generation is stricter, on the other hand it reduces the
> keyspace by one bit).
>
> Gruss
> Bernd
More information about the security-dev
mailing list