PIVX Core  5.6.99
P2P Digital Currency
ParamGeneration.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2021 The PIVX Core developers
12 
13 #include "ParamGeneration.h"
14 #include <string>
15 #include <cmath>
16 #include "arith_uint256.h"
17 #include "hash.h"
18 #include "uint256.h"
19 
20 
21 namespace libzerocoin {
22 
40 
41 void CalculateParams(ZerocoinParams &params, const CBigNum& N, const std::string& aux, uint32_t securityLevel)
42 {
43  params.initialized = false;
44  params.accumulatorParams.initialized = false;
45 
46  // Verify that |N| is > 1023 bits.
47  uint32_t NLen = N.bitSize();
48  if (NLen < 1023) {
49  throw std::runtime_error("Modulus must be at least 1023 bits");
50  }
51 
52  // Verify that "securityLevel" is at least 80 bits (minimum).
53  if (securityLevel < 80) {
54  throw std::runtime_error("Security level must be at least 80 bits.");
55  }
56 
57  // Set the accumulator modulus to "N".
59 
60  // Calculate the required size of the field "F_p" into which
61  // we're embedding the coin commitment group. This may throw an
62  // exception if the securityLevel is too large to be supported
63  // by the current modulus.
64  uint32_t pLen = 0;
65  uint32_t qLen = 0;
66  calculateGroupParamLengths(NLen - 2, securityLevel, &pLen, &qLen);
67 
68  // Calculate candidate parameters ("p", "q") for the coin commitment group
69  // using a deterministic process based on "N", the "aux" string, and
70  // the dedicated string "COMMITMENTGROUP".
72  pLen, qLen);
73 
74  // Next, we derive parameters for a second Accumulated Value commitment group.
75  // This is a Schnorr group with the specific property that the order of the group
76  // must be exactly equal to "q" from the commitment group. We set
77  // the modulus of the new group equal to "2q+1" and test to see if this is prime.
79 
80  // Calculate the parameters for the internal commitment
81  // using the same process.
83  qLen + 300, qLen + 1);
84 
85  // Calculate the parameters for the accumulator QRN commitment generators. This isn't really
86  // a whole group, just a pair of random generators in QR_N.
87  uint32_t resultCtr;
89  UintToArith256(calculateSeed(N, aux, securityLevel, STRING_QRNCOMMIT_GROUPG)),
90  &resultCtr).pow_mod(BN_TWO, N);
92  UintToArith256(calculateSeed(N, aux, securityLevel, STRING_QRNCOMMIT_GROUPH)),
93  &resultCtr).pow_mod(BN_TWO, N);
94 
95  // Calculate the accumulator base, which we calculate as "u = C**2 mod N"
96  // where C is an arbitrary value. In the unlikely case that "u = 1" we increment
97  // "C" and repeat.
100  for (uint32_t count = 0; count < MAX_ACCUMGEN_ATTEMPTS && params.accumulatorParams.accumulatorBase.isOne(); count++) {
102  }
103 
104  // Compute the accumulator range. The upper range is the largest possible coin commitment value.
105  // The lower range is sqrt(upper range) + 1. Since OpenSSL doesn't have
106  // a square root function we use a slightly higher approximation.
109 
110  // If all went well, mark params as successfully initialized.
111  params.accumulatorParams.initialized = true;
112 
113  // If all went well, mark params as successfully initialized.
114  params.initialized = true;
115 }
116 
125 
126 uint256 calculateGeneratorSeed(const uint256& seed, const uint256& pSeed, const uint256& qSeed, const std::string& label, uint32_t index, uint32_t count)
127 {
128  CHashWriter hasher(0,0);
129  uint256 hash;
130 
131  // Compute the hash of:
132  // <modulus>||<securitylevel>||<auxString>||groupName
133  hasher << seed;
134  hasher << std::string("||");
135  hasher << pSeed;
136  hasher << std::string("||");
137  hasher << qSeed;
138  hasher << std::string("||");
139  hasher << label;
140  hasher << std::string("||");
141  hasher << index;
142  hasher << std::string("||");
143  hasher << count;
144 
145  return hasher.GetHash();
146 }
147 
156 
157 uint256 calculateSeed(const CBigNum& modulus, const std::string& auxString, uint32_t securityLevel, const std::string& groupName)
158 {
159  CHashWriter hasher(0,0);
160  uint256 hash;
161 
162  // Compute the hash of:
163  // <modulus>||<securitylevel>||<auxString>||groupName
164  hasher << modulus;
165  hasher << std::string("||");
166  hasher << securityLevel;
167  hasher << std::string("||");
168  hasher << auxString;
169  hasher << std::string("||");
170  hasher << groupName;
171 
172  return hasher.GetHash();
173 }
174 
176 {
177  CHashWriter hasher(0,0);
178 
179  // Compute the hash of "input"
180  hasher << input;
181 
182  return hasher.GetHash();
183 }
184 
203 
204 void
205 calculateGroupParamLengths(uint32_t maxPLen, uint32_t securityLevel,
206  uint32_t *pLen, uint32_t *qLen)
207 {
208  *pLen = *qLen = 0;
209 
210  if (securityLevel < 80) {
211  throw std::runtime_error("Security level must be at least 80 bits.");
212  } else if (securityLevel == 80) {
213  *qLen = 256;
214  *pLen = 1024;
215  } else if (securityLevel <= 112) {
216  *qLen = 256;
217  *pLen = 2048;
218  } else if (securityLevel <= 128) {
219  *qLen = 320;
220  *pLen = 3072;
221  } else {
222  throw std::runtime_error("Security level not supported.");
223  }
224 
225  if (*pLen > maxPLen) {
226  throw std::runtime_error("Modulus size is too small for this security level.");
227  }
228 }
229 
241 
242 IntegerGroupParams deriveIntegerGroupParams(const uint256& seed, uint32_t pLen, uint32_t qLen)
243 {
244  IntegerGroupParams result;
245  CBigNum p;
246  CBigNum q;
247  uint256 pSeed, qSeed;
248 
249  // Calculate "p" and "q" and "domain_parameter_seed" from the
250  // "seed" buffer above, using the procedure described in NIST
251  // FIPS 186-3, Appendix A.1.2.
252  calculateGroupModulusAndOrder(seed, pLen, qLen, &(result.modulus),
253  &(result.groupOrder), &pSeed, &qSeed);
254 
255  // Calculate the generators "g", "h" using the process described in
256  // NIST FIPS 186-3, Appendix A.2.3. This algorithm takes ("p", "q",
257  // "domain_parameter_seed", "index"). We use "index" value 1
258  // to generate "g" and "index" value 2 to generate "h".
259  result.g = calculateGroupGenerator(seed, pSeed, qSeed, result.modulus, result.groupOrder, 1);
260  result.h = calculateGroupGenerator(seed, pSeed, qSeed, result.modulus, result.groupOrder, 2);
261 
262  // Perform some basic tests to make sure we have good parameters
263  if ((uint32_t)(result.modulus.bitSize()) < pLen || // modulus is pLen bits long
264  (uint32_t)(result.groupOrder.bitSize()) < qLen || // order is qLen bits long
265  !(result.modulus.isPrime()) || // modulus is prime
266  !(result.groupOrder.isPrime()) || // order is prime
267  !((result.g.pow_mod(result.groupOrder, result.modulus)).isOne()) || // g^order mod modulus = 1
268  !((result.h.pow_mod(result.groupOrder, result.modulus)).isOne()) || // h^order mod modulus = 1
269  ((result.g.pow_mod(CBigNum(100), result.modulus)).isOne()) || // g^100 mod modulus != 1
270  ((result.h.pow_mod(CBigNum(100), result.modulus)).isOne()) || // h^100 mod modulus != 1
271  result.g == result.h || // g != h
272  result.g.isOne()) { // g != 1
273  // If any of the above tests fail, throw an exception
274  throw std::runtime_error("Group parameters are not valid");
275  }
276 
277  return result;
278 }
279 
286 
288 {
289  IntegerGroupParams result;
290 
291  // Set the order to "groupOrder"
292  result.groupOrder = groupOrder;
293 
294  // Try possible values for "modulus" of the form "groupOrder * 2 * i" where
295  // "p" is prime and i is a counter starting at 1.
296  for (uint32_t i = 1; i < NUM_SCHNORRGEN_ATTEMPTS; i++) {
297  // Set modulus equal to "groupOrder * 2 * i"
298  result.modulus = (result.groupOrder * CBigNum(i*2)) + BN_ONE;
299 
300  // Test the result for primality
301  // TODO: This is a probabilistic routine and thus not the right choice
302  if (result.modulus.isPrime(256)) {
303 
304  // Success.
305  //
306  // Calculate the generators "g", "h" using the process described in
307  // NIST FIPS 186-3, Appendix A.2.3. This algorithm takes ("p", "q",
308  // "domain_parameter_seed", "index"). We use "index" value 1
309  // to generate "g" and "index" value 2 to generate "h".
310  uint256 seed = calculateSeed(groupOrder, "", 128, "");
311  uint256 pSeed = calculateHash(seed);
312  uint256 qSeed = calculateHash(pSeed);
313  result.g = calculateGroupGenerator(seed, pSeed, qSeed, result.modulus, result.groupOrder, 1);
314  result.h = calculateGroupGenerator(seed, pSeed, qSeed, result.modulus, result.groupOrder, 2);
315 
316  // Perform some basic tests to make sure we have good parameters
317  if (!(result.modulus.isPrime()) || // modulus is prime
318  !(result.groupOrder.isPrime()) || // order is prime
319  !((result.g.pow_mod(result.groupOrder, result.modulus)).isOne()) || // g^order mod modulus = 1
320  !((result.h.pow_mod(result.groupOrder, result.modulus)).isOne()) || // h^order mod modulus = 1
321  ((result.g.pow_mod(CBigNum(100), result.modulus)).isOne()) || // g^100 mod modulus != 1
322  ((result.h.pow_mod(CBigNum(100), result.modulus)).isOne()) || // h^100 mod modulus != 1
323  result.g == result.h || // g != h
324  result.g.isOne()) { // g != 1
325  // If any of the above tests fail, throw an exception
326  throw std::runtime_error("Group parameters are not valid");
327  }
328 
329  return result;
330  }
331  }
332 
333  // If we reached this point group generation has failed. Throw an exception.
334  throw std::runtime_error("Too many attempts to generate Schnorr group.");
335 }
336 
349 
350 void calculateGroupModulusAndOrder(const uint256& seed, uint32_t pLen, uint32_t qLen,
351  CBigNum *resultModulus, CBigNum *resultGroupOrder,
352  uint256 *resultPseed, uint256 *resultQseed)
353 {
354  // Verify that the seed length is >= qLen
355  if (qLen > (sizeof(seed)) * 8) {
356  // TODO: The use of 256-bit seeds limits us to 256-bit group orders. We should probably change this.
357  // throw std::runtime_error("Seed is too short to support the required security level.");
358  }
359 
360 #ifdef ZEROCOIN_DEBUG
361  cout << "calculateGroupModulusAndOrder: pLen = " << pLen << endl;
362 #endif
363 
364  // Generate a random prime for the group order.
365  // This may throw an exception, which we'll pass upwards.
366  // Result is the value "resultGroupOrder", "qseed" and "qgen_counter".
367  arith_uint256 qseed;
368  uint32_t qgen_counter;
369  *resultGroupOrder = generateRandomPrime(qLen, UintToArith256(seed), &qseed, &qgen_counter);
370 
371  // Using pLen / 2 + 1 as the length and qseed as the input_seed, use the random prime
372  // routine to obtain p0 , pseed, and pgen_counter. We pass exceptions upward.
373  uint32_t p0len = ceil((pLen / 2.0) + 1);
374  arith_uint256 pseed;
375  uint32_t pgen_counter;
376  CBigNum p0 = generateRandomPrime(p0len, qseed, &pseed, &pgen_counter);
377 
378  // Set x = 0, old_counter = pgen_counter
379  uint32_t old_counter = pgen_counter;
380 
381  // Generate a random integer "x" of pLen bits
382  uint32_t iterations;
383  CBigNum x = generateIntegerFromSeed(pLen, pseed, &iterations);
384  pseed += iterations + 1;
385 
386  // Set x = 2^{pLen-1} + (x mod 2^{pLen-1}).
387  CBigNum powerOfTwo = BN_TWO.pow(pLen-1);
388  x = powerOfTwo + (x % powerOfTwo);
389 
390  // t = x / (2 * resultGroupOrder * p0).
391  // TODO: we don't have a ceiling function
392  CBigNum t = x / (BN_TWO * (*resultGroupOrder) * p0);
393 
394  // Now loop until we find a valid prime "p" or we fail due to
395  // pgen_counter exceeding ((4*pLen) + old_counter).
396  for ( ; pgen_counter <= ((4*pLen) + old_counter) ; pgen_counter++) {
397  // If (2 * t * resultGroupOrder * p0 + 1) > 2^{pLen}, then
398  // t = 2^{pLen-1} / (2 * resultGroupOrder * p0)
399  powerOfTwo = BN_TWO.pow(pLen);
400  CBigNum prod = (BN_TWO * t * (*resultGroupOrder) * p0) + BN_ONE;
401  if (prod > powerOfTwo) {
402  // TODO: implement a ceil function
403  t = BN_TWO.pow(pLen-1) / (BN_TWO * (*resultGroupOrder) * p0);
404  }
405 
406  // Compute a candidate prime resultModulus = 2tqp0 + 1.
407  *resultModulus = (BN_TWO * t * (*resultGroupOrder) * p0) + BN_ONE;
408 
409  // Verify that resultModulus is prime. First generate a pseudorandom integer "a".
410  CBigNum a = generateIntegerFromSeed(pLen, pseed, &iterations);
411  pseed += iterations + 1;
412 
413  // Set a = 2 + (a mod (resultModulus - 3)).
414  a = BN_TWO + (a % ((*resultModulus) - BN_THREE));
415 
416  // Set z = a^{2 * t * resultGroupOrder} mod resultModulus
417  CBigNum z = a.pow_mod(BN_TWO * t * (*resultGroupOrder), (*resultModulus));
418 
419  // If GCD(z-1, resultModulus) == 1 AND (z^{p0} mod resultModulus == 1)
420  // then we have found our result. Return.
421  if ((resultModulus->gcd(z - BN_ONE)).isOne() &&
422  (z.pow_mod(p0, (*resultModulus))).isOne()) {
423  // Success! Return the seeds and primes.
424  *resultPseed = ArithToUint256(pseed);
425  *resultQseed = ArithToUint256(qseed);
426  return;
427  }
428 
429  // This prime did not work out. Increment "t" and try again.
430  t = t + BN_ONE;
431  } // loop continues until pgen_counter exceeds a limit
432 
433  // We reach this point only if we exceeded our maximum iteration count.
434  // Throw an exception.
435  throw std::runtime_error("Unable to generate a prime modulus for the group");
436 }
437 
450 
451 CBigNum calculateGroupGenerator(const uint256& seed, const uint256& pSeed, const uint256& qSeed, const CBigNum& modulus, const CBigNum& groupOrder, uint32_t index)
452 {
453  CBigNum result;
454 
455  // Verify that 0 <= index < 256
456  if (index > 255) {
457  throw std::runtime_error("Invalid index for group generation");
458  }
459 
460  // Compute e = (modulus - 1) / groupOrder
461  CBigNum e = (modulus - BN_ONE) / groupOrder;
462 
463  // Loop until we find a generator
464  for (uint32_t count = 1; count < MAX_GENERATOR_ATTEMPTS; count++) {
465  // hash = Hash(seed || pSeed || qSeed || "ggen" || index || count
466  uint256 hash = calculateGeneratorSeed(seed, pSeed, qSeed, "ggen", index, count);
467  CBigNum W(hash);
468 
469  // Compute result = W^e mod p
470  result = W.pow_mod(e, modulus);
471 
472  // If result > 1, we have a generator
473  if (result > 1) {
474  return result;
475  }
476  }
477 
478  // We only get here if we failed to find a generator
479  throw std::runtime_error("Unable to find a generator, too many attempts");
480 }
481 
493 
494 CBigNum generateRandomPrime(uint32_t primeBitLen, const arith_uint256& in_seed, arith_uint256 *out_seed,
495  uint32_t *prime_gen_counter)
496 {
497  // Verify that primeBitLen is not too small
498  if (primeBitLen < 2) {
499  throw std::runtime_error("Prime length is too short");
500  }
501 
502  // If primeBitLen < 33 bits, perform the base case.
503  if (primeBitLen < 33) {
504  CBigNum result(0);
505 
506  // Set prime_seed = in_seed, prime_gen_counter = 0.
507  arith_uint256 prime_seed = in_seed;
508  (*prime_gen_counter) = 0;
509 
510  // Loop up to "4 * primeBitLen" iterations.
511  while ((*prime_gen_counter) < (4 * primeBitLen)) {
512 
513  // Generate a pseudorandom integer "c" of length primeBitLength bits
514  uint32_t iteration_count;
515  CBigNum c = generateIntegerFromSeed(primeBitLen, prime_seed, &iteration_count);
516 #ifdef ZEROCOIN_DEBUG
517  cout << "generateRandomPrime: primeBitLen = " << primeBitLen << endl;
518  cout << "Generated c = " << c << endl;
519 #endif
520 
521  prime_seed += (iteration_count + 1);
522  (*prime_gen_counter)++;
523 
524  // Set "intc" to be the least odd integer >= "c" we just generated
525  uint32_t intc = c.getulong();
526  intc = (2 * floor(intc / 2.0)) + 1;
527 #ifdef ZEROCOIN_DEBUG
528  cout << "Should be odd. c = " << intc << endl;
529  cout << "The big num is: c = " << c << endl;
530 #endif
531 
532  // Perform trial division on this (relatively small) integer to determine if "intc"
533  // is prime. If so, return success.
534  if (primalityTestByTrialDivision(intc)) {
535  // Return "intc" converted back into a CBigNum and "prime_seed". We also updated
536  // the variable "prime_gen_counter" in previous statements.
537  result = intc;
538  *out_seed = prime_seed;
539 
540  // Success
541  return result;
542  }
543  } // while()
544 
545  // If we reached this point there was an error finding a candidate prime
546  // so throw an exception.
547  throw std::runtime_error("Unable to find prime in Shawe-Taylor algorithm");
548 
549  // END OF BASE CASE
550  }
551  // If primeBitLen >= 33 bits, perform the recursive case.
552  else {
553  // Recurse to find a new random prime of roughly half the size
554  uint32_t newLength = ceil((double)primeBitLen / 2.0) + 1;
555  CBigNum c0 = generateRandomPrime(newLength, in_seed, out_seed, prime_gen_counter);
556 
557  // Generate a random integer "x" of primeBitLen bits using the output
558  // of the previous call.
559  uint32_t numIterations;
560  CBigNum x = generateIntegerFromSeed(primeBitLen, *out_seed, &numIterations);
561  (*out_seed) += numIterations + 1;
562 
563  // Compute "t" = x / (2 * c0)
564  // TODO no Ceiling call
565  CBigNum t = x / (BN_TWO * c0);
566 
567  // Repeat the following procedure until we find a prime (or time out)
568  for (uint32_t testNum = 0; testNum < MAX_PRIMEGEN_ATTEMPTS; testNum++) {
569 
570  // If ((2 * t * c0) + 1 > 2^{primeBitLen}),
571  // then t = (2^{primeBitLen} - 1) / (2 * c0)
572  if ((BN_TWO * t * c0) > (BN_TWO.pow(CBigNum(primeBitLen)))) {
573  t = ((BN_TWO.pow(CBigNum(primeBitLen))) - BN_ONE) / (BN_TWO * c0);
574  }
575 
576  // Set c = (2 * t * c0) + 1
577  CBigNum c = (BN_TWO * t * c0) + BN_ONE;
578 
579  // Increment prime_gen_counter
580  (*prime_gen_counter)++;
581 
582  // Test "c" for primality as follows:
583  // 1. First pick an integer "a" in between 2 and (c - 2)
584  CBigNum a = generateIntegerFromSeed(c.bitSize(), *out_seed, &numIterations);
585  a = BN_TWO + (a % (c - BN_THREE));
586  (*out_seed) += (numIterations + 1);
587 
588  // 2. Compute "z" = a^{2*t} mod c
589  CBigNum z = a.pow_mod(BN_TWO * t, c);
590 
591  // 3. Check if "c" is prime.
592  // Specifically, verify that gcd((z-1), c) == 1 AND (z^c0 mod c) == 1
593  // If so we return "c" as our result.
594  if (c.gcd(z - BN_ONE).isOne() && z.pow_mod(c0, c).isOne()) {
595  // Return "c", out_seed and prime_gen_counter
596  // (the latter two of which were already updated)
597  return c;
598  }
599 
600  // 4. If the test did not succeed, increment "t" and loop
601  t = t + BN_ONE;
602  } // end of test loop
603  }
604 
605  // We only reach this point if the test loop has iterated MAX_PRIMEGEN_ATTEMPTS
606  // and failed to identify a valid prime. Throw an exception.
607  throw std::runtime_error("Unable to generate random prime (too many tests)");
608 }
609 
610 CBigNum generateIntegerFromSeed(uint32_t numBits, const arith_uint256& seed, uint32_t *numIterations)
611 {
612  CBigNum result(0);
613  uint32_t iterations = ceil((double)numBits / (double)HASH_OUTPUT_BITS);
614 
615 #ifdef ZEROCOIN_DEBUG
616  cout << "numBits = " << numBits << endl;
617  cout << "iterations = " << iterations << endl;
618 #endif
619 
620  // Loop "iterations" times filling up the value "result" with random bits
621  for (uint32_t count = 0; count < iterations; count++) {
622  // result += ( H(pseed + count) * 2^{count * p0len} )
623  result += CBigNum(calculateHash(ArithToUint256(seed + count))) * BN_TWO.pow(count * HASH_OUTPUT_BITS);
624  }
625 
626  result = BN_TWO.pow(numBits - 1) + (result % (BN_TWO.pow(numBits - 1)));
627 
628  // Return the number of iterations and the result
629  *numIterations = iterations;
630  return result;
631 }
632 
638 
639 bool primalityTestByTrialDivision(uint32_t candidate)
640 {
641  // TODO: HACK HACK WRONG WRONG
642  CBigNum canBignum(candidate);
643 
644  return canBignum.isPrime();
645 }
646 
647 } // namespace libzerocoin
Parameter generation routines for Zerocoin.
#define STRING_AIC_GROUP
#define STRING_QRNCOMMIT_GROUPG
#define MAX_GENERATOR_ATTEMPTS
#define MAX_ACCUMGEN_ATTEMPTS
#define MAX_PRIMEGEN_ATTEMPTS
#define ACCUMULATOR_BASE_CONSTANT
#define NUM_SCHNORRGEN_ATTEMPTS
#define STRING_QRNCOMMIT_GROUPH
#define STRING_COMMIT_GROUP
#define HASH_OUTPUT_BITS
arith_uint256 UintToArith256(const uint256 &a)
uint256 ArithToUint256(const arith_uint256 &a)
const CBigNum BN_THREE
Definition: bignum.h:235
const CBigNum BN_TWO
Definition: bignum.h:234
const CBigNum BN_ONE
Definition: bignum.h:233
C++ wrapper for BIGNUM.
Definition: bignum.h:35
unsigned long getulong() const
Definition: bignum.cpp:88
bool isOne() const
Definition: bignum.cpp:267
CBigNum gcd(const CBigNum &b) const
Calculates the greatest common divisor (GCD) of two numbers.
Definition: bignum.cpp:248
bool isPrime(const int checks=15) const
Miller-Rabin primality test on this element.
Definition: bignum.cpp:261
CBigNum pow_mod(const CBigNum &e, const CBigNum &m) const
modular exponentiation: this^e mod n
Definition: bignum.cpp:220
CBigNum pow(const int e) const
exponentiation with an int.
Definition: bignum.cpp:331
int bitSize() const
Returns the size in bits of the underlying bignum.
Definition: bignum.cpp:78
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:216
uint256 GetHash()
Definition: hash.h:236
256-bit unsigned big integer.
CBigNum maxCoinValue
Upper bound on the value for a committed coin.
Definition: Params.h:108
IntegerGroupParams accumulatorPoKCommitmentGroup
The second of two groups used to form a commitment to a coin (which it self is a commitment to a seri...
Definition: Params.h:116
IntegerGroupParams accumulatorQRNCommitmentGroup
Hidden order quadratic residue group mod N.
Definition: Params.h:122
CBigNum accumulatorModulus
Modulus used for the accumulator.
Definition: Params.h:90
CBigNum accumulatorBase
The initial value for the accumulator A random Quadratic residue mod n that's not 1.
Definition: Params.h:96
CBigNum minCoinValue
Lower bound on the value for committed coin.
Definition: Params.h:102
CBigNum groupOrder
The order of the group.
Definition: Params.h:57
CBigNum h
A second generator for the group.
Definition: Params.h:47
CBigNum modulus
The modulus for the group.
Definition: Params.h:52
CBigNum g
A generator for the group.
Definition: Params.h:40
IntegerGroupParams coinCommitmentGroup
The Quadratic Residue group from which we form a coin as a commitment to a serial number.
Definition: Params.h:169
AccumulatorAndProofParams accumulatorParams
Definition: Params.h:163
IntegerGroupParams serialNumberSoKCommitmentGroup
One of two groups used to form a commitment to a coin (which it self is a commitment to a serial numb...
Definition: Params.h:177
256-bit opaque blob.
Definition: uint256.h:138
uint256 calculateHash(const uint256 &input)
uint256 calculateGeneratorSeed(const uint256 &seed, const uint256 &pSeed, const uint256 &qSeed, const std::string &label, uint32_t index, uint32_t count)
Format a seed string by hashing several values.
uint256 calculateSeed(const CBigNum &modulus, const std::string &auxString, uint32_t securityLevel, const std::string &groupName)
Format a seed string by hashing several values.
IntegerGroupParams deriveIntegerGroupFromOrder(const CBigNum &groupOrder)
Deterministically compute a set of group parameters with a specified order.
void calculateGroupModulusAndOrder(const uint256 &seed, uint32_t pLen, uint32_t qLen, CBigNum *resultModulus, CBigNum *resultGroupOrder, uint256 *resultPseed, uint256 *resultQseed)
Deterministically compute a group description using NIST procedures.
IntegerGroupParams deriveIntegerGroupParams(const uint256 &seed, uint32_t pLen, uint32_t qLen)
Deterministically compute a set of group parameters using NIST procedures.
CBigNum generateRandomPrime(uint32_t primeBitLen, const arith_uint256 &in_seed, arith_uint256 *out_seed, uint32_t *prime_gen_counter)
Deterministically compute a random prime number.
CBigNum generateIntegerFromSeed(uint32_t numBits, const arith_uint256 &seed, uint32_t *numIterations)
CBigNum calculateGroupGenerator(const uint256 &seed, const uint256 &pSeed, const uint256 &qSeed, const CBigNum &modulus, const CBigNum &groupOrder, uint32_t index)
Deterministically compute a generator for a given group.
void CalculateParams(ZerocoinParams &params, const CBigNum &N, const std::string &aux, uint32_t securityLevel)
Fill in a set of Zerocoin parameters from a modulus "N".
bool primalityTestByTrialDivision(uint32_t candidate)
Determines whether a uint32_t is a prime through trial division.
void calculateGroupParamLengths(uint32_t maxPLen, uint32_t securityLevel, uint32_t *pLen, uint32_t *qLen)
Calculate field/group parameter sizes based on a security level.