SeComLib
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Macros Pages
random_provider_gmp.cpp
Go to the documentation of this file.
1 /*
2 SeComLib
3 Copyright 2012-2013 TU Delft, Information Security & Privacy Lab (http://isplab.tudelft.nl/)
4 
5 Contributors:
6 Inald Lagendijk (R.L.Lagendijk@TUDelft.nl)
7 Mihai Todor (todormihai@gmail.com)
8 Thijs Veugen (P.J.M.Veugen@tudelft.nl)
9 Zekeriya Erkin (z.erkin@tudelft.nl)
10 
11 Licensed under the Apache License, Version 2.0 (the "License");
12 you may not use this file except in compliance with the License.
13 You may obtain a copy of the License at
14 
15 http://www.apache.org/licenses/LICENSE-2.0
16 
17 Unless required by applicable law or agreed to in writing, software
18 distributed under the License is distributed on an "AS IS" BASIS,
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 See the License for the specific language governing permissions and
21 limitations under the License.
22 */
29 #include "random_provider_gmp.h"
30 
31 namespace SeComLib {
32 namespace Core {
46  input.randomSeed = 0;
47 
48  #if _WIN32
49  if (0 != rand_s(&input.randomSeed)) {
50  throw std::runtime_error("Error calling rand_s.");
51  }
52 
53  #else
54  std::ifstream randomGeneratorFile("/dev/urandom", std::ios::binary);
55 
56  if (randomGeneratorFile.is_open()) {
57  randomGeneratorFile.read((char *)&input.randomSeed, sizeof(input.randomSeed));
58  randomGeneratorFile.close();
59  //std::cout << this->randomSeed;
60  }
61  else {
62  throw std::runtime_error("Error opening /dev/urandom.");
63  }
64  #endif
65 
66  gmp_randinit_default(input.randomGeneratorState);
67 
68  //initialize the random generator state
69  //should seed be generated as unsigned long instead of unsigned int?
70  //should use gmp_randseed instead? (with mpz_t seed)
71  gmp_randseed_ui(input.randomGeneratorState, static_cast<unsigned long>(input.randomSeed));
72  }
73 
78  gmp_randclear(randomProvider.randomGeneratorState);
79  }
80 
87  mpz_urandomb(output.data, randomProvider.randomGeneratorState, (unsigned long)numberOfBits);
88  }
89 
96  mpz_urandomm(output.data, randomProvider.randomGeneratorState, maximumValue.data);
97  }
98 
109  do {
110  //generate a random number in the interval [0, 2^(numberOfBits - 1))
111  output = randomProvider.GetRandomInteger(numberOfBits - 1);
112 
113  //shift number to the interval [2^(numberOfBits - 1), 2^numberOfBits)
114  output.SetBit(numberOfBits - 1);
115  }
116  while (!output.IsPrime());
117 
118  #if 0//start disabled code block
119  //My first version of the prime generator algorithm (faster but not the best approach)
120  /*
121  Algorithm logic:
122  Generates a random integer in the interval @f$ [0, 2^{numberOfBits - 1}) @f$.
123  Shifts the integer to the interval @f$ [2^{numberOfBits - 1}, 2^{numberOfBits}) @f$ by setting the MSB.
124  Computes the first prime greater than the random integer.
125  Repeats the process if the prime happns to end up in the interval @f$ [2^{numberOfBits}, 2^{numberOfBits + 1}) @f$
126 
127  The issue: primes are not evenly distributed, so there might be a bias towards certain primes
128 
129  mpz_nextprime first tests a number against a large quantity of small primes to see if they are a factor. If not, mpz_nextprime uses a probabilistic Miller-Rabin test.
130  The number of Miller-Rabin tests varies between GMP (25) and MPIR (2), but they also use different ways to perform the small primes test
131  (MPIR first checks if the primes smaller than 1000 are factors and then uses Miller-Rabin)
132  */
133  bool retry = false;
134 
135  do {
136  //generate a random number in the interval [0, 2^(numberOfBits - 1))
137  output = randomProvider.GetRandomInteger(numberOfBits - 1);
138 
139  /*
140  std::cout << output.GetSizeInBase() << std::endl;
141  std::cout << output.ToString(16) << std::endl;
142  */
143 
144  //shift number to the interval [2^(numberOfBits - 1), 2^numberOfBits)
145  //GMP counts the number of bits starting from bit 0...
146  output.SetBit(numberOfBits - 1);
147 
148  /*
149  std::cout << output.GetSizeInBase() << std::endl;
150  std::cout << output.ToString(16) << std::endl;
151  */
152 
153  //generate prime number
154  output = output.GetNextPrime();
155 
156  //it mustn't end up in the interval [2^numberOfBits, 2^(numberOfBits + 1))
157  if (output.GetSize() != length) {
158  retry = true;
159  }
160  }
161  while (true == retry);
162  #endif//end disabled code block
163  }
164 
165 }//namespace Core
166 }//namespace SeComLib
BigIntegerBase< T_Impl > & SetBit(const size_t index)
Sets a bit in the current instance at the specified index.
BigIntegerBase< T_Impl > GetNextPrime() const
Computes the first prime greater than the current instance.
static void Destroy(RandomProviderBase< RandomProviderGmp > &input)
Destroys the underlying data from input.
T_Impl::RandomGeneratorState randomGeneratorState
Implementation-defined random generator state.
Definition of class RandomProviderGmp.
static void Initialize(RandomProviderBase< RandomProviderGmp > &input)
Initializes the underlying random state from input.
bool IsPrime() const
Tests if the current instance is a prime number.
BigInteger GetRandomInteger(const size_t numberOfBits)
Generates a random integer having at most numberOfBits bits.
size_t GetSize(const unsigned int base=2) const
Gets the length of the integer in the specified base.
T_Impl::BigIntegerType data
Implementation-defined big integer variable.
Template class which masks various RandomProvider implementations and provides a common interface tha...
Template class which adds syntactic sugar to big integer operations.
static void GetRandomInteger(BigIntegerBase< BigIntegerGmp > &output, RandomProviderBase< RandomProviderGmp > &input, const size_t numberOfBits)
Generates a random integer having at most numberOfBits bits.
unsigned int randomSeed
Random seed required for the random generator state initialization.
static void GetMaxLengthRandomPrime(BigIntegerBase< BigIntegerGmp > &output, RandomProviderBase< RandomProviderGmp > &input, const size_t numberOfBits)
Generates a random prime, guaranteed to have numberOfBits length.