12

I'm about to implement the DSA algorithm, but there is a problem:

choose "p", a prime number with L bits, where 512 <= L <= 1024 and L is a multiple of 64

How can I implement a random generator of that number? Int64 has "only" 63 bits length.

Sildoreth
  • 1,883
  • 1
  • 25
  • 38
Tony
  • 12,405
  • 36
  • 126
  • 226
  • 6
    standard comment: "That's OK for study/experimentation but don't you dare use that in production". – H H Jun 03 '10 at 12:09
  • Also see [Chew Keong TAN's BigInteger class](http://www.weblearn.hs-bremen.de/risse/RST/WS06/single_vs_dual/sources/BigInteger.cs) – jww Feb 16 '17 at 03:02

1 Answers1

15

You can generate a random number with n bits using this code:

var rng = new RNGCryptoServiceProvider();
byte[] bytes = new byte[n / 8];
rng.GetBytes(bytes);

BigInteger p = new BigInteger(bytes);

The result is, of course, random and not necessarily a prime.

The BigInteger class was introduced in the .NET 4.0 Framework.


For generating large prime numbers, Wikipedia says:

For the large primes used in cryptography, it is usual to use a modified form of sieving: a randomly-chosen range of odd numbers of the desired size is sieved against a number of relatively small odd primes (typically all primes less than 65,000). The remaining candidate primes are tested in random order with a standard primality test such as the Miller-Rabin primality test for probable primes.

So you could do something like this:

var p = Enumerable.Range(0, numberOfCandidates)
                  .Select(i => RandomOddNumber(bits))
                  .Where(x => !primesLessThan65000.Contains(x))
                  .Where(x => PrimalityTest(x))
                  .FirstOrDefault();
dtb
  • 213,145
  • 36
  • 401
  • 431
  • @AakashM - Likely enough. Guessing is a good strategy for getting a prime number, not to mention a prime random number. – Kobi Jun 03 '10 at 12:08
  • Why are you dividing by 8? Does that ensure it to be a multiple of 64 ? – Filip Ekberg Jun 03 '10 at 12:12
  • 2
    i downvoted because `Random` class is not good for cryptographic purposes. and your quote from wiki gives only slight sense of how to make prime. – Andrey Jun 03 '10 at 12:15
  • http://msdn.microsoft.com/en-us/library/system.security.cryptography.randomnumbergenerator(v=VS.100).aspx – Mitch Wheat Jun 03 '10 at 12:18
  • @Filip Ekberg: I'm dividing the number of bits by 8 to get the size of the byte array, because there are 8 bits in a byte. – dtb Jun 03 '10 at 12:18
  • @dtb this is much better. But i think that security is the place where you should not reinvent bicycles and use well proven implementations, because your system might be vulnerable, or algorithm inefficient. i am sure that there are very well done algorithms for key generation for DSA – Andrey Jun 03 '10 at 12:21
  • @Mitch Wheat public **abstract** class RandomNumberGenerator – Andrey Jun 03 '10 at 12:21
  • 1
    @Henk Holterman: Is `RandomNumberGenerator.Create()` preferable to `new RNGCryptoServiceProvider`? – dtb Jun 03 '10 at 12:25
  • 1
    Don't you need to add a `00` byte as MSB so the sign is always positive? – CodesInChaos Jun 15 '16 at 15:42
  • @Andrey - [Can computers generate a truly random number](http://engineering.mit.edu/ask/can-computer-generate-truly-random-number). Whether he uses the crypto library or not, is kind of irrelevant as neither is capable or true random numbers. Crypto just offers a slightly more advanced algo for generating. The quote on there from random.org following it [random.org](https://www.random.org/) states that it uses "atmospheric noise" as it's method, which is, an algorithm. While the seed is larger, it is still not truly random, but it is more complex. – Kraang Prime Aug 17 '16 at 10:24
  • @SamuelJackson using "atmospheric noise" is not an algorithm. It is not a computer that generates random number, computer here merely observe an a outside randomness. Computer here is not a RNG, atmosphere is. – Andrey Aug 22 '16 at 07:47
  • "A randomly-chosen range of odd numbers of the desired size is sieved against a number of relatively small odd primes (typically all primes less than 65,000)" doesn't translate to `.Where(x => !primesLessThan65000.Contains(x))`. To "sieve" using all primes less than 65,000 means to eliminate any number that is a *multiple* of one of those smaller primes. – Trevor Dixon Feb 16 '17 at 10:51