49 throw std::runtime_error(
"Modulus must be at least 1023 bits");
53 if (securityLevel < 80) {
54 throw std::runtime_error(
"Security level must be at least 80 bits.");
83 qLen + 300, qLen + 1);
134 hasher << std::string(
"||");
136 hasher << std::string(
"||");
138 hasher << std::string(
"||");
140 hasher << std::string(
"||");
142 hasher << std::string(
"||");
165 hasher << std::string(
"||");
166 hasher << securityLevel;
167 hasher << std::string(
"||");
169 hasher << std::string(
"||");
206 uint32_t *pLen, uint32_t *qLen)
210 if (securityLevel < 80) {
211 throw std::runtime_error(
"Security level must be at least 80 bits.");
212 }
else if (securityLevel == 80) {
215 }
else if (securityLevel <= 112) {
218 }
else if (securityLevel <= 128) {
222 throw std::runtime_error(
"Security level not supported.");
225 if (*pLen > maxPLen) {
226 throw std::runtime_error(
"Modulus size is too small for this security level.");
271 result.
g == result.
h ||
274 throw std::runtime_error(
"Group parameters are not valid");
323 result.
g == result.
h ||
326 throw std::runtime_error(
"Group parameters are not valid");
334 throw std::runtime_error(
"Too many attempts to generate Schnorr group.");
355 if (qLen > (
sizeof(seed)) * 8) {
360 #ifdef ZEROCOIN_DEBUG
361 cout <<
"calculateGroupModulusAndOrder: pLen = " << pLen << endl;
368 uint32_t qgen_counter;
373 uint32_t p0len = ceil((pLen / 2.0) + 1);
375 uint32_t pgen_counter;
379 uint32_t old_counter = pgen_counter;
384 pseed += iterations + 1;
388 x = powerOfTwo + (x % powerOfTwo);
396 for ( ; pgen_counter <= ((4*pLen) + old_counter) ; pgen_counter++) {
401 if (prod > powerOfTwo) {
407 *resultModulus = (
BN_TWO * t * (*resultGroupOrder) * p0) +
BN_ONE;
411 pseed += iterations + 1;
421 if ((resultModulus->
gcd(z -
BN_ONE)).isOne() &&
422 (z.
pow_mod(p0, (*resultModulus))).isOne()) {
435 throw std::runtime_error(
"Unable to generate a prime modulus for the group");
457 throw std::runtime_error(
"Invalid index for group generation");
470 result = W.
pow_mod(e, modulus);
479 throw std::runtime_error(
"Unable to find a generator, too many attempts");
495 uint32_t *prime_gen_counter)
498 if (primeBitLen < 2) {
499 throw std::runtime_error(
"Prime length is too short");
503 if (primeBitLen < 33) {
508 (*prime_gen_counter) = 0;
511 while ((*prime_gen_counter) < (4 * primeBitLen)) {
514 uint32_t iteration_count;
516 #ifdef ZEROCOIN_DEBUG
517 cout <<
"generateRandomPrime: primeBitLen = " << primeBitLen << endl;
518 cout <<
"Generated c = " << c << endl;
521 prime_seed += (iteration_count + 1);
522 (*prime_gen_counter)++;
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;
538 *out_seed = prime_seed;
547 throw std::runtime_error(
"Unable to find prime in Shawe-Taylor algorithm");
554 uint32_t newLength = ceil((
double)primeBitLen / 2.0) + 1;
559 uint32_t numIterations;
561 (*out_seed) += numIterations + 1;
580 (*prime_gen_counter)++;
586 (*out_seed) += (numIterations + 1);
607 throw std::runtime_error(
"Unable to generate random prime (too many tests)");
615 #ifdef ZEROCOIN_DEBUG
616 cout <<
"numBits = " << numBits << endl;
617 cout <<
"iterations = " << iterations << endl;
621 for (uint32_t count = 0; count < iterations; count++) {
629 *numIterations = iterations;
Parameter generation routines for Zerocoin.
#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
arith_uint256 UintToArith256(const uint256 &a)
uint256 ArithToUint256(const arith_uint256 &a)
unsigned long getulong() const
CBigNum gcd(const CBigNum &b) const
Calculates the greatest common divisor (GCD) of two numbers.
bool isPrime(const int checks=15) const
Miller-Rabin primality test on this element.
CBigNum pow_mod(const CBigNum &e, const CBigNum &m) const
modular exponentiation: this^e mod n
CBigNum pow(const int e) const
exponentiation with an int.
int bitSize() const
Returns the size in bits of the underlying bignum.
A writer stream (for serialization) that computes a 256-bit hash.
256-bit unsigned big integer.
CBigNum maxCoinValue
Upper bound on the value for a committed coin.
IntegerGroupParams accumulatorPoKCommitmentGroup
The second of two groups used to form a commitment to a coin (which it self is a commitment to a seri...
IntegerGroupParams accumulatorQRNCommitmentGroup
Hidden order quadratic residue group mod N.
CBigNum accumulatorModulus
Modulus used for the accumulator.
CBigNum accumulatorBase
The initial value for the accumulator A random Quadratic residue mod n that's not 1.
CBigNum minCoinValue
Lower bound on the value for committed coin.
CBigNum groupOrder
The order of the group.
CBigNum h
A second generator for the group.
CBigNum modulus
The modulus for the group.
CBigNum g
A generator for the group.
IntegerGroupParams coinCommitmentGroup
The Quadratic Residue group from which we form a coin as a commitment to a serial number.
AccumulatorAndProofParams accumulatorParams
IntegerGroupParams serialNumberSoKCommitmentGroup
One of two groups used to form a commitment to a coin (which it self is a commitment to a serial numb...
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 ¶ms, 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.