Skip to content

Commit

Permalink
Merge dashpay#875: [Zerocoin] GMP BigNum: Fix limits for random numbe…
Browse files Browse the repository at this point in the history
…r generators

253c63e [Zerocoin] include 0 in randBignum() range (random-zebra)
daeb752 [Test] Add tests for bignum random generators (random-zebra)
5627807 [Zerocoin] Fix limits for random number generators in GMP bignum implementation (random-zebra)

Tree-SHA512: c88ab99912683736a886065ecfbfd52aeb419357ee0e7eb6e3c1a09c22c3c316884bf8606f44d13e0f0fcb4de4137fb52339b556eb6e1a134b7aafff36c1d414
  • Loading branch information
Mrs-X committed May 17, 2019
2 parents fc6b5a1 + 253c63e commit a99c2dd
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 57 deletions.
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ BITCOIN_TESTS =\
test/zerocoin_denomination_tests.cpp\
test/zerocoin_transactions_tests.cpp \
test/zerocoin_coinspend_tests.cpp \
test/zerocoin_bignum_tests.cpp \
test/benchmark_zerocoin.cpp \
test/tutorial_zerocoin.cpp \
test/libzerocoin_tests.cpp \
Expand Down
6 changes: 3 additions & 3 deletions src/libzerocoin/bignum.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ class CBigNum
* @param range The upper bound on the number.
* @return
*/
static CBigNum randBignum(const CBigNum& range);
static CBigNum randBignum(const CBigNum& range);

/** Generates a cryptographically secure random k-bit number
* @param k The bit length of the number.
* @return
*/
static CBigNum RandKBitBigum(const uint32_t k);
static CBigNum randKBitBignum(const uint32_t k);

/**Returns the size in bits of the underlying bignum.
*
Expand Down Expand Up @@ -122,7 +122,7 @@ class CBigNum
* @param e the exponent as an int
* @return
*/
CBigNum pow(const int e) const ;
CBigNum pow(const int e) const;

/**
* exponentiation this^e
Expand Down
17 changes: 11 additions & 6 deletions src/libzerocoin/bignum_gmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,18 @@ CBigNum::CBigNum(const std::vector<unsigned char>& vch)
setvch(vch);
}

/** Generates a cryptographically secure random number between zero and range exclusive
* i.e. 0 < returned number < range
/** PRNGs use OpenSSL for consistency with seed initialization **/

/** Generates a cryptographically secure random number between zero and range-1 (inclusive)
* i.e. 0 <= returned number < range
* @param range The upper bound on the number.
* @return
*/
CBigNum CBigNum::randBignum(const CBigNum& range)
{
if (range < 2)
return 0;

size_t size = (mpz_sizeinbase (range.bn, 2) + CHAR_BIT-1) / CHAR_BIT;
std::vector<unsigned char> buf(size);

Expand All @@ -64,14 +69,14 @@ CBigNum CBigNum::randBignum(const CBigNum& range)
CBigNum ret(buf);
if (ret < 0)
mpz_neg(ret.bn, ret.bn);
return ret;
return (ret % range);
}

/** Generates a cryptographically secure random k-bit number
* @param k The bit length of the number.
* @return
*/
CBigNum CBigNum::RandKBitBigum(const uint32_t k)
CBigNum CBigNum::randKBitBignum(const uint32_t k)
{
std::vector<unsigned char> buf((k+7)/8);

Expand All @@ -81,7 +86,7 @@ CBigNum CBigNum::RandKBitBigum(const uint32_t k)
CBigNum ret(buf);
if (ret < 0)
mpz_neg(ret.bn, ret.bn);
return ret;
return ret % (CBigNum(1) << k);
}

/**Returns the size in bits of the underlying bignum.
Expand Down Expand Up @@ -256,7 +261,7 @@ CBigNum CBigNum::inverse(const CBigNum& m) const
*/
CBigNum CBigNum::generatePrime(const unsigned int numBits, bool safe)
{
CBigNum rand = RandKBitBigum(numBits);
CBigNum rand = randKBitBignum(numBits);
CBigNum prime;
mpz_nextprime(prime.bn, rand.bn);
return prime;
Expand Down
6 changes: 3 additions & 3 deletions src/libzerocoin/bignum_openssl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ CBigNum::CBigNum(const std::vector<unsigned char>& vch)
setvch(vch);
}

/** Generates a cryptographically secure random number between zero and range exclusive
* i.e. 0 < returned number < range
/** Generates a cryptographically secure random number between zero and range-1 (inclusive)
* i.e. 0 <= returned number < range
* @param range The upper bound on the number.
* @return
*/
Expand All @@ -70,7 +70,7 @@ CBigNum CBigNum::randBignum(const CBigNum& range)
* @param k The bit length of the number.
* @return
*/
CBigNum CBigNum::RandKBitBigum(const uint32_t k)
CBigNum CBigNum::randKBitBignum(const uint32_t k)
{
CBigNum ret;
if(!BN_rand(ret.bn, k, -1, 0)){
Expand Down
90 changes: 90 additions & 0 deletions src/test/zerocoin_bignum_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright (c) 2017-2018 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <boost/test/unit_test.hpp>
#include <iostream>

#include "libzerocoin/Commitment.h"
#include "libzerocoin/Denominations.h"
#include "libzerocoin/CoinSpend.h"
#include "libzerocoin/Accumulator.h"
#include "zpiv/zerocoin.h"

using namespace libzerocoin;

bool testRandKBitBignum(int k_bits)
{
CBigNum x = CBigNum::randKBitBignum(k_bits);
return (x.bitSize() <= k_bits);
}

bool testRandBignum(CBigNum limit)
{
CBigNum x = CBigNum::randBignum(limit);
return 0 <= x && x < limit;
}

BOOST_AUTO_TEST_SUITE(zerocoin_bignum_tests)

std::string zerocoinModulus = "25195908475657893494027183240048398571429282126204032027777137836043662020707595556264018525880784"
"4069182906412495150821892985591491761845028084891200728449926873928072877767359714183472702618963750149718246911"
"6507761337985909570009733045974880842840179742910064245869181719511874612151517265463228221686998754918242243363"
"7259085141865462043576798423387184774447920739934236584823824281198163815010674810451660377306056201619676256133"
"8441436038339044149526344321901146575444541784240209246165157233507787077498171257724679629263863563732899121548"
"31438167899885040445364023527381951378636564391212010397122822120720357";

std::string strHexModulus = "c7970ceedcc3b0754490201a7aa613cd73911081c790f5f1a8726f463550bb5b7ff0db8e1ea1189ec72f93d1650011bd721aeeacc2acde32a04107f0648c2813a31f5b0b7765ff8b44b4b6ffc93384b646eb09c7cf5e8592d40ea33c80039f35b4f14a04b51f7bfd781be4d1673164ba8eb991c2c4d730bbbe35f592bdef524af7e8daefd26c66fc02c479af89d64d373f442709439de66ceb955f3ea37d5159f6135809f85334b5cb1813addc80cd05609f10ac6a95ad65872c909525bdad32bc729592642920f24c61dc5b3c3b7923e56b16a4d9d373d8721f24a3fc0f1b3131f55615172866bccc30f95054c824e733a5eb6817f7bc16399d48c6361cc7e5";

BOOST_AUTO_TEST_CASE(bignum_setdecimal)
{
CBigNum bnDec;
bnDec.SetDec(zerocoinModulus);
CBigNum bnHex;
bnHex.SetHex(strHexModulus);
BOOST_CHECK_MESSAGE(bnDec == bnHex, "CBigNum.SetDec() does not work correctly");
}

std::string negstrHexModulus = "-c7970ceedcc3b0754490201a7aa613cd73911081c790f5f1a8726f463550bb5b7ff0db8e1ea1189ec72f93d1650011bd721aeeacc2acde32a04107f0648c2813a31f5b0b7765ff8b44b4b6ffc93384b646eb09c7cf5e8592d40ea33c80039f35b4f14a04b51f7bfd781be4d1673164ba8eb991c2c4d730bbbe35f592bdef524af7e8daefd26c66fc02c479af89d64d373f442709439de66ceb955f3ea37d5159f6135809f85334b5cb1813addc80cd05609f10ac6a95ad65872c909525bdad32bc729592642920f24c61dc5b3c3b7923e56b16a4d9d373d8721f24a3fc0f1b3131f55615172866bccc30f95054c824e733a5eb6817f7bc16399d48c6361cc7e5";
std::string str_a = "775897c5463939bf29a02816aba7b1741162e1f6b052cd32fec36c44dfee7d4b5162de78bb0b448cb305b0a9bd7e006aec62d7c1e94a31003c2decbdc6fd7c9b261cb88801c51e7cee71a215ff113ccbd02069cf29671e6302944ca5780a2f626eb9046fa6872968addc93c74d09cf6b2872bc4c6bd08e89324cc7e9fb921488";
std::string str_b = "-775897c5463939bf29a02816aba7b1741162e1f6b052cd32fec36c44dfee7d4b5162de78bb0b448cb305b0a9bd7e006aec62d7c1e94a31003c2decbdc6fd7c9b261cb88801c51e7cee71a215ff113ccbd02069cf29671e6302944ca5780a2f626eb9046fa6872968addc93c74d09cf6b2872bc4c6bd08e89324cc7e9fb921488";

BOOST_AUTO_TEST_CASE(bignum_basic_tests)
{
CBigNum bn, bn2;
std::vector<unsigned char> vch;

bn.SetHex(strHexModulus);
vch = bn.getvch();
bn2.setvch(vch);
BOOST_CHECK_MESSAGE(bn2 == bn, "CBigNum.setvch() or CBigNum.getvch() does not work correctly");

bn.SetHex(negstrHexModulus);
vch = bn.getvch();
bn2.setvch(vch);
BOOST_CHECK_MESSAGE(bn2 == bn, "CBigNum.setvch() or CBigNum.getvch() does not work correctly");

bn.SetHex(str_a);
vch = bn.getvch();
bn2.setvch(vch);
BOOST_CHECK_MESSAGE(bn2 == bn, "CBigNum.setvch() or CBigNum.getvch() does not work correctly");

bn.SetHex(str_b);
vch = bn.getvch();
bn2.setvch(vch);
BOOST_CHECK_MESSAGE(bn2 == bn, "CBigNum.setvch() or CBigNum.getvch() does not work correctly");
}


BOOST_AUTO_TEST_CASE(bignum_random_generation_tests)
{
for(int i=1; i<3000; i++) {
BOOST_CHECK_MESSAGE(testRandKBitBignum(i), strprintf("CBigNum::randKBitBignum(%d) failed", i));
}

for(int i=1; i<3000; i++) {
CBigNum x = 1 + CBigNum::randKBitBignum(i);
BOOST_CHECK_MESSAGE(testRandBignum(x), strprintf("CBigNum::randBignum(x) failed with x=%s", x.ToString()));
}
}

BOOST_AUTO_TEST_SUITE_END()
10 changes: 5 additions & 5 deletions src/test/zerocoin_denomination_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE(zerocoin_spend_test241)
nTotalAmount += currentAmount;
CBigNum value;
CBigNum rand;
CBigNum serial = CBigNum::RandKBitBigum(256);
CBigNum serial = CBigNum::randKBitBignum(256);
bool isUsed = false;
CMintMeta meta;
meta.denom = denom;
Expand Down Expand Up @@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(zerocoin_spend_test115)
nTotalAmount += currentAmount;
CBigNum value;
CBigNum rand;
CBigNum serial = CBigNum::RandKBitBigum(256);
CBigNum serial = CBigNum::randKBitBignum(256);
bool isUsed = false;
CMintMeta meta;
meta.denom = denom;
Expand Down Expand Up @@ -259,7 +259,7 @@ BOOST_AUTO_TEST_CASE(zerocoin_spend_test_from_245)
nTotalAmount += currentAmount;
CBigNum value;
CBigNum rand;
CBigNum serial = CBigNum::RandKBitBigum(256);
CBigNum serial = CBigNum::randKBitBignum(256);
bool isUsed = false;
CMintMeta meta;
meta.denom = denom;
Expand Down Expand Up @@ -361,7 +361,7 @@ BOOST_AUTO_TEST_CASE(zerocoin_spend_test_from_145)
nTotalAmount += currentAmount;
CBigNum value;
CBigNum rand;
CBigNum serial = CBigNum::RandKBitBigum(256);
CBigNum serial = CBigNum::randKBitBignum(256);
bool isUsed = false;
CMintMeta meta;
meta.denom = denom;
Expand Down Expand Up @@ -467,7 +467,7 @@ BOOST_AUTO_TEST_CASE(zerocoin_spend_test99)
nTotalAmount += currentAmount;
CBigNum value;
CBigNum rand;
CBigNum serial = CBigNum::RandKBitBigum(256);
CBigNum serial = CBigNum::randKBitBignum(256);
bool isUsed = false;
CMintMeta meta;
meta.denom = denom;
Expand Down
41 changes: 1 addition & 40 deletions src/test/zerocoin_implementation_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,46 +48,7 @@ std::string zerocoinModulus = "2519590847565789349402718324004839857142928212620
"8441436038339044149526344321901146575444541784240209246165157233507787077498171257724679629263863563732899121548"
"31438167899885040445364023527381951378636564391212010397122822120720357";

std::string strHexModulus = "c7970ceedcc3b0754490201a7aa613cd73911081c790f5f1a8726f463550bb5b7ff0db8e1ea1189ec72f93d1650011bd721aeeacc2acde32a04107f0648c2813a31f5b0b7765ff8b44b4b6ffc93384b646eb09c7cf5e8592d40ea33c80039f35b4f14a04b51f7bfd781be4d1673164ba8eb991c2c4d730bbbe35f592bdef524af7e8daefd26c66fc02c479af89d64d373f442709439de66ceb955f3ea37d5159f6135809f85334b5cb1813addc80cd05609f10ac6a95ad65872c909525bdad32bc729592642920f24c61dc5b3c3b7923e56b16a4d9d373d8721f24a3fc0f1b3131f55615172866bccc30f95054c824e733a5eb6817f7bc16399d48c6361cc7e5";

BOOST_AUTO_TEST_CASE(bignum_setdecimal)
{
CBigNum bnDec;
bnDec.SetDec(zerocoinModulus);
CBigNum bnHex;
bnHex.SetHex(strHexModulus);
BOOST_CHECK_MESSAGE(bnDec == bnHex, "CBigNum.SetDec() does not work correctly");
}

std::string negstrHexModulus = "-c7970ceedcc3b0754490201a7aa613cd73911081c790f5f1a8726f463550bb5b7ff0db8e1ea1189ec72f93d1650011bd721aeeacc2acde32a04107f0648c2813a31f5b0b7765ff8b44b4b6ffc93384b646eb09c7cf5e8592d40ea33c80039f35b4f14a04b51f7bfd781be4d1673164ba8eb991c2c4d730bbbe35f592bdef524af7e8daefd26c66fc02c479af89d64d373f442709439de66ceb955f3ea37d5159f6135809f85334b5cb1813addc80cd05609f10ac6a95ad65872c909525bdad32bc729592642920f24c61dc5b3c3b7923e56b16a4d9d373d8721f24a3fc0f1b3131f55615172866bccc30f95054c824e733a5eb6817f7bc16399d48c6361cc7e5";
std::string str_a = "775897c5463939bf29a02816aba7b1741162e1f6b052cd32fec36c44dfee7d4b5162de78bb0b448cb305b0a9bd7e006aec62d7c1e94a31003c2decbdc6fd7c9b261cb88801c51e7cee71a215ff113ccbd02069cf29671e6302944ca5780a2f626eb9046fa6872968addc93c74d09cf6b2872bc4c6bd08e89324cc7e9fb921488";
std::string str_b = "-775897c5463939bf29a02816aba7b1741162e1f6b052cd32fec36c44dfee7d4b5162de78bb0b448cb305b0a9bd7e006aec62d7c1e94a31003c2decbdc6fd7c9b261cb88801c51e7cee71a215ff113ccbd02069cf29671e6302944ca5780a2f626eb9046fa6872968addc93c74d09cf6b2872bc4c6bd08e89324cc7e9fb921488";

BOOST_AUTO_TEST_CASE(bignum_basic_tests)
{
CBigNum bn, bn2;
std::vector<unsigned char> vch;

bn.SetHex(strHexModulus);
vch = bn.getvch();
bn2.setvch(vch);
BOOST_CHECK_MESSAGE(bn2 == bn, "CBigNum.setvch() or CBigNum.getvch() does not work correctly");

bn.SetHex(negstrHexModulus);
vch = bn.getvch();
bn2.setvch(vch);
BOOST_CHECK_MESSAGE(bn2 == bn, "CBigNum.setvch() or CBigNum.getvch() does not work correctly");

bn.SetHex(str_a);
vch = bn.getvch();
bn2.setvch(vch);
BOOST_CHECK_MESSAGE(bn2 == bn, "CBigNum.setvch() or CBigNum.getvch() does not work correctly");

bn.SetHex(str_b);
vch = bn.getvch();
bn2.setvch(vch);
BOOST_CHECK_MESSAGE(bn2 == bn, "CBigNum.setvch() or CBigNum.getvch() does not work correctly");
}

//ZQ_ONE mints
std::string rawTx1 = "0100000001983d5fd91685bb726c0ebc3676f89101b16e663fd896fea53e19972b95054c49000000006a473044022010fbec3e78f9c46e58193d481caff715ceb984df44671d30a2c0bde95c54055f0220446a97d9340da690eaf2658e5b2bf6a0add06f1ae3f1b40f37614c7079ce450d012103cb666bd0f32b71cbf4f32e95fa58e05cd83869ac101435fcb8acee99123ccd1dffffffff0200e1f5050000000086c10280004c80c3a01f94e71662f2ae8bfcd88dfc5b5e717136facd6538829db0c7f01e5fd793cccae7aa1958564518e0223d6d9ce15b1e38e757583546e3b9a3f85bd14408120cd5192a901bb52152e8759fdd194df230d78477706d0e412a66398f330be38a23540d12ab147e9fb19224913f3fe552ae6a587fb30a68743e52577150ff73042c0f0d8f000000001976a914d6042025bd1fff4da5da5c432d85d82b3f26a01688ac00000000";
Expand Down Expand Up @@ -397,7 +358,7 @@ BOOST_AUTO_TEST_CASE(checkzerocoinspend_test)
//Get the checksum of the accumulator we use for the spend and also add it to our checksum map
uint32_t nChecksum_v2 = GetChecksum(accumulator_v2.getValue());
//AddAccumulatorChecksum(nChecksum_v2, accumulator_v2.getValue(), true);
uint256 ptxHash = CBigNum::RandKBitBigum(256).getuint256();
uint256 ptxHash = CBigNum::randKBitBignum(256).getuint256();
CoinSpend coinSpend_v2(Params().Zerocoin_Params(false), Params().Zerocoin_Params(false), privateCoin_v2, accumulator_v2, nChecksum_v2, witness_v2, ptxHash, SpendType::SPEND);

BOOST_CHECK_MESSAGE(coinSpend_v2.HasValidSerial(Params().Zerocoin_Params(false)), "coinspend_v2 does not have a valid serial");
Expand Down

0 comments on commit a99c2dd

Please sign in to comment.