From fe25370cb1bcb07a894fc1a020cbf99e8bb07434 Mon Sep 17 00:00:00 2001 From: MASM fan Date: Fri, 7 Nov 2014 22:48:30 +0400 Subject: [PATCH] Remove zerocoin for now --- novacoin-qt.pro | 23 +- src/init.cpp | 11 - src/kernel.h | 4 +- src/main.cpp | 26 - src/main.h | 3 +- src/makefile.bsd | 21 +- src/makefile.linux-mingw | 16 +- src/makefile.mingw | 16 +- src/makefile.osx | 21 +- src/makefile.unix | 21 +- src/obj/zerocoin/.gitignore | 2 - src/wallet.h | 4 +- src/zerocoin/Accumulator.cpp | 106 ---- src/zerocoin/Accumulator.h | 148 ----- src/zerocoin/AccumulatorProofOfKnowledge.cpp | 143 ----- src/zerocoin/AccumulatorProofOfKnowledge.h | 91 --- src/zerocoin/Coin.cpp | 167 ------ src/zerocoin/Coin.h | 139 ----- src/zerocoin/CoinSpend.cpp | 82 --- src/zerocoin/CoinSpend.h | 107 ---- src/zerocoin/Commitment.cpp | 172 ------ src/zerocoin/Commitment.h | 105 ---- src/zerocoin/ParamGeneration.cpp | 654 --------------------- src/zerocoin/ParamGeneration.h | 53 -- src/zerocoin/Params.cpp | 45 -- src/zerocoin/Params.h | 216 ------- src/zerocoin/SerialNumberSignatureOfKnowledge.cpp | 139 ----- src/zerocoin/SerialNumberSignatureOfKnowledge.h | 75 --- src/zerocoin/SpendMetaData.cpp | 19 - src/zerocoin/SpendMetaData.h | 52 -- src/zerocoin/ZeroTest.cpp | 421 ------------- src/zerocoin/ZeroTest.h | 6 - src/zerocoin/Zerocoin.h | 61 -- 33 files changed, 11 insertions(+), 3158 deletions(-) delete mode 100644 src/obj/zerocoin/.gitignore delete mode 100644 src/zerocoin/Accumulator.cpp delete mode 100644 src/zerocoin/Accumulator.h delete mode 100644 src/zerocoin/AccumulatorProofOfKnowledge.cpp delete mode 100644 src/zerocoin/AccumulatorProofOfKnowledge.h delete mode 100644 src/zerocoin/Coin.cpp delete mode 100644 src/zerocoin/Coin.h delete mode 100644 src/zerocoin/CoinSpend.cpp delete mode 100644 src/zerocoin/CoinSpend.h delete mode 100644 src/zerocoin/Commitment.cpp delete mode 100644 src/zerocoin/Commitment.h delete mode 100644 src/zerocoin/ParamGeneration.cpp delete mode 100644 src/zerocoin/ParamGeneration.h delete mode 100644 src/zerocoin/Params.cpp delete mode 100644 src/zerocoin/Params.h delete mode 100644 src/zerocoin/SerialNumberSignatureOfKnowledge.cpp delete mode 100644 src/zerocoin/SerialNumberSignatureOfKnowledge.h delete mode 100644 src/zerocoin/SpendMetaData.cpp delete mode 100644 src/zerocoin/SpendMetaData.h delete mode 100644 src/zerocoin/ZeroTest.cpp delete mode 100644 src/zerocoin/ZeroTest.h delete mode 100644 src/zerocoin/Zerocoin.h diff --git a/novacoin-qt.pro b/novacoin-qt.pro index 739a69d..8d16160 100644 --- a/novacoin-qt.pro +++ b/novacoin-qt.pro @@ -199,17 +199,6 @@ HEADERS += src/qt/bitcoingui.h \ src/kernel.h \ src/scrypt.h \ src/pbkdf2.h \ - src/zerocoin/Accumulator.h \ - src/zerocoin/AccumulatorProofOfKnowledge.h \ - src/zerocoin/Coin.h \ - src/zerocoin/CoinSpend.h \ - src/zerocoin/Commitment.h \ - src/zerocoin/ParamGeneration.h \ - src/zerocoin/Params.h \ - src/zerocoin/SerialNumberSignatureOfKnowledge.h \ - src/zerocoin/SpendMetaData.h \ - src/zerocoin/ZeroTest.h \ - src/zerocoin/Zerocoin.h \ src/serialize.h \ src/strlcpy.h \ src/main.h \ @@ -329,17 +318,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/noui.cpp \ src/kernel.cpp \ src/scrypt.cpp \ - src/pbkdf2.cpp \ - src/zerocoin/Accumulator.cpp \ - src/zerocoin/AccumulatorProofOfKnowledge.cpp \ - src/zerocoin/Coin.cpp \ - src/zerocoin/CoinSpend.cpp \ - src/zerocoin/Commitment.cpp \ - src/zerocoin/ParamGeneration.cpp \ - src/zerocoin/Params.cpp \ - src/zerocoin/SerialNumberSignatureOfKnowledge.cpp \ - src/zerocoin/SpendMetaData.cpp \ - src/zerocoin/ZeroTest.cpp + src/pbkdf2.cpp RESOURCES += \ src/qt/bitcoin.qrc diff --git a/src/init.cpp b/src/init.cpp index 2e9193d..03b8c13 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -10,7 +10,6 @@ #include "util.h" #include "ui_interface.h" #include "checkpoints.h" -#include "zerocoin/ZeroTest.h" #include #include #include @@ -778,16 +777,6 @@ bool AppInit2() return false; } - // ********************************************************* Testing Zerocoin - - - if (GetBoolArg("-zerotest", false)) - { - printf("\n=== ZeroCoin tests start ===\n"); - Test_RunAllTests(); - printf("=== ZeroCoin tests end ===\n\n"); - } - // ********************************************************* Step 8: load wallet uiInterface.InitMessage(_("Loading wallet...")); diff --git a/src/kernel.h b/src/kernel.h index a0632f9..6491cfd 100644 --- a/src/kernel.h +++ b/src/kernel.h @@ -42,11 +42,11 @@ typedef struct KernelSearchSettings { unsigned int nSearchInterval; // Number of seconds allowed to go into the past } KernelSearchSettings; -typedef set > CoinsSet; +typedef std::set > CoinsSet; // Preloaded coins metadata // txid => ((txindex, (tx, vout.n)), (block, modifier)) -typedef map >, pair > > MetaMap; +typedef std::map >, std::pair > > MetaMap; // Scan given coins set for kernel solution bool ScanForStakeKernelHash(MetaMap &mapMeta, KernelSearchSettings &settings, CoinsSet::value_type &kernelcoin, unsigned int &nTimeTx, unsigned int &nBlockTime); diff --git a/src/main.cpp b/src/main.cpp index 0d2325c..ab518d4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,7 +12,6 @@ #include "ui_interface.h" #include "checkqueue.h" #include "kernel.h" -#include "zerocoin/Zerocoin.h" #include #include #include @@ -35,7 +34,6 @@ unsigned int nTransactionsUpdated = 0; map mapBlockIndex; set > setStakeSeen; -libzerocoin::Params* ZCParams; CBigNum bnProofOfWorkLimit(~uint256(0) >> 20); // "standard" scrypt target limit for proof of work, results with 0,000244140625 proof-of-work difficulty CBigNum bnProofOfStakeLegacyLimit(~uint256(0) >> 24); // proof of stake target limit from block #15000 and until 20 June 2013, results with 0,00390625 proof of stake difficulty @@ -2804,30 +2802,6 @@ FILE* AppendBlockFile(unsigned int& nFileRet) bool LoadBlockIndex(bool fAllowNew) { - CBigNum bnTrustedModulus; - - if (fTestNet) - { - pchMessageStart[0] = 0xcd; - pchMessageStart[1] = 0xf2; - pchMessageStart[2] = 0xc0; - pchMessageStart[3] = 0xef; - - bnTrustedModulus.SetHex("f0d14cf72623dacfe738d0892b599be0f31052239cddd95a3f25101c801dc990453b38c9434efe3f372db39a32c2bb44cbaea72d62c8931fa785b0ec44531308df3e46069be5573e49bb29f4d479bfc3d162f57a5965db03810be7636da265bfced9c01a6b0296c77910ebdc8016f70174f0f18a57b3b971ac43a934c6aedbc5c866764a3622b5b7e3f9832b8b3f133c849dbcc0396588abcd1e41048555746e4823fb8aba5b3d23692c6857fccce733d6bb6ec1d5ea0afafecea14a0f6f798b6b27f77dc989c557795cc39a0940ef6bb29a7fc84135193a55bcfc2f01dd73efad1b69f45a55198bd0e6bef4d338e452f6a420f1ae2b1167b923f76633ab6e55"); - bnProofOfWorkLimit = bnProofOfWorkLimitTestNet; // 16 bits PoW target limit for testnet - nStakeMinAge = 2 * 60 * 60; // test net min age is 2 hours - nModifierInterval = 20 * 60; // test modifier interval is 20 minutes - nCoinbaseMaturity = 10; // test maturity is 10 blocks - nStakeTargetSpacing = 5 * 60; // test block spacing is 5 minutes - } - else - { - bnTrustedModulus.SetHex("d01f952e1090a5a72a3eda261083256596ccc192935ae1454c2bafd03b09e6ed11811be9f3a69f5783bbbced8c6a0c56621f42c2d19087416facf2f13cc7ed7159d1c5253119612b8449f0c7f54248e382d30ecab1928dbf075c5425dcaee1a819aa13550e0f3227b8c685b14e0eae094d65d8a610a6f49fff8145259d1187e4c6a472fa5868b2b67f957cb74b787f4311dbc13c97a2ca13acdb876ff506ebecbb904548c267d68868e07a32cd9ed461fbc2f920e9940e7788fed2e4817f274df5839c2196c80abe5c486df39795186d7bc86314ae1e8342f3c884b158b4b05b4302754bf351477d35370bad6639b2195d30006b77bf3dbb28b848fd9ecff5662bf39dde0c974e83af51b0d3d642d43834827b8c3b189065514636b8f2a59c42ba9b4fc4975d4827a5d89617a3873e4b377b4d559ad165748632bd928439cfbc5a8ef49bc2220e0b15fb0aa302367d5e99e379a961c1bc8cf89825da5525e3c8f14d7d8acca2fa9c133a2176ae69874d8b1d38b26b9c694e211018005a97b40848681b9dd38feb2de141626fb82591aad20dc629b2b6421cef1227809551a0e4e943ab99841939877f18f2d9c0addc93cf672e26b02ed94da3e6d329e8ac8f3736eebbf37bb1a21e5aadf04ee8e3b542f876aa88b2adf2608bd86329b7f7a56fd0dc1c40b48188731d11082aea360c62a0840c2db3dad7178fd7e359317ae081"); - } - - // Set up the Zerocoin Params object - ZCParams = new libzerocoin::Params(bnTrustedModulus); - // // Load block index // diff --git a/src/main.h b/src/main.h index 02586c1..862747b 100644 --- a/src/main.h +++ b/src/main.h @@ -11,9 +11,9 @@ #include "net.h" #include "script.h" #include "scrypt.h" -#include "zerocoin/Zerocoin.h" #include +#include class CWallet; class CBlock; @@ -59,7 +59,6 @@ static const uint256 hashGenesisBlockTestNet("0x000c763e402f2436da9ed36c7286f62c inline int64 PastDrift(int64 nTime) { return nTime - 2 * 60 * 60; } // up to 2 hours from the past inline int64 FutureDrift(int64 nTime) { return nTime + 2 * 60 * 60; } // up to 2 hours from the future -extern libzerocoin::Params* ZCParams; extern CScript COINBASE_FLAGS; extern CCriticalSection cs_main; extern std::map mapBlockIndex; diff --git a/src/makefile.bsd b/src/makefile.bsd index 472f111..5a30ebc 100644 --- a/src/makefile.bsd +++ b/src/makefile.bsd @@ -128,17 +128,7 @@ OBJS= \ obj/noui.o \ obj/kernel.o \ obj/pbkdf2.o \ - obj/scrypt.o \ - obj/zerocoin/Accumulator.o \ - obj/zerocoin/AccumulatorProofOfKnowledge.o \ - obj/zerocoin/Coin.o \ - obj/zerocoin/CoinSpend.o \ - obj/zerocoin/Commitment.o \ - obj/zerocoin/ParamGeneration.o \ - obj/zerocoin/Params.o \ - obj/zerocoin/SerialNumberSignatureOfKnowledge.o \ - obj/zerocoin/SpendMetaData.o \ - obj/zerocoin/ZeroTest.o + obj/scrypt.o all: novacoind @@ -192,22 +182,13 @@ obj/%.o: %.cpp -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ rm -f $(@:%.o=%.d) -obj/zerocoin/%.o: zerocoin/%.cpp - $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< - @cp $(@:%.o=%.d) $(@:%.o=%.P); \ - sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ - -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ - rm -f $(@:%.o=%.d) - novacoind: $(OBJS:obj/%=obj/%) $(LINK) $(xCXXFLAGS) -o $@ $^ $(xLDFLAGS) $(LIBS) clean: -rm -f novacoind -rm -f obj/*.o - -rm -f obj/zerocoin/*.o -rm -f obj/*.P - -rm -f obj/zerocoin/*.P -rm -f obj/build.h FORCE: diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index 385bab0..8bed0ff 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -91,17 +91,7 @@ OBJS= \ obj/noui.o \ obj/kernel.o \ obj/pbkdf2.o \ - obj/scrypt.o \ - obj/zerocoin/Accumulator.o \ - obj/zerocoin/AccumulatorProofOfKnowledge.o \ - obj/zerocoin/Coin.o \ - obj/zerocoin/CoinSpend.o \ - obj/zerocoin/Commitment.o \ - obj/zerocoin/ParamGeneration.o \ - obj/zerocoin/Params.o \ - obj/zerocoin/SerialNumberSignatureOfKnowledge.o \ - obj/zerocoin/SpendMetaData.o \ - obj/zerocoin/ZeroTest.o + obj/scrypt.o all: novacoind.exe @@ -144,16 +134,12 @@ DEFS += -DHAVE_BUILD_INFO obj/%.o: %.cpp $(HEADERS) $(CXX) -c $(CFLAGS) -o $@ $< -obj/zerocoin/%.o: zerocoin/%.cpp $(HEADERS) - $(CXX) -c $(CFLAGS) -o $@ $< - novacoind.exe: $(OBJS:obj/%=obj/%) $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) -lshlwapi $(STRIP) novacoind.exe clean: -rm -f obj/*.o - -rm -f obj/zerocoin/*.o -rm -f novacoind.exe -rm -f obj/build.h cd leveldb && TARGET_OS=OS_WINDOWS_CROSSCOMPILE $(MAKE) clean && cd .. diff --git a/src/makefile.mingw b/src/makefile.mingw index 4c9944b..6a808b0 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -82,17 +82,7 @@ OBJS= \ obj/noui.o \ obj/kernel.o \ obj/pbkdf2.o \ - obj/scrypt.o \ - obj/zerocoin/Accumulator.o \ - obj/zerocoin/AccumulatorProofOfKnowledge.o \ - obj/zerocoin/Coin.o \ - obj/zerocoin/CoinSpend.o \ - obj/zerocoin/Commitment.o \ - obj/zerocoin/ParamGeneration.o \ - obj/zerocoin/Params.o \ - obj/zerocoin/SerialNumberSignatureOfKnowledge.o \ - obj/zerocoin/SpendMetaData.o \ - obj/zerocoin/ZeroTest.o + obj/scrypt.o all: novacoind.exe @@ -129,15 +119,11 @@ endif obj/%.o: %.cpp $(HEADERS) g++ -c $(CFLAGS) -o $@ $< -obj/zerocoin/%.o: zerocoin/%.cpp - g++ -c $(CFLAGS) -o $@ $< - novacoind.exe: $(OBJS:obj/%=obj/%) g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) clean: -del /Q novacoind -del /Q obj\* - -del /Q obj\zerocoin\* FORCE: diff --git a/src/makefile.osx b/src/makefile.osx index 2988d81..3b6353d 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -93,17 +93,7 @@ OBJS= \ obj/noui.o \ obj/pbkdf2.o \ obj/kernel.o \ - obj/scrypt.o \ - obj/zerocoin/Accumulator.o \ - obj/zerocoin/AccumulatorProofOfKnowledge.o \ - obj/zerocoin/Coin.o \ - obj/zerocoin/CoinSpend.o \ - obj/zerocoin/Commitment.o \ - obj/zerocoin/ParamGeneration.o \ - obj/zerocoin/Params.o \ - obj/zerocoin/SerialNumberSignatureOfKnowledge.o \ - obj/zerocoin/SpendMetaData.o \ - obj/zerocoin/ZeroTest.o + obj/scrypt.o ifndef USE_UPNP override USE_UPNP = - @@ -172,22 +162,13 @@ obj/%.o: %.cpp -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ rm -f $(@:%.o=%.d) -obj/zerocoin/%.o: zerocoin/%.cpp - $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< - @cp $(@:%.o=%.d) $(@:%.o=%.P); \ - sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ - -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ - rm -f $(@:%.o=%.d) - novacoind: $(OBJS:obj/%=obj/%) $(CXX) $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) clean: -rm -f novacoind -rm -f obj/*.o - -rm -f obj/zerocoin/*.o -rm -f obj/*.P - -rm -f obj/zerocoin/*.P -rm -f obj/build.h FORCE: diff --git a/src/makefile.unix b/src/makefile.unix index 9097e93..bcc102e 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -134,17 +134,7 @@ OBJS= \ obj/noui.o \ obj/kernel.o \ obj/pbkdf2.o \ - obj/scrypt.o \ - obj/zerocoin/Accumulator.o \ - obj/zerocoin/AccumulatorProofOfKnowledge.o \ - obj/zerocoin/Coin.o \ - obj/zerocoin/CoinSpend.o \ - obj/zerocoin/Commitment.o \ - obj/zerocoin/ParamGeneration.o \ - obj/zerocoin/Params.o \ - obj/zerocoin/SerialNumberSignatureOfKnowledge.o \ - obj/zerocoin/SpendMetaData.o \ - obj/zerocoin/ZeroTest.o + obj/scrypt.o all: novacoind @@ -199,22 +189,13 @@ obj/%.o: %.cpp -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ rm -f $(@:%.o=%.d) -obj/zerocoin/%.o: zerocoin/%.cpp - $(CXX) -c $(xCXXFLAGS) -MMD -MF $(@:%.o=%.d) -o $@ $< - @cp $(@:%.o=%.d) $(@:%.o=%.P); \ - sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ - -e '/^$$/ d' -e 's/$$/ :/' < $(@:%.o=%.d) >> $(@:%.o=%.P); \ - rm -f $(@:%.o=%.d) - novacoind: $(OBJS:obj/%=obj/%) $(LINK) $(xCXXFLAGS) -o $@ $^ $(xLDFLAGS) $(LIBS) clean: -rm -f novacoind -rm -f obj/*.o - -rm -f obj/zerocoin/*.o -rm -f obj/*.P - -rm -f obj/zerocoin/*.P -rm -f obj/build.h FORCE: diff --git a/src/obj/zerocoin/.gitignore b/src/obj/zerocoin/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/src/obj/zerocoin/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/src/wallet.h b/src/wallet.h index e838834..a9be672 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -81,7 +81,7 @@ private: int nWalletMaxVersion; // selected coins metadata - map >, pair > > mapMeta; + std::map >, std::pair > > mapMeta; public: mutable CCriticalSection cs_wallet; @@ -203,7 +203,7 @@ public: bool GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight); void GetStakeWeightFromValue(const int64& nTime, const int64& nValue, uint64& nWeight); bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew, CKey& key); - bool MergeCoins(const int64& nAmount, const int64& nMinValue, const int64& nMaxValue, list& listMerged); + bool MergeCoins(const int64& nAmount, const int64& nMinValue, const int64& nMaxValue, std::list& listMerged); std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); diff --git a/src/zerocoin/Accumulator.cpp b/src/zerocoin/Accumulator.cpp deleted file mode 100644 index e05f8ac..0000000 --- a/src/zerocoin/Accumulator.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @file Accumulator.cpp - * - * @brief Accumulator and AccumulatorWitness classes for the Zerocoin library. - * - * @author Ian Miers, Christina Garman and Matthew Green - * @date June 2013 - * - * @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green - * @license This project is released under the MIT license. - **/ - -#include -#include "Zerocoin.h" - -namespace libzerocoin { - -//Accumulator class -Accumulator::Accumulator(const AccumulatorAndProofParams* p, const CoinDenomination d): params(p), denomination(d) { - if (!(params->initialized)) { - throw ZerocoinException("Invalid parameters for accumulator"); - } - - this->value = this->params->accumulatorBase; -} - -Accumulator::Accumulator(const Params* p, const CoinDenomination d) { - this->params = &(p->accumulatorParams); - this->denomination = d; - - if (!(params->initialized)) { - throw ZerocoinException("Invalid parameters for accumulator"); - } - - this->value = this->params->accumulatorBase; -} - -void Accumulator::accumulate(const PublicCoin& coin) { - // Make sure we're initialized - if(!(this->value)) { - throw ZerocoinException("Accumulator is not initialized"); - } - - if(this->denomination != coin.getDenomination()) { - //std::stringstream msg; - std::string msg; - msg = "Wrong denomination for coin. Expected coins of denomination: "; - msg += this->denomination; - msg += ". Instead, got a coin of denomination: "; - msg += coin.getDenomination(); - throw std::invalid_argument(msg); - } - - if(coin.validate()) { - // Compute new accumulator = "old accumulator"^{element} mod N - this->value = this->value.pow_mod(coin.getValue(), this->params->accumulatorModulus); - } else { - throw std::invalid_argument("Coin is not valid"); - } -} - -const CoinDenomination Accumulator::getDenomination() const { - return static_cast (this->denomination); -} - -const Bignum& Accumulator::getValue() const { - return this->value; -} - -Accumulator& Accumulator::operator += (const PublicCoin& c) { - this->accumulate(c); - return *this; -} - -bool Accumulator::operator == (const Accumulator rhs) const { - return this->value == rhs.value; -} - -//AccumulatorWitness class -AccumulatorWitness::AccumulatorWitness(const Params* p, - const Accumulator& checkpoint, const PublicCoin coin): params(p), witness(checkpoint), element(coin) { -} - -void AccumulatorWitness::AddElement(const PublicCoin& c) { - if(element != c) { - witness += c; - } -} - -const Bignum& AccumulatorWitness::getValue() const { - return this->witness.getValue(); -} - -bool AccumulatorWitness::VerifyWitness(const Accumulator& a, const PublicCoin &publicCoin) const { - Accumulator temp(witness); - temp += element; - return (temp == a && this->element == publicCoin); -} - -AccumulatorWitness& AccumulatorWitness::operator +=( - const PublicCoin& rhs) { - this->AddElement(rhs); - return *this; -} - -} /* namespace libzerocoin */ diff --git a/src/zerocoin/Accumulator.h b/src/zerocoin/Accumulator.h deleted file mode 100644 index deed87b..0000000 --- a/src/zerocoin/Accumulator.h +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @file Accumulator.h - * - * @brief Accumulator and AccumulatorWitness classes for the Zerocoin library. - * - * @author Ian Miers, Christina Garman and Matthew Green - * @date June 2013 - * - * @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green - * @license This project is released under the MIT license. - **/ -#ifndef ACCUMULATOR_H_ -#define ACCUMULATOR_H_ - -namespace libzerocoin { -/** - * \brief Implementation of the RSA-based accumulator. - **/ - -class Accumulator { -public: - - /** - * @brief Construct an Accumulator from a stream. - * @param p An AccumulatorAndProofParams object containing global parameters - * @param d the denomination of coins we are accumulating - * @throw Zerocoin exception in case of invalid parameters - **/ - template - Accumulator(const AccumulatorAndProofParams* p, Stream& strm): params(p) { - strm >> *this; - } - - template - Accumulator(const Params* p, Stream& strm) { - strm >> *this; - this->params = &(p->accumulatorParams); - } - - /** - * @brief Construct an Accumulator from a Params object. - * @param p A Params object containing global parameters - * @param d the denomination of coins we are accumulating - * @throw Zerocoin exception in case of invalid parameters - **/ - Accumulator(const AccumulatorAndProofParams* p, const CoinDenomination d = ZQ_PEDERSEN); - - Accumulator(const Params* p, const CoinDenomination d = ZQ_PEDERSEN); - - /** - * Accumulate a coin into the accumulator. Validates - * the coin prior to accumulation. - * - * @param coin A PublicCoin to accumulate. - * - * @throw Zerocoin exception if the coin is not valid. - * - **/ - void accumulate(const PublicCoin &coin); - - const CoinDenomination getDenomination() const; - /** Get the accumulator result - * - * @return a Bignum containing the result. - */ - const Bignum& getValue() const; - - - // /** - // * Used to set the accumulator value - // * - // * Use this to handle accumulator checkpoints - // * @param b the value to set the accumulator to. - // * @throw A ZerocoinException if the accumulator value is invalid. - // */ - // void setValue(Bignum &b); // shouldn't this be a constructor? - - /** Used to accumulate a coin - * - * @param c the coin to accumulate - * @return a refrence to the updated accumulator. - */ - Accumulator& operator +=(const PublicCoin& c); - bool operator==(const Accumulator rhs) const; - - IMPLEMENT_SERIALIZE - ( - READWRITE(value); - READWRITE(denomination); - ) -private: - const AccumulatorAndProofParams* params; - Bignum value; - // Denomination is stored as an INT because storing - // and enum raises amigiuities in the serialize code //FIXME if possible - int denomination; -}; - -/**A witness that a PublicCoin is in the accumulation of a set of coins - * - */ -class AccumulatorWitness { -public: - template - AccumulatorWitness(const Params* p, Stream& strm): params(p) { - strm >> *this; - } - - /** Construct's a witness. You must add all elements after the witness - * @param p pointer to params - * @param checkpoint the last known accumulator value before the element was added - * @param coin the coin we want a witness to - */ - AccumulatorWitness(const Params* p, const Accumulator& checkpoint, const PublicCoin coin); - - /** Adds element to the set whose's accumulation we are proving coin is a member of - * - * @param c the coin to add - */ - void AddElement(const PublicCoin& c); - - /** - * - * @return the value of the witness - */ - const Bignum& getValue() const; - - /** Checks that this is a witness to the accumulation of coin - * @param a the accumulator we are checking against. - * @param publicCoin the coin we're providing a witness for - * @return True if the witness computation validates - */ - bool VerifyWitness(const Accumulator& a, const PublicCoin &publicCoin) const; - - /** - * Adds rhs to the set whose's accumulation ware proving coin is a member of - * @param rhs the PublicCoin to add - * @return - */ - AccumulatorWitness& operator +=(const PublicCoin& rhs); -private: - const Params* params; - Accumulator witness; - const PublicCoin element; -}; - -} /* namespace libzerocoin */ -#endif /* ACCUMULATOR_H_ */ diff --git a/src/zerocoin/AccumulatorProofOfKnowledge.cpp b/src/zerocoin/AccumulatorProofOfKnowledge.cpp deleted file mode 100644 index ed9ac91..0000000 --- a/src/zerocoin/AccumulatorProofOfKnowledge.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/** - * @file AccumulatorProofOfKnowledge.cpp - * - * @brief AccumulatorProofOfKnowledge class for the Zerocoin library. - * - * @author Ian Miers, Christina Garman and Matthew Green - * @date June 2013 - * - * @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green - * @license This project is released under the MIT license. - **/ - -#include "Zerocoin.h" - -namespace libzerocoin { - -AccumulatorProofOfKnowledge::AccumulatorProofOfKnowledge(const AccumulatorAndProofParams* p): params(p) {} - -AccumulatorProofOfKnowledge::AccumulatorProofOfKnowledge(const AccumulatorAndProofParams* p, - const Commitment& commitmentToCoin, const AccumulatorWitness& witness, - Accumulator& a): params(p) { - - Bignum sg = params->accumulatorPoKCommitmentGroup.g; - Bignum sh = params->accumulatorPoKCommitmentGroup.h; - - Bignum g_n = params->accumulatorQRNCommitmentGroup.g; - Bignum h_n = params->accumulatorQRNCommitmentGroup.h; - - Bignum e = commitmentToCoin.getContents(); - Bignum r = commitmentToCoin.getRandomness(); - - Bignum r_1 = Bignum::randBignum(params->accumulatorModulus/4); - Bignum r_2 = Bignum::randBignum(params->accumulatorModulus/4); - Bignum r_3 = Bignum::randBignum(params->accumulatorModulus/4); - - this->C_e = g_n.pow_mod(e, params->accumulatorModulus) * h_n.pow_mod(r_1, params->accumulatorModulus); - this->C_u = witness.getValue() * h_n.pow_mod(r_2, params->accumulatorModulus); - this->C_r = g_n.pow_mod(r_2, params->accumulatorModulus) * h_n.pow_mod(r_3, params->accumulatorModulus); - - Bignum r_alpha = Bignum::randBignum(params->maxCoinValue * Bignum(2).pow(params->k_prime + params->k_dprime)); - if(!(Bignum::randBignum(Bignum(3)) % 2)) { - r_alpha = 0-r_alpha; - } - - Bignum r_gamma = Bignum::randBignum(params->accumulatorPoKCommitmentGroup.modulus); - Bignum r_phi = Bignum::randBignum(params->accumulatorPoKCommitmentGroup.modulus); - Bignum r_psi = Bignum::randBignum(params->accumulatorPoKCommitmentGroup.modulus); - Bignum r_sigma = Bignum::randBignum(params->accumulatorPoKCommitmentGroup.modulus); - Bignum r_xi = Bignum::randBignum(params->accumulatorPoKCommitmentGroup.modulus); - - Bignum r_epsilon = Bignum::randBignum((params->accumulatorModulus/4) * Bignum(2).pow(params->k_prime + params->k_dprime)); - if(!(Bignum::randBignum(Bignum(3)) % 2)) { - r_epsilon = 0-r_epsilon; - } - Bignum r_eta = Bignum::randBignum((params->accumulatorModulus/4) * Bignum(2).pow(params->k_prime + params->k_dprime)); - if(!(Bignum::randBignum(Bignum(3)) % 2)) { - r_eta = 0-r_eta; - } - Bignum r_zeta = Bignum::randBignum((params->accumulatorModulus/4) * Bignum(2).pow(params->k_prime + params->k_dprime)); - if(!(Bignum::randBignum(Bignum(3)) % 2)) { - r_zeta = 0-r_zeta; - } - - Bignum r_beta = Bignum::randBignum((params->accumulatorModulus/4) * params->accumulatorPoKCommitmentGroup.modulus * Bignum(2).pow(params->k_prime + params->k_dprime)); - if(!(Bignum::randBignum(Bignum(3)) % 2)) { - r_beta = 0-r_beta; - } - Bignum r_delta = Bignum::randBignum((params->accumulatorModulus/4) * params->accumulatorPoKCommitmentGroup.modulus * Bignum(2).pow(params->k_prime + params->k_dprime)); - if(!(Bignum::randBignum(Bignum(3)) % 2)) { - r_delta = 0-r_delta; - } - - this->st_1 = (sg.pow_mod(r_alpha, params->accumulatorPoKCommitmentGroup.modulus) * sh.pow_mod(r_phi, params->accumulatorPoKCommitmentGroup.modulus)) % params->accumulatorPoKCommitmentGroup.modulus; - this->st_2 = (((commitmentToCoin.getCommitmentValue() * sg.inverse(params->accumulatorPoKCommitmentGroup.modulus)).pow_mod(r_gamma, params->accumulatorPoKCommitmentGroup.modulus)) * sh.pow_mod(r_psi, params->accumulatorPoKCommitmentGroup.modulus)) % params->accumulatorPoKCommitmentGroup.modulus; - this->st_3 = ((sg * commitmentToCoin.getCommitmentValue()).pow_mod(r_sigma, params->accumulatorPoKCommitmentGroup.modulus) * sh.pow_mod(r_xi, params->accumulatorPoKCommitmentGroup.modulus)) % params->accumulatorPoKCommitmentGroup.modulus; - - this->t_1 = (h_n.pow_mod(r_zeta, params->accumulatorModulus) * g_n.pow_mod(r_epsilon, params->accumulatorModulus)) % params->accumulatorModulus; - this->t_2 = (h_n.pow_mod(r_eta, params->accumulatorModulus) * g_n.pow_mod(r_alpha, params->accumulatorModulus)) % params->accumulatorModulus; - this->t_3 = (C_u.pow_mod(r_alpha, params->accumulatorModulus) * ((h_n.inverse(params->accumulatorModulus)).pow_mod(r_beta, params->accumulatorModulus))) % params->accumulatorModulus; - this->t_4 = (C_r.pow_mod(r_alpha, params->accumulatorModulus) * ((h_n.inverse(params->accumulatorModulus)).pow_mod(r_delta, params->accumulatorModulus)) * ((g_n.inverse(params->accumulatorModulus)).pow_mod(r_beta, params->accumulatorModulus))) % params->accumulatorModulus; - - CHashWriter hasher(0,0); - hasher << *params << sg << sh << g_n << h_n << commitmentToCoin.getCommitmentValue() << C_e << C_u << C_r << st_1 << st_2 << st_3 << t_1 << t_2 << t_3 << t_4; - - //According to the proof, this hash should be of length k_prime bits. It is currently greater than that, which should not be a problem, but we should check this. - Bignum c = Bignum(hasher.GetHash()); - - this->s_alpha = r_alpha - c*e; - this->s_beta = r_beta - c*r_2*e; - this->s_zeta = r_zeta - c*r_3; - this->s_sigma = r_sigma - c*((e+1).inverse(params->accumulatorPoKCommitmentGroup.groupOrder)); - this->s_eta = r_eta - c*r_1; - this->s_epsilon = r_epsilon - c*r_2; - this->s_delta = r_delta - c*r_3*e; - this->s_xi = r_xi + c*r*((e+1).inverse(params->accumulatorPoKCommitmentGroup.groupOrder)); - this->s_phi = (r_phi - c*r) % params->accumulatorPoKCommitmentGroup.groupOrder; - this->s_gamma = r_gamma - c*((e-1).inverse(params->accumulatorPoKCommitmentGroup.groupOrder)); - this->s_psi = r_psi + c*r*((e-1).inverse(params->accumulatorPoKCommitmentGroup.groupOrder)); -} - -/** Verifies that a commitment c is accumulated in accumulator a - */ -bool AccumulatorProofOfKnowledge:: Verify(const Accumulator& a, const Bignum& valueOfCommitmentToCoin) const { - Bignum sg = params->accumulatorPoKCommitmentGroup.g; - Bignum sh = params->accumulatorPoKCommitmentGroup.h; - - Bignum g_n = params->accumulatorQRNCommitmentGroup.g; - Bignum h_n = params->accumulatorQRNCommitmentGroup.h; - - //According to the proof, this hash should be of length k_prime bits. It is currently greater than that, which should not be a problem, but we should check this. - CHashWriter hasher(0,0); - hasher << *params << sg << sh << g_n << h_n << valueOfCommitmentToCoin << C_e << C_u << C_r << st_1 << st_2 << st_3 << t_1 << t_2 << t_3 << t_4; - - Bignum c = Bignum(hasher.GetHash()); //this hash should be of length k_prime bits - - Bignum st_1_prime = (valueOfCommitmentToCoin.pow_mod(c, params->accumulatorPoKCommitmentGroup.modulus) * sg.pow_mod(s_alpha, params->accumulatorPoKCommitmentGroup.modulus) * sh.pow_mod(s_phi, params->accumulatorPoKCommitmentGroup.modulus)) % params->accumulatorPoKCommitmentGroup.modulus; - Bignum st_2_prime = (sg.pow_mod(c, params->accumulatorPoKCommitmentGroup.modulus) * ((valueOfCommitmentToCoin * sg.inverse(params->accumulatorPoKCommitmentGroup.modulus)).pow_mod(s_gamma, params->accumulatorPoKCommitmentGroup.modulus)) * sh.pow_mod(s_psi, params->accumulatorPoKCommitmentGroup.modulus)) % params->accumulatorPoKCommitmentGroup.modulus; - Bignum st_3_prime = (sg.pow_mod(c, params->accumulatorPoKCommitmentGroup.modulus) * (sg * valueOfCommitmentToCoin).pow_mod(s_sigma, params->accumulatorPoKCommitmentGroup.modulus) * sh.pow_mod(s_xi, params->accumulatorPoKCommitmentGroup.modulus)) % params->accumulatorPoKCommitmentGroup.modulus; - - Bignum t_1_prime = (C_r.pow_mod(c, params->accumulatorModulus) * h_n.pow_mod(s_zeta, params->accumulatorModulus) * g_n.pow_mod(s_epsilon, params->accumulatorModulus)) % params->accumulatorModulus; - Bignum t_2_prime = (C_e.pow_mod(c, params->accumulatorModulus) * h_n.pow_mod(s_eta, params->accumulatorModulus) * g_n.pow_mod(s_alpha, params->accumulatorModulus)) % params->accumulatorModulus; - Bignum t_3_prime = ((a.getValue()).pow_mod(c, params->accumulatorModulus) * C_u.pow_mod(s_alpha, params->accumulatorModulus) * ((h_n.inverse(params->accumulatorModulus)).pow_mod(s_beta, params->accumulatorModulus))) % params->accumulatorModulus; - Bignum t_4_prime = (C_r.pow_mod(s_alpha, params->accumulatorModulus) * ((h_n.inverse(params->accumulatorModulus)).pow_mod(s_delta, params->accumulatorModulus)) * ((g_n.inverse(params->accumulatorModulus)).pow_mod(s_beta, params->accumulatorModulus))) % params->accumulatorModulus; - - bool result = false; - - bool result_st1 = (st_1 == st_1_prime); - bool result_st2 = (st_2 == st_2_prime); - bool result_st3 = (st_3 == st_3_prime); - - bool result_t1 = (t_1 == t_1_prime); - bool result_t2 = (t_2 == t_2_prime); - bool result_t3 = (t_3 == t_3_prime); - bool result_t4 = (t_4 == t_4_prime); - - bool result_range = ((s_alpha >= -(params->maxCoinValue * Bignum(2).pow(params->k_prime + params->k_dprime + 1))) && (s_alpha <= (params->maxCoinValue * Bignum(2).pow(params->k_prime + params->k_dprime + 1)))); - - result = result_st1 && result_st2 && result_st3 && result_t1 && result_t2 && result_t3 && result_t4 && result_range; - - return result; -} - -} /* namespace libzerocoin */ diff --git a/src/zerocoin/AccumulatorProofOfKnowledge.h b/src/zerocoin/AccumulatorProofOfKnowledge.h deleted file mode 100644 index 4078940..0000000 --- a/src/zerocoin/AccumulatorProofOfKnowledge.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @file AccumulatorProofOfKnowledge.h - * - * @brief AccumulatorProofOfKnowledge class for the Zerocoin library. - * - * @author Ian Miers, Christina Garman and Matthew Green - * @date June 2013 - * - * @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green - * @license This project is released under the MIT license. - **/ - -#ifndef ACCUMULATEPROOF_H_ -#define ACCUMULATEPROOF_H_ - -namespace libzerocoin { - -/**A prove that a value insde the commitment commitmentToCoin is in an accumulator a. - * - */ -class AccumulatorProofOfKnowledge { -public: - AccumulatorProofOfKnowledge(const AccumulatorAndProofParams* p); - - /** Generates a proof that a commitment to a coin c was accumulated - * @param p Cryptographic parameters - * @param commitmentToCoin commitment containing the coin we want to prove is accumulated - * @param witness The witness to the accumulation of the coin - * @param a - */ - AccumulatorProofOfKnowledge(const AccumulatorAndProofParams* p, const Commitment& commitmentToCoin, const AccumulatorWitness& witness, Accumulator& a); - /** Verifies that a commitment c is accumulated in accumulated a - */ - bool Verify(const Accumulator& a,const Bignum& valueOfCommitmentToCoin) const; - - IMPLEMENT_SERIALIZE - ( - READWRITE(C_e); - READWRITE(C_u); - READWRITE(C_r); - READWRITE(st_1); - READWRITE(st_2); - READWRITE(st_3); - READWRITE(t_1); - READWRITE(t_2); - READWRITE(t_3); - READWRITE(t_4); - READWRITE(s_alpha); - READWRITE(s_beta); - READWRITE(s_zeta); - READWRITE(s_sigma); - READWRITE(s_eta); - READWRITE(s_epsilon); - READWRITE(s_delta); - READWRITE(s_xi); - READWRITE(s_phi); - READWRITE(s_gamma); - READWRITE(s_psi); - ) -private: - const AccumulatorAndProofParams* params; - - /* Return values for proof */ - Bignum C_e; - Bignum C_u; - Bignum C_r; - - Bignum st_1; - Bignum st_2; - Bignum st_3; - - Bignum t_1; - Bignum t_2; - Bignum t_3; - Bignum t_4; - - Bignum s_alpha; - Bignum s_beta; - Bignum s_zeta; - Bignum s_sigma; - Bignum s_eta; - Bignum s_epsilon; - Bignum s_delta; - Bignum s_xi; - Bignum s_phi; - Bignum s_gamma; - Bignum s_psi; -}; - -} /* namespace libzerocoin */ -#endif /* ACCUMULATEPROOF_H_ */ diff --git a/src/zerocoin/Coin.cpp b/src/zerocoin/Coin.cpp deleted file mode 100644 index c9aa9a5..0000000 --- a/src/zerocoin/Coin.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/** - * @file Coin.cpp - * - * @brief PublicCoin and PrivateCoin classes for the Zerocoin library. - * - * @author Ian Miers, Christina Garman and Matthew Green - * @date June 2013 - * - * @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green - * @license This project is released under the MIT license. - **/ - -#include -#include "Zerocoin.h" - -namespace libzerocoin { - -//PublicCoin class -PublicCoin::PublicCoin(const Params* p): - params(p), denomination(ZQ_PEDERSEN) { - if(this->params->initialized == false) { - throw std::invalid_argument("Params are not initialized"); - } -}; - -PublicCoin::PublicCoin(const Params* p, const Bignum& coin, const CoinDenomination d): - params(p), value(coin), denomination(d) { - if(this->params->initialized == false) { - throw std::invalid_argument("Params are not initialized"); - } -}; - -bool PublicCoin::operator==(const PublicCoin& rhs) const { - return this->value == rhs.value;// FIXME check param equality -} - -bool PublicCoin::operator!=(const PublicCoin& rhs) const { - return !(*this == rhs); -} - -const Bignum& PublicCoin::getValue() const { - return this->value; -} - -const CoinDenomination PublicCoin::getDenomination() const { - return static_cast(this->denomination); -} - -bool PublicCoin::validate() const { - return (this->params->accumulatorParams.minCoinValue < value) && (value < this->params->accumulatorParams.maxCoinValue) && value.isPrime(params->zkp_iterations); -} - -//PrivateCoin class -PrivateCoin::PrivateCoin(const Params* p, const CoinDenomination denomination): params(p), publicCoin(p) { - // Verify that the parameters are valid - if(this->params->initialized == false) { - throw std::invalid_argument("Params are not initialized"); - } - -#ifdef ZEROCOIN_FAST_MINT - // Mint a new coin with a random serial number using the fast process. - // This is more vulnerable to timing attacks so don't mint coins when - // somebody could be timing you. - this->mintCoinFast(denomination); -#else - // Mint a new coin with a random serial number using the standard process. - this->mintCoin(denomination); -#endif - -} - -/** - * - * @return the coins serial number - */ -const Bignum& PrivateCoin::getSerialNumber() const { - return this->serialNumber; -} - -const Bignum& PrivateCoin::getRandomness() const { - return this->randomness; -} - -void PrivateCoin::mintCoin(const CoinDenomination denomination) { - // Repeat this process up to MAX_COINMINT_ATTEMPTS times until - // we obtain a prime number - for(uint32_t attempt = 0; attempt < MAX_COINMINT_ATTEMPTS; attempt++) { - - // Generate a random serial number in the range 0...{q-1} where - // "q" is the order of the commitment group. - Bignum s = Bignum::randBignum(this->params->coinCommitmentGroup.groupOrder); - - // Generate a Pedersen commitment to the serial number "s" - Commitment coin(¶ms->coinCommitmentGroup, s); - - // Now verify that the commitment is a prime number - // in the appropriate range. If not, we'll throw this coin - // away and generate a new one. - if (coin.getCommitmentValue().isPrime(ZEROCOIN_MINT_PRIME_PARAM) && - coin.getCommitmentValue() >= params->accumulatorParams.minCoinValue && - coin.getCommitmentValue() <= params->accumulatorParams.maxCoinValue) { - // Found a valid coin. Store it. - this->serialNumber = s; - this->randomness = coin.getRandomness(); - this->publicCoin = PublicCoin(params,coin.getCommitmentValue(), denomination); - - // Success! We're done. - return; - } - } - - // We only get here if we did not find a coin within - // MAX_COINMINT_ATTEMPTS. Throw an exception. - throw ZerocoinException("Unable to mint a new Zerocoin (too many attempts)"); -} - -void PrivateCoin::mintCoinFast(const CoinDenomination denomination) { - - // Generate a random serial number in the range 0...{q-1} where - // "q" is the order of the commitment group. - Bignum s = Bignum::randBignum(this->params->coinCommitmentGroup.groupOrder); - - // Generate a random number "r" in the range 0...{q-1} - Bignum r = Bignum::randBignum(this->params->coinCommitmentGroup.groupOrder); - - // Manually compute a Pedersen commitment to the serial number "s" under randomness "r" - // C = g^s * h^r mod p - Bignum commitmentValue = this->params->coinCommitmentGroup.g.pow_mod(s, this->params->coinCommitmentGroup.modulus).mul_mod(this->params->coinCommitmentGroup.h.pow_mod(r, this->params->coinCommitmentGroup.modulus), this->params->coinCommitmentGroup.modulus); - - // Repeat this process up to MAX_COINMINT_ATTEMPTS times until - // we obtain a prime number - for (uint32_t attempt = 0; attempt < MAX_COINMINT_ATTEMPTS; attempt++) { - // First verify that the commitment is a prime number - // in the appropriate range. If not, we'll throw this coin - // away and generate a new one. - if (commitmentValue.isPrime(ZEROCOIN_MINT_PRIME_PARAM) && - commitmentValue >= params->accumulatorParams.minCoinValue && - commitmentValue <= params->accumulatorParams.maxCoinValue) { - // Found a valid coin. Store it. - this->serialNumber = s; - this->randomness = r; - this->publicCoin = PublicCoin(params, commitmentValue, denomination); - - // Success! We're done. - return; - } - - // Generate a new random "r_delta" in 0...{q-1} - Bignum r_delta = Bignum::randBignum(this->params->coinCommitmentGroup.groupOrder); - - // The commitment was not prime. Increment "r" and recalculate "C": - // r = r + r_delta mod q - // C = C * h mod p - r = (r + r_delta) % this->params->coinCommitmentGroup.groupOrder; - commitmentValue = commitmentValue.mul_mod(this->params->coinCommitmentGroup.h.pow_mod(r_delta, this->params->coinCommitmentGroup.modulus), this->params->coinCommitmentGroup.modulus); - } - - // We only get here if we did not find a coin within - // MAX_COINMINT_ATTEMPTS. Throw an exception. - throw ZerocoinException("Unable to mint a new Zerocoin (too many attempts)"); -} - -const PublicCoin& PrivateCoin::getPublicCoin() const { - return this->publicCoin; -} - -} /* namespace libzerocoin */ diff --git a/src/zerocoin/Coin.h b/src/zerocoin/Coin.h deleted file mode 100644 index 09e3caa..0000000 --- a/src/zerocoin/Coin.h +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @file Coin.h - * - * @brief PublicCoin and PrivateCoin classes for the Zerocoin library. - * - * @author Ian Miers, Christina Garman and Matthew Green - * @date June 2013 - * - * @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green - * @license This project is released under the MIT license. - **/ - -#ifndef COIN_H_ -#define COIN_H_ -#include "../bignum.h" -#include "Params.h" -namespace libzerocoin { - -enum CoinDenomination { - ZQ_LOVELACE = 1, - ZQ_GOLDWASSER = 10, - ZQ_RACKOFF = 25, - ZQ_PEDERSEN = 50, - ZQ_WILLIAMSON = 100 // Malcolm J. Williamson, - // the scientist who actually invented - // Public key cryptography -}; - -/** A Public coin is the part of a coin that - * is published to the network and what is handled - * by other clients. It contains only the value - * of commitment to a serial number and the - * denomination of the coin. - */ -class PublicCoin { -public: - template - PublicCoin(const Params* p, Stream& strm): params(p) { - strm >> *this; - } - - PublicCoin( const Params* p); - - /**Generates a public coin - * - * @param p cryptographic paramters - * @param coin the value of the commitment. - * @param denomination The denomination of the coin. Defaults to ZQ_PEDERSEN - */ - PublicCoin( const Params* p, const Bignum& coin, const CoinDenomination d = ZQ_PEDERSEN); - const Bignum& getValue() const; - const CoinDenomination getDenomination() const; - bool operator==(const PublicCoin& rhs) const; - bool operator!=(const PublicCoin& rhs) const; - /** Checks that a coin prime - * and in the appropriate range - * given the parameters - * @return true if valid - */ - bool validate() const; - IMPLEMENT_SERIALIZE - ( - READWRITE(value); - READWRITE(denomination); - ) -private: - const Params* params; - Bignum value; - // Denomination is stored as an INT because storing - // and enum raises amigiuities in the serialize code //FIXME if possible - int denomination; -}; - -/** - * A private coin. As the name implies, the content - * of this should stay private except PublicCoin. - * - * Contains a coin's serial number, a commitment to it, - * and opening randomness for the commitment. - * - * @warning Failure to keep this secret(or safe), - * @warning will result in the theft of your coins - * @warning and a TOTAL loss of anonymity. - */ -class PrivateCoin { -public: - template - PrivateCoin(const Params* p, Stream& strm): params(p) { - strm >> *this; - } - PrivateCoin(const Params* p,const CoinDenomination denomination = ZQ_PEDERSEN); - const PublicCoin& getPublicCoin() const; - const Bignum& getSerialNumber() const; - const Bignum& getRandomness() const; - - IMPLEMENT_SERIALIZE - ( - READWRITE(publicCoin); - READWRITE(randomness); - READWRITE(serialNumber); - ) -private: - const Params* params; - PublicCoin publicCoin; - Bignum randomness; - Bignum serialNumber; - - /** - * @brief Mint a new coin. - * @param denomination the denomination of the coin to mint - * @throws ZerocoinException if the process takes too long - * - * Generates a new Zerocoin by (a) selecting a random serial - * number, (b) committing to this serial number and repeating until - * the resulting commitment is prime. Stores the - * resulting commitment (coin) and randomness (trapdoor). - **/ - void mintCoin(const CoinDenomination denomination); - - /** - * @brief Mint a new coin using a faster process. - * @param denomination the denomination of the coin to mint - * @throws ZerocoinException if the process takes too long - * - * Generates a new Zerocoin by (a) selecting a random serial - * number, (b) committing to this serial number and repeating until - * the resulting commitment is prime. Stores the - * resulting commitment (coin) and randomness (trapdoor). - * This routine is substantially faster than the - * mintCoin() routine, but could be more vulnerable - * to timing attacks. Don't use it if you think someone - * could be timing your coin minting. - **/ - void mintCoinFast(const CoinDenomination denomination); - -}; - -} /* namespace libzerocoin */ -#endif /* COIN_H_ */ diff --git a/src/zerocoin/CoinSpend.cpp b/src/zerocoin/CoinSpend.cpp deleted file mode 100644 index c7890f5..0000000 --- a/src/zerocoin/CoinSpend.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file CoinSpend.cpp - * - * @brief CoinSpend class for the Zerocoin library. - * - * @author Ian Miers, Christina Garman and Matthew Green - * @date June 2013 - * - * @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green - * @license This project is released under the MIT license. - **/ - -#include "Zerocoin.h" - -namespace libzerocoin { - -CoinSpend::CoinSpend(const Params* p, const PrivateCoin& coin, - Accumulator& a, const AccumulatorWitness& witness, const SpendMetaData& m): - params(p), - denomination(coin.getPublicCoin().getDenomination()), - coinSerialNumber((coin.getSerialNumber())), - accumulatorPoK(&p->accumulatorParams), - serialNumberSoK(p), - commitmentPoK(&p->serialNumberSoKCommitmentGroup, &p->accumulatorParams.accumulatorPoKCommitmentGroup) { - - // Sanity check: let's verify that the Witness is valid with respect to - // the coin and Accumulator provided. - if (!(witness.VerifyWitness(a, coin.getPublicCoin()))) { - throw std::invalid_argument("Accumulator witness does not verify"); - } - - // 1: Generate two separate commitments to the public coin (C), each under - // a different set of public parameters. We do this because the RSA accumulator - // has specific requirements for the commitment parameters that are not - // compatible with the group we use for the serial number proof. - // Specifically, our serial number proof requires the order of the commitment group - // to be the same as the modulus of the upper group. The Accumulator proof requires a - // group with a significantly larger order. - const Commitment fullCommitmentToCoinUnderSerialParams(&p->serialNumberSoKCommitmentGroup, coin.getPublicCoin().getValue()); - this->serialCommitmentToCoinValue = fullCommitmentToCoinUnderSerialParams.getCommitmentValue(); - - const Commitment fullCommitmentToCoinUnderAccParams(&p->accumulatorParams.accumulatorPoKCommitmentGroup, coin.getPublicCoin().getValue()); - this->accCommitmentToCoinValue = fullCommitmentToCoinUnderAccParams.getCommitmentValue(); - - // 2. Generate a ZK proof that the two commitments contain the same public coin. - this->commitmentPoK = CommitmentProofOfKnowledge(&p->serialNumberSoKCommitmentGroup, &p->accumulatorParams.accumulatorPoKCommitmentGroup, fullCommitmentToCoinUnderSerialParams, fullCommitmentToCoinUnderAccParams); - - // Now generate the two core ZK proofs: - // 3. Proves that the committed public coin is in the Accumulator (PoK of "witness") - this->accumulatorPoK = AccumulatorProofOfKnowledge(&p->accumulatorParams, fullCommitmentToCoinUnderAccParams, witness, a); - - // 4. Proves that the coin is correct w.r.t. serial number and hidden coin secret - // (This proof is bound to the coin 'metadata', i.e., transaction hash) - this->serialNumberSoK = SerialNumberSignatureOfKnowledge(p, coin, fullCommitmentToCoinUnderSerialParams, signatureHash(m)); -} - -const Bignum& -CoinSpend::getCoinSerialNumber() { - return this->coinSerialNumber; -} - -const CoinDenomination -CoinSpend::getDenomination() { - return static_cast(this->denomination); -} - -bool -CoinSpend::Verify(const Accumulator& a, const SpendMetaData &m) const { - // Verify both of the sub-proofs using the given meta-data - return (a.getDenomination() == this->denomination) - && commitmentPoK.Verify(serialCommitmentToCoinValue, accCommitmentToCoinValue) - && accumulatorPoK.Verify(a, accCommitmentToCoinValue) - && serialNumberSoK.Verify(coinSerialNumber, serialCommitmentToCoinValue, signatureHash(m)); -} - -const uint256 CoinSpend::signatureHash(const SpendMetaData &m) const { - CHashWriter h(0,0); - h << m << serialCommitmentToCoinValue << accCommitmentToCoinValue << commitmentPoK << accumulatorPoK; - return h.GetHash(); -} - -} /* namespace libzerocoin */ diff --git a/src/zerocoin/CoinSpend.h b/src/zerocoin/CoinSpend.h deleted file mode 100644 index 8bf6925..0000000 --- a/src/zerocoin/CoinSpend.h +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @file CoinSpend.h - * - * @brief CoinSpend class for the Zerocoin library. - * - * @author Ian Miers, Christina Garman and Matthew Green - * @date June 2013 - * - * @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green - * @license This project is released under the MIT license. - **/ - -#ifndef COINSPEND_H_ -#define COINSPEND_H_ - -#include "Params.h" -#include "Coin.h" -#include "Commitment.h" -#include "../bignum.h" -#include "Accumulator.h" -#include "AccumulatorProofOfKnowledge.h" -#include "SerialNumberSignatureOfKnowledge.h" -#include "SpendMetaData.h" -#include "../serialize.h" - -namespace libzerocoin { - -/** The complete proof needed to spend a zerocoin. - * Composes together a proof that a coin is accumulated - * and that it has a given serial number. - */ -class CoinSpend { -public: - template - CoinSpend(const Params* p, Stream& strm):denomination(ZQ_PEDERSEN), - accumulatorPoK(&p->accumulatorParams), - serialNumberSoK(p), - commitmentPoK(&p->serialNumberSoKCommitmentGroup, &p->accumulatorParams.accumulatorPoKCommitmentGroup) { - strm >> *this; - } - /**Generates a proof spending a zerocoin. - * - * To use this, provide an unspent PrivateCoin, the latest Accumulator - * (e.g from the most recent Bitcoin block) containing the public part - * of the coin, a witness to that, and whatever medeta data is needed. - * - * Once constructed, this proof can be serialized and sent. - * It is validated simply be calling validate. - * @warning Validation only checks that the proof is correct - * @warning for the specified values in this class. These values must be validated - * Clients ought to check that - * 1) params is the right params - * 2) the accumulator actually is in some block - * 3) that the serial number is unspent - * 4) that the transaction - * - * @param p cryptographic parameters - * @param coin The coin to be spend - * @param a The current accumulator containing the coin - * @param witness The witness showing that the accumulator contains the coin - * @param m arbitrary meta data related to the spend that might be needed by Bitcoin - * (i.e. the transaction hash) - * @throw ZerocoinException if the process fails - */ - CoinSpend(const Params* p, const PrivateCoin& coin, Accumulator& a, const AccumulatorWitness& witness, const SpendMetaData& m); - - /** Returns the serial number of the coin spend by this proof. - * - * @return the coin's serial number - */ - const Bignum& getCoinSerialNumber(); - - /**Gets the denomination of the coin spent in this proof. - * - * @return the denomination - */ - const CoinDenomination getDenomination(); - - bool Verify(const Accumulator& a, const SpendMetaData &metaData) const; - - IMPLEMENT_SERIALIZE - ( - READWRITE(denomination); - READWRITE(accCommitmentToCoinValue); - READWRITE(serialCommitmentToCoinValue); - READWRITE(coinSerialNumber); - READWRITE(accumulatorPoK); - READWRITE(serialNumberSoK); - READWRITE(commitmentPoK); - ) - -private: - const Params *params; - const uint256 signatureHash(const SpendMetaData &m) const; - // Denomination is stored as an INT because storing - // and enum raises amigiuities in the serialize code //FIXME if possible - int denomination; - Bignum accCommitmentToCoinValue; - Bignum serialCommitmentToCoinValue; - Bignum coinSerialNumber; - AccumulatorProofOfKnowledge accumulatorPoK; - SerialNumberSignatureOfKnowledge serialNumberSoK; - CommitmentProofOfKnowledge commitmentPoK; -}; - -} /* namespace libzerocoin */ -#endif /* COINSPEND_H_ */ diff --git a/src/zerocoin/Commitment.cpp b/src/zerocoin/Commitment.cpp deleted file mode 100644 index 50e7fcd..0000000 --- a/src/zerocoin/Commitment.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/** - * @file Commitment.cpp - * - * @brief Commitment and CommitmentProof classes for the Zerocoin library. - * - * @author Ian Miers, Christina Garman and Matthew Green - * @date June 2013 - * - * @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green - * @license This project is released under the MIT license. - **/ - -#include -#include "Zerocoin.h" - -namespace libzerocoin { - -//Commitment class -Commitment::Commitment::Commitment(const IntegerGroupParams* p, - const Bignum& value): params(p), contents(value) { - this->randomness = Bignum::randBignum(params->groupOrder); - this->commitmentValue = (params->g.pow_mod(this->contents, params->modulus).mul_mod( - params->h.pow_mod(this->randomness, params->modulus), params->modulus)); -} - -const Bignum& Commitment::getCommitmentValue() const { - return this->commitmentValue; -} - -const Bignum& Commitment::getRandomness() const { - return this->randomness; -} - -const Bignum& Commitment::getContents() const { - return this->contents; -} - -//CommitmentProofOfKnowledge class -CommitmentProofOfKnowledge::CommitmentProofOfKnowledge(const IntegerGroupParams* ap, const IntegerGroupParams* bp): ap(ap), bp(bp) {} - -// TODO: get parameters from the commitment group -CommitmentProofOfKnowledge::CommitmentProofOfKnowledge(const IntegerGroupParams* aParams, - const IntegerGroupParams* bParams, const Commitment& a, const Commitment& b): - ap(aParams),bp(bParams) -{ - Bignum r1, r2, r3; - - // First: make sure that the two commitments have the - // same contents. - if (a.getContents() != b.getContents()) { - throw std::invalid_argument("Both commitments must contain the same value"); - } - - // Select three random values "r1, r2, r3" in the range 0 to (2^l)-1 where l is: - // length of challenge value + max(modulus 1, modulus 2, order 1, order 2) + margin. - // We set "margin" to be a relatively generous security parameter. - // - // We choose these large values to ensure statistical zero knowledge. - uint32_t randomSize = COMMITMENT_EQUALITY_CHALLENGE_SIZE + COMMITMENT_EQUALITY_SECMARGIN + - std::max(std::max(this->ap->modulus.bitSize(), this->bp->modulus.bitSize()), - std::max(this->ap->groupOrder.bitSize(), this->bp->groupOrder.bitSize())); - Bignum maxRange = (Bignum(2).pow(randomSize) - Bignum(1)); - - r1 = Bignum::randBignum(maxRange); - r2 = Bignum::randBignum(maxRange); - r3 = Bignum::randBignum(maxRange); - - // Generate two random, ephemeral commitments "T1, T2" - // of the form: - // T1 = g1^r1 * h1^r2 mod p1 - // T2 = g2^r1 * h2^r3 mod p2 - // - // Where (g1, h1, p1) are from "aParams" and (g2, h2, p2) are from "bParams". - Bignum T1 = this->ap->g.pow_mod(r1, this->ap->modulus).mul_mod((this->ap->h.pow_mod(r2, this->ap->modulus)), this->ap->modulus); - Bignum T2 = this->bp->g.pow_mod(r1, this->bp->modulus).mul_mod((this->bp->h.pow_mod(r3, this->bp->modulus)), this->bp->modulus); - - // Now hash commitment "A" with commitment "B" as well as the - // parameters and the two ephemeral commitments "T1, T2" we just generated - this->challenge = calculateChallenge(a.getCommitmentValue(), b.getCommitmentValue(), T1, T2); - - // Let "m" be the contents of the commitments "A, B". We have: - // A = g1^m * h1^x mod p1 - // B = g2^m * h2^y mod p2 - // T1 = g1^r1 * h1^r2 mod p1 - // T2 = g2^r1 * h2^r3 mod p2 - // - // Now compute: - // S1 = r1 + (m * challenge) -- note, not modular arithmetic - // S2 = r2 + (x * challenge) -- note, not modular arithmetic - // S3 = r3 + (y * challenge) -- note, not modular arithmetic - this->S1 = r1 + (a.getContents() * this->challenge); - this->S2 = r2 + (a.getRandomness() * this->challenge); - this->S3 = r3 + (b.getRandomness() * this->challenge); - - // We're done. The proof is S1, S2, S3 and "challenge", all of which - // are stored in member variables. -} - -bool CommitmentProofOfKnowledge::Verify(const Bignum& A, const Bignum& B) const -{ - // Compute the maximum range of S1, S2, S3 and verify that the given values are - // in a correct range. This might be an unnecessary check. - uint32_t maxSize = 64 * (COMMITMENT_EQUALITY_CHALLENGE_SIZE + COMMITMENT_EQUALITY_SECMARGIN + - std::max(std::max(this->ap->modulus.bitSize(), this->bp->modulus.bitSize()), - std::max(this->ap->groupOrder.bitSize(), this->bp->groupOrder.bitSize()))); - - if ((uint32_t)this->S1.bitSize() > maxSize || - (uint32_t)this->S2.bitSize() > maxSize || - (uint32_t)this->S3.bitSize() > maxSize || - this->S1 < Bignum(0) || - this->S2 < Bignum(0) || - this->S3 < Bignum(0) || - this->challenge < Bignum(0) || - this->challenge > (Bignum(2).pow(COMMITMENT_EQUALITY_CHALLENGE_SIZE) - Bignum(1))) { - // Invalid inputs. Reject. - return false; - } - - // Compute T1 = g1^S1 * h1^S2 * inverse(A^{challenge}) mod p1 - Bignum T1 = A.pow_mod(this->challenge, ap->modulus).inverse(ap->modulus).mul_mod( - (ap->g.pow_mod(S1, ap->modulus).mul_mod(ap->h.pow_mod(S2, ap->modulus), ap->modulus)), - ap->modulus); - - // Compute T2 = g2^S1 * h2^S3 * inverse(B^{challenge}) mod p2 - Bignum T2 = B.pow_mod(this->challenge, bp->modulus).inverse(bp->modulus).mul_mod( - (bp->g.pow_mod(S1, bp->modulus).mul_mod(bp->h.pow_mod(S3, bp->modulus), bp->modulus)), - bp->modulus); - - // Hash T1 and T2 along with all of the public parameters - Bignum computedChallenge = calculateChallenge(A, B, T1, T2); - - // Return success if the computed challenge matches the incoming challenge - if(computedChallenge == this->challenge) { - return true; - } - - // Otherwise return failure - return false; -} - -const Bignum CommitmentProofOfKnowledge::calculateChallenge(const Bignum& a, const Bignum& b, const Bignum &commitOne, const Bignum &commitTwo) const { - CHashWriter hasher(0,0); - - // Hash together the following elements: - // * A string identifying the proof - // * Commitment A - // * Commitment B - // * Ephemeral commitment T1 - // * Ephemeral commitment T2 - // * A serialized instance of the commitment A parameters - // * A serialized instance of the commitment B parameters - - hasher << std::string(ZEROCOIN_COMMITMENT_EQUALITY_PROOF); - hasher << commitOne; - hasher << std::string("||"); - hasher << commitTwo; - hasher << std::string("||"); - hasher << a; - hasher << std::string("||"); - hasher << b; - hasher << std::string("||"); - hasher << *(this->ap); - hasher << std::string("||"); - hasher << *(this->bp); - - // Convert the SHA256 result into a Bignum - // Note that if we ever change the size of the hash function we will have - // to update COMMITMENT_EQUALITY_CHALLENGE_SIZE appropriately! - return Bignum(hasher.GetHash()); -} - -} /* namespace libzerocoin */ diff --git a/src/zerocoin/Commitment.h b/src/zerocoin/Commitment.h deleted file mode 100644 index d8630a3..0000000 --- a/src/zerocoin/Commitment.h +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file Commitment.h - * - * @brief Commitment and CommitmentProof classes for the Zerocoin library. - * - * @author Ian Miers, Christina Garman and Matthew Green - * @date June 2013 - * - * @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green - * @license This project is released under the MIT license. - **/ - -#ifndef COMMITMENT_H_ -#define COMMITMENT_H_ - -#include "Params.h" -#include "../serialize.h" - -// We use a SHA256 hash for our PoK challenges. Update the following -// if we ever change hash functions. -#define COMMITMENT_EQUALITY_CHALLENGE_SIZE 256 - -// A 512-bit security parameter for the statistical ZK PoK. -#define COMMITMENT_EQUALITY_SECMARGIN 512 - -namespace libzerocoin { - -/** - * A commitment, complete with contents and opening randomness. - * These should remain secret. Publish only the commitment value. - */ -class Commitment { -public: - /**Generates a Pedersen commitment to the given value. - * - * @param p the group parameters for the coin - * @param value the value to commit to - */ - Commitment(const IntegerGroupParams* p, const Bignum& value); - const Bignum& getCommitmentValue() const; - const Bignum& getRandomness() const; - const Bignum& getContents() const; -private: - const IntegerGroupParams *params; - Bignum commitmentValue; - Bignum randomness; - const Bignum contents; - IMPLEMENT_SERIALIZE - ( - READWRITE(commitmentValue); - READWRITE(randomness); - READWRITE(contents); - ) -}; - -/**Proof that two commitments open to the same value. - * - */ -class CommitmentProofOfKnowledge { -public: - CommitmentProofOfKnowledge(const IntegerGroupParams* ap, const IntegerGroupParams* bp); - /** Generates a proof that two commitments, a and b, open to the same value. - * - * @param ap the IntegerGroup for commitment a - * @param bp the IntegerGroup for commitment b - * @param a the first commitment - * @param b the second commitment - */ - CommitmentProofOfKnowledge(const IntegerGroupParams* aParams, const IntegerGroupParams* bParams, const Commitment& a, const Commitment& b); - //FIXME: is it best practice that this is here? - template - CommitmentProofOfKnowledge(const IntegerGroupParams* aParams, - const IntegerGroupParams* bParams, Stream& strm): ap(aParams), bp(bParams) - { - strm >> *this; - } - - const Bignum calculateChallenge(const Bignum& a, const Bignum& b, const Bignum &commitOne, const Bignum &commitTwo) const; - - /**Verifies the proof - * - * @return true if the proof is valid. - */ - /**Verifies the proof of equality of the two commitments - * - * @param A value of commitment one - * @param B value of commitment two - * @return - */ - bool Verify(const Bignum& A, const Bignum& B) const; - IMPLEMENT_SERIALIZE - ( - READWRITE(S1); - READWRITE(S2); - READWRITE(S3); - READWRITE(challenge); - ) -private: - const IntegerGroupParams *ap, *bp; - - Bignum S1, S2, S3, challenge; -}; - -} /* namespace libzerocoin */ -#endif /* COMMITMENT_H_ */ diff --git a/src/zerocoin/ParamGeneration.cpp b/src/zerocoin/ParamGeneration.cpp deleted file mode 100644 index d5bd36b..0000000 --- a/src/zerocoin/ParamGeneration.cpp +++ /dev/null @@ -1,654 +0,0 @@ -/// \file ParamGeneration.cpp -/// -/// \brief Parameter manipulation routines for the Zerocoin cryptographic -/// components. -/// -/// \author Ian Miers, Christina Garman and Matthew Green -/// \date June 2013 -/// -/// \copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green -/// \license This project is released under the MIT license. - -#include -#include "Zerocoin.h" - -using namespace std; - -namespace libzerocoin { - -/// \brief Fill in a set of Zerocoin parameters from a modulus "N". -/// \param N A trusted RSA modulus -/// \param aux An optional auxiliary string used in derivation -/// \param securityLevel A security level -/// -/// \throws ZerocoinException if the process fails -/// -/// Fills in a ZC_Params data structure deterministically from -/// a trustworthy RSA modulus "N", which is provided as a Bignum. -/// -/// Note: this routine makes the fundamental assumption that "N" -/// encodes a valid RSA-style modulus of the form "e1*e2" for some -/// unknown safe primes "e1" and "e2". These factors must not -/// be known to any party, or the security of Zerocoin is -/// compromised. The integer "N" must be a MINIMUM of 1023 -/// in length, and 3072 bits is strongly recommended. -/// - -void -CalculateParams(Params ¶ms, Bignum N, string aux, uint32_t securityLevel) -{ - params.initialized = false; - params.accumulatorParams.initialized = false; - - // Verify that |N| is > 1023 bits. - uint32_t NLen = N.bitSize(); - if (NLen < 1023) { - throw ZerocoinException("Modulus must be at least 1023 bits"); - } - - // Verify that "securityLevel" is at least 80 bits (minimum). - if (securityLevel < 80) { - throw ZerocoinException("Security level must be at least 80 bits."); - } - - // Set the accumulator modulus to "N". - params.accumulatorParams.accumulatorModulus = N; - - // Calculate the required size of the field "F_p" into which - // we're embedding the coin commitment group. This may throw an - // exception if the securityLevel is too large to be supported - // by the current modulus. - uint32_t pLen = 0; - uint32_t qLen = 0; - calculateGroupParamLengths(NLen - 2, securityLevel, &pLen, &qLen); - - // Calculate candidate parameters ("p", "q") for the coin commitment group - // using a deterministic process based on "N", the "aux" string, and - // the dedicated string "COMMITMENTGROUP". - params.coinCommitmentGroup = deriveIntegerGroupParams(calculateSeed(N, aux, securityLevel, STRING_COMMIT_GROUP), - pLen, qLen); - - // Next, we derive parameters for a second Accumulated Value commitment group. - // This is a Schnorr group with the specific property that the order of the group - // must be exactly equal to "q" from the commitment group. We set - // the modulus of the new group equal to "2q+1" and test to see if this is prime. - params.serialNumberSoKCommitmentGroup = deriveIntegerGroupFromOrder(params.coinCommitmentGroup.modulus); - - // Calculate the parameters for the internal commitment - // using the same process. - params.accumulatorParams.accumulatorPoKCommitmentGroup = deriveIntegerGroupParams(calculateSeed(N, aux, securityLevel, STRING_AIC_GROUP), - qLen + 300, qLen + 1); - - // Calculate the parameters for the accumulator QRN commitment generators. This isn't really - // a whole group, just a pair of random generators in QR_N. - uint32_t resultCtr; - params.accumulatorParams.accumulatorQRNCommitmentGroup.g = generateIntegerFromSeed(NLen - 1, - calculateSeed(N, aux, securityLevel, STRING_QRNCOMMIT_GROUPG), - &resultCtr).pow_mod(Bignum(2), N); - params.accumulatorParams.accumulatorQRNCommitmentGroup.h = generateIntegerFromSeed(NLen - 1, - calculateSeed(N, aux, securityLevel, STRING_QRNCOMMIT_GROUPG), - &resultCtr).pow_mod(Bignum(2), N); - - // Calculate the accumulator base, which we calculate as "u = C**2 mod N" - // where C is an arbitrary value. In the unlikely case that "u = 1" we increment - // "C" and repeat. - Bignum constant(ACCUMULATOR_BASE_CONSTANT); - params.accumulatorParams.accumulatorBase = Bignum(1); - for (uint32_t count = 0; count < MAX_ACCUMGEN_ATTEMPTS && params.accumulatorParams.accumulatorBase.isOne(); count++) { - params.accumulatorParams.accumulatorBase = constant.pow_mod(Bignum(2), params.accumulatorParams.accumulatorModulus); - } - - // Compute the accumulator range. The upper range is the largest possible coin commitment value. - // The lower range is sqrt(upper range) + 1. Since OpenSSL doesn't have - // a square root function we use a slightly higher approximation. - params.accumulatorParams.maxCoinValue = params.coinCommitmentGroup.modulus; - params.accumulatorParams.minCoinValue = Bignum(2).pow((params.coinCommitmentGroup.modulus.bitSize() / 2) + 3); - - // If all went well, mark params as successfully initialized. - params.accumulatorParams.initialized = true; - - // If all went well, mark params as successfully initialized. - params.initialized = true; -} - -/// \brief Format a seed string by hashing several values. -/// \param N A Bignum -/// \param aux An auxiliary string -/// \param securityLevel The security level in bits -/// \param groupName A group description string -/// \throws ZerocoinException if the process fails -/// -/// Returns the hash of the value. - -uint256 -calculateGeneratorSeed(uint256 seed, uint256 pSeed, uint256 qSeed, string label, uint32_t index, uint32_t count) -{ - CHashWriter hasher(0,0); - uint256 hash; - - // Compute the hash of: - // ||||||groupName - hasher << seed; - hasher << string("||"); - hasher << pSeed; - hasher << string("||"); - hasher << qSeed; - hasher << string("||"); - hasher << label; - hasher << string("||"); - hasher << index; - hasher << string("||"); - hasher << count; - - return hasher.GetHash(); -} - -/// \brief Format a seed string by hashing several values. -/// \param N A Bignum -/// \param aux An auxiliary string -/// \param securityLevel The security level in bits -/// \param groupName A group description string -/// \throws ZerocoinException if the process fails -/// -/// Returns the hash of the value. - -uint256 -calculateSeed(Bignum modulus, string auxString, uint32_t securityLevel, string groupName) -{ - CHashWriter hasher(0,0); - uint256 hash; - - // Compute the hash of: - // ||||||groupName - hasher << modulus; - hasher << string("||"); - hasher << securityLevel; - hasher << string("||"); - hasher << auxString; - hasher << string("||"); - hasher << groupName; - - return hasher.GetHash(); -} - -uint256 -calculateHash(uint256 input) -{ - CHashWriter hasher(0,0); - - // Compute the hash of "input" - hasher << input; - - return hasher.GetHash(); -} - -/// \brief Calculate field/group parameter sizes based on a security level. -/// \param maxPLen Maximum size of the field (modulus "p") in bits. -/// \param securityLevel Required security level in bits (at least 80) -/// \param pLen Result: length of "p" in bits -/// \param qLen Result: length of "q" in bits -/// \throws ZerocoinException if the process fails -/// -/// Calculates the appropriate sizes of "p" and "q" for a prime-order -/// subgroup of order "q" embedded within a field "F_p". The sizes -/// are based on a 'securityLevel' provided in symmetric-equivalent -/// bits. Our choices slightly exceed the specs in FIPS 186-3: -/// -/// securityLevel = 80: pLen = 1024, qLen = 256 -/// securityLevel = 112: pLen = 2048, qLen = 256 -/// securityLevel = 128: qLen = 3072, qLen = 320 -/// -/// If the length of "p" exceeds the length provided in "maxPLen", or -/// if "securityLevel < 80" this routine throws an exception. - -void -calculateGroupParamLengths(uint32_t maxPLen, uint32_t securityLevel, - uint32_t *pLen, uint32_t *qLen) -{ - *pLen = *qLen = 0; - - if (securityLevel < 80) { - throw ZerocoinException("Security level must be at least 80 bits."); - } else if (securityLevel == 80) { - *qLen = 256; - *pLen = 1024; - } else if (securityLevel <= 112) { - *qLen = 256; - *pLen = 2048; - } else if (securityLevel <= 128) { - *qLen = 320; - *pLen = 3072; - } else { - throw ZerocoinException("Security level not supported."); - } - - if (*pLen > maxPLen) { - throw ZerocoinException("Modulus size is too small for this security level."); - } -} - -/// \brief Deterministically compute a set of group parameters using NIST procedures. -/// \param seedStr A byte string seeding the process. -/// \param pLen The desired length of the modulus "p" in bits -/// \param qLen The desired length of the order "q" in bits -/// \return An IntegerGroupParams object -/// -/// Calculates the description of a group G of prime order "q" embedded within -/// a field "F_p". The input to this routine is in arbitrary seed. It uses the -/// algorithms described in FIPS 186-3 Appendix A.1.2 to calculate -/// primes "p" and "q". It uses the procedure in Appendix A.2.3 to -/// derive two generators "g", "h". - -IntegerGroupParams -deriveIntegerGroupParams(uint256 seed, uint32_t pLen, uint32_t qLen) -{ - IntegerGroupParams result; - Bignum p; - Bignum q; - uint256 pSeed, qSeed; - - // Calculate "p" and "q" and "domain_parameter_seed" from the - // "seed" buffer above, using the procedure described in NIST - // FIPS 186-3, Appendix A.1.2. - calculateGroupModulusAndOrder(seed, pLen, qLen, &(result.modulus), - &(result.groupOrder), &pSeed, &qSeed); - - // Calculate the generators "g", "h" using the process described in - // NIST FIPS 186-3, Appendix A.2.3. This algorithm takes ("p", "q", - // "domain_parameter_seed", "index"). We use "index" value 1 - // to generate "g" and "index" value 2 to generate "h". - result.g = calculateGroupGenerator(seed, pSeed, qSeed, result.modulus, result.groupOrder, 1); - result.h = calculateGroupGenerator(seed, pSeed, qSeed, result.modulus, result.groupOrder, 2); - - // Perform some basic tests to make sure we have good parameters - if ((uint32_t)(result.modulus.bitSize()) < pLen || // modulus is pLen bits long - (uint32_t)(result.groupOrder.bitSize()) < qLen || // order is qLen bits long - !(result.modulus.isPrime()) || // modulus is prime - !(result.groupOrder.isPrime()) || // order is prime - !((result.g.pow_mod(result.groupOrder, result.modulus)).isOne()) || // g^order mod modulus = 1 - !((result.h.pow_mod(result.groupOrder, result.modulus)).isOne()) || // h^order mod modulus = 1 - ((result.g.pow_mod(Bignum(100), result.modulus)).isOne()) || // g^100 mod modulus != 1 - ((result.h.pow_mod(Bignum(100), result.modulus)).isOne()) || // h^100 mod modulus != 1 - result.g == result.h || // g != h - result.g.isOne()) { // g != 1 - // If any of the above tests fail, throw an exception - throw ZerocoinException("Group parameters are not valid"); - } - - return result; -} - -/// \brief Deterministically compute a set of group parameters with a specified order. -/// \param groupOrder The order of the group -/// \return An IntegerGroupParams object -/// -/// Given "q" calculates the description of a group G of prime order "q" embedded within -/// a field "F_p". - -IntegerGroupParams -deriveIntegerGroupFromOrder(Bignum &groupOrder) -{ - IntegerGroupParams result; - - // Set the order to "groupOrder" - result.groupOrder = groupOrder; - - // Try possible values for "modulus" of the form "groupOrder * 2 * i" where - // "p" is prime and i is a counter starting at 1. - for (uint32_t i = 1; i < NUM_SCHNORRGEN_ATTEMPTS; i++) { - // Set modulus equal to "groupOrder * 2 * i" - result.modulus = (result.groupOrder * Bignum(i*2)) + Bignum(1); - - // Test the result for primality - // TODO: This is a probabilistic routine and thus not the right choice - if (result.modulus.isPrime(256)) { - - // Success. - // - // Calculate the generators "g", "h" using the process described in - // NIST FIPS 186-3, Appendix A.2.3. This algorithm takes ("p", "q", - // "domain_parameter_seed", "index"). We use "index" value 1 - // to generate "g" and "index" value 2 to generate "h". - uint256 seed = calculateSeed(groupOrder, "", 128, ""); - uint256 pSeed = calculateHash(seed); - uint256 qSeed = calculateHash(pSeed); - result.g = calculateGroupGenerator(seed, pSeed, qSeed, result.modulus, result.groupOrder, 1); - result.h = calculateGroupGenerator(seed, pSeed, qSeed, result.modulus, result.groupOrder, 2); - - // Perform some basic tests to make sure we have good parameters - if (!(result.modulus.isPrime()) || // modulus is prime - !(result.groupOrder.isPrime()) || // order is prime - !((result.g.pow_mod(result.groupOrder, result.modulus)).isOne()) || // g^order mod modulus = 1 - !((result.h.pow_mod(result.groupOrder, result.modulus)).isOne()) || // h^order mod modulus = 1 - ((result.g.pow_mod(Bignum(100), result.modulus)).isOne()) || // g^100 mod modulus != 1 - ((result.h.pow_mod(Bignum(100), result.modulus)).isOne()) || // h^100 mod modulus != 1 - result.g == result.h || // g != h - result.g.isOne()) { // g != 1 - // If any of the above tests fail, throw an exception - throw ZerocoinException("Group parameters are not valid"); - } - - return result; - } - } - - // If we reached this point group generation has failed. Throw an exception. - throw ZerocoinException("Too many attempts to generate Schnorr group."); -} - -/// \brief Deterministically compute a group description using NIST procedures. -/// \param seed A byte string seeding the process. -/// \param pLen The desired length of the modulus "p" in bits -/// \param qLen The desired length of the order "q" in bits -/// \param resultModulus A value "p" describing a finite field "F_p" -/// \param resultGroupOrder A value "q" describing the order of a subgroup -/// \param resultDomainParameterSeed A resulting seed for use in later calculations. -/// -/// Calculates the description of a group G of prime order "q" embedded within -/// a field "F_p". The input to this routine is in arbitrary seed. It uses the -/// algorithms described in FIPS 186-3 Appendix A.1.2 to calculate -/// primes "p" and "q". - -void -calculateGroupModulusAndOrder(uint256 seed, uint32_t pLen, uint32_t qLen, - Bignum *resultModulus, Bignum *resultGroupOrder, - uint256 *resultPseed, uint256 *resultQseed) -{ - // Verify that the seed length is >= qLen - if (qLen > (sizeof(seed)) * 8) { - // TODO: The use of 256-bit seeds limits us to 256-bit group orders. We should probably change this. - // throw ZerocoinException("Seed is too short to support the required security level."); - } - -#ifdef ZEROCOIN_DEBUG - cout << "calculateGroupModulusAndOrder: pLen = " << pLen << endl; -#endif - - // Generate a random prime for the group order. - // This may throw an exception, which we'll pass upwards. - // Result is the value "resultGroupOrder", "qseed" and "qgen_counter". - uint256 qseed; - uint32_t qgen_counter; - *resultGroupOrder = generateRandomPrime(qLen, seed, &qseed, &qgen_counter); - - // Using ⎡pLen / 2 + 1⎤ as the length and qseed as the input_seed, use the random prime - // routine to obtain p0 , pseed, and pgen_counter. We pass exceptions upward. - uint32_t p0len = ceil((pLen / 2.0) + 1); - uint256 pseed; - uint32_t pgen_counter; - Bignum p0 = generateRandomPrime(p0len, qseed, &pseed, &pgen_counter); - - // Set x = 0, old_counter = pgen_counter - uint32_t old_counter = pgen_counter; - - // Generate a random integer "x" of pLen bits - uint32_t iterations; - Bignum x = generateIntegerFromSeed(pLen, pseed, &iterations); - pseed += (iterations + 1); - - // Set x = 2^{pLen−1} + (x mod 2^{pLen–1}). - Bignum powerOfTwo = Bignum(2).pow(pLen-1); - x = powerOfTwo + (x % powerOfTwo); - - // t = ⎡x / (2 * resultGroupOrder * p0)⎤. - // TODO: we don't have a ceiling function - Bignum t = x / (Bignum(2) * (*resultGroupOrder) * p0); - - // Now loop until we find a valid prime "p" or we fail due to - // pgen_counter exceeding ((4*pLen) + old_counter). - for ( ; pgen_counter <= ((4*pLen) + old_counter) ; pgen_counter++) { - // If (2 * t * resultGroupOrder * p0 + 1) > 2^{pLen}, then - // t = ⎡2^{pLen−1} / (2 * resultGroupOrder * p0)⎤. - powerOfTwo = Bignum(2).pow(pLen); - Bignum prod = (Bignum(2) * t * (*resultGroupOrder) * p0) + Bignum(1); - if (prod > powerOfTwo) { - // TODO: implement a ceil function - t = Bignum(2).pow(pLen-1) / (Bignum(2) * (*resultGroupOrder) * p0); - } - - // Compute a candidate prime resultModulus = 2tqp0 + 1. - *resultModulus = (Bignum(2) * t * (*resultGroupOrder) * p0) + Bignum(1); - - // Verify that resultModulus is prime. First generate a pseudorandom integer "a". - Bignum a = generateIntegerFromSeed(pLen, pseed, &iterations); - pseed += iterations + 1; - - // Set a = 2 + (a mod (resultModulus–3)). - a = Bignum(2) + (a % ((*resultModulus) - Bignum(3))); - - // Set z = a^{2 * t * resultGroupOrder} mod resultModulus - Bignum z = a.pow_mod(Bignum(2) * t * (*resultGroupOrder), (*resultModulus)); - - // If GCD(z–1, resultModulus) == 1 AND (z^{p0} mod resultModulus == 1) - // then we have found our result. Return. - if ((resultModulus->gcd(z - Bignum(1))).isOne() && - (z.pow_mod(p0, (*resultModulus))).isOne()) { - // Success! Return the seeds and primes. - *resultPseed = pseed; - *resultQseed = qseed; - return; - } - - // This prime did not work out. Increment "t" and try again. - t = t + Bignum(1); - } // loop continues until pgen_counter exceeds a limit - - // We reach this point only if we exceeded our maximum iteration count. - // Throw an exception. - throw ZerocoinException("Unable to generate a prime modulus for the group"); -} - -/// \brief Deterministically compute a generator for a given group. -/// \param seed A first seed for the process. -/// \param pSeed A second seed for the process. -/// \param qSeed A third seed for the process. -/// \param modulus Proposed prime modulus for the field. -/// \param groupOrder Proposed order of the group. -/// \param index Index value, selects which generator you're building. -/// \return The resulting generator. -/// \throws A ZerocoinException if error. -/// -/// Generates a random group generator deterministically as a function of (seed,pSeed,qSeed) -/// Uses the algorithm described in FIPS 186-3 Appendix A.2.3. - -Bignum -calculateGroupGenerator(uint256 seed, uint256 pSeed, uint256 qSeed, Bignum modulus, Bignum groupOrder, uint32_t index) -{ - Bignum result; - - // Verify that 0 <= index < 256 - if (index > 255) { - throw ZerocoinException("Invalid index for group generation"); - } - - // Compute e = (modulus - 1) / groupOrder - Bignum e = (modulus - Bignum(1)) / groupOrder; - - // Loop until we find a generator - for (uint32_t count = 1; count < MAX_GENERATOR_ATTEMPTS; count++) { - // hash = Hash(seed || pSeed || qSeed || “ggen” || index || count - uint256 hash = calculateGeneratorSeed(seed, pSeed, qSeed, "ggen", index, count); - Bignum W(hash); - - // Compute result = W^e mod p - result = W.pow_mod(e, modulus); - - // If result > 1, we have a generator - if (result > 1) { - return result; - } - } - - // We only get here if we failed to find a generator - throw ZerocoinException("Unable to find a generator, too many attempts"); -} - -/// \brief Deterministically compute a random prime number. -/// \param primeBitLen Desired bit length of the prime. -/// \param in_seed Input seed for the process. -/// \param out_seed Result: output seed from the process. -/// \param prime_gen_counter Result: number of iterations required. -/// \return The resulting prime number. -/// \throws A ZerocoinException if error. -/// -/// Generates a random prime number of primeBitLen bits from a given input -/// seed. Uses the Shawe-Taylor algorithm as described in FIPS 186-3 -/// Appendix C.6. This is a recursive function. - -Bignum -generateRandomPrime(uint32_t primeBitLen, uint256 in_seed, uint256 *out_seed, - uint32_t *prime_gen_counter) -{ - // Verify that primeBitLen is not too small - if (primeBitLen < 2) { - throw ZerocoinException("Prime length is too short"); - } - - // If primeBitLen < 33 bits, perform the base case. - if (primeBitLen < 33) { - Bignum result(0); - - // Set prime_seed = in_seed, prime_gen_counter = 0. - uint256 prime_seed = in_seed; - (*prime_gen_counter) = 0; - - // Loop up to "4 * primeBitLen" iterations. - while ((*prime_gen_counter) < (4 * primeBitLen)) { - - // Generate a pseudorandom integer "c" of length primeBitLength bits - uint32_t iteration_count; - Bignum c = generateIntegerFromSeed(primeBitLen, prime_seed, &iteration_count); -#ifdef ZEROCOIN_DEBUG - cout << "generateRandomPrime: primeBitLen = " << primeBitLen << endl; - cout << "Generated c = " << c << endl; -#endif - - prime_seed += (iteration_count + 1); - (*prime_gen_counter)++; - - // Set "intc" to be the least odd integer >= "c" we just generated - uint32_t intc = c.getulong(); - intc = (2 * floor(intc / 2.0)) + 1; -#ifdef ZEROCOIN_DEBUG - cout << "Should be odd. c = " << intc << endl; - cout << "The big num is: c = " << c << endl; -#endif - - // Perform trial division on this (relatively small) integer to determine if "intc" - // is prime. If so, return success. - if (primalityTestByTrialDivision(intc)) { - // Return "intc" converted back into a Bignum and "prime_seed". We also updated - // the variable "prime_gen_counter" in previous statements. - result = intc; - *out_seed = prime_seed; - - // Success - return result; - } - } // while() - - // If we reached this point there was an error finding a candidate prime - // so throw an exception. - throw ZerocoinException("Unable to find prime in Shawe-Taylor algorithm"); - - // END OF BASE CASE - } - // If primeBitLen >= 33 bits, perform the recursive case. - else { - // Recurse to find a new random prime of roughly half the size - uint32_t newLength = ceil((double)primeBitLen / 2.0) + 1; - Bignum c0 = generateRandomPrime(newLength, in_seed, out_seed, prime_gen_counter); - - // Generate a random integer "x" of primeBitLen bits using the output - // of the previous call. - uint32_t numIterations; - Bignum x = generateIntegerFromSeed(primeBitLen, *out_seed, &numIterations); - (*out_seed) += numIterations + 1; - - // Compute "t" = ⎡x / (2 * c0⎤ - // TODO no Ceiling call - Bignum t = x / (Bignum(2) * c0); - - // Repeat the following procedure until we find a prime (or time out) - for (uint32_t testNum = 0; testNum < MAX_PRIMEGEN_ATTEMPTS; testNum++) { - - // If ((2 * t * c0) + 1 > 2^{primeBitLen}), - // then t = ⎡2^{primeBitLen} – 1 / (2 * c0)⎤. - if ((Bignum(2) * t * c0) > (Bignum(2).pow(Bignum(primeBitLen)))) { - t = ((Bignum(2).pow(Bignum(primeBitLen))) - Bignum(1)) / (Bignum(2) * c0); - } - - // Set c = (2 * t * c0) + 1 - Bignum c = (Bignum(2) * t * c0) + Bignum(1); - - // Increment prime_gen_counter - (*prime_gen_counter)++; - - // Test "c" for primality as follows: - // 1. First pick an integer "a" in between 2 and (c - 2) - Bignum a = generateIntegerFromSeed(c.bitSize(), (*out_seed), &numIterations); - a = Bignum(2) + (a % (c - Bignum(3))); - (*out_seed) += (numIterations + 1); - - // 2. Compute "z" = a^{2*t} mod c - Bignum z = a.pow_mod(Bignum(2) * t, c); - - // 3. Check if "c" is prime. - // Specifically, verify that gcd((z-1), c) == 1 AND (z^c0 mod c) == 1 - // If so we return "c" as our result. - if (c.gcd(z - Bignum(1)).isOne() && z.pow_mod(c0, c).isOne()) { - // Return "c", out_seed and prime_gen_counter - // (the latter two of which were already updated) - return c; - } - - // 4. If the test did not succeed, increment "t" and loop - t = t + Bignum(1); - } // end of test loop - } - - // We only reach this point if the test loop has iterated MAX_PRIMEGEN_ATTEMPTS - // and failed to identify a valid prime. Throw an exception. - throw ZerocoinException("Unable to generate random prime (too many tests)"); -} - -Bignum -generateIntegerFromSeed(uint32_t numBits, uint256 seed, uint32_t *numIterations) -{ - Bignum result(0); - uint32_t iterations = ceil((double)numBits / (double)HASH_OUTPUT_BITS); - -#ifdef ZEROCOIN_DEBUG - cout << "numBits = " << numBits << endl; - cout << "iterations = " << iterations << endl; -#endif - - // Loop "iterations" times filling up the value "result" with random bits - for (uint32_t count = 0; count < iterations; count++) { - // result += ( H(pseed + count) * 2^{count * p0len} ) - result += Bignum(calculateHash(seed + count)) * Bignum(2).pow(count * HASH_OUTPUT_BITS); - } - - result = Bignum(2).pow(numBits - 1) + (result % (Bignum(2).pow(numBits - 1))); - - // Return the number of iterations and the result - *numIterations = iterations; - return result; -} - -/// \brief Determines whether a uint32_t is a prime through trial division. -/// \param candidate Candidate to test. -/// \return true if the value is prime, false otherwise -/// -/// Performs trial division to determine whether a uint32_t is prime. - -bool -primalityTestByTrialDivision(uint32_t candidate) -{ - // TODO: HACK HACK WRONG WRONG - Bignum canBignum(candidate); - - return canBignum.isPrime(); -} - -} // namespace libzerocoin diff --git a/src/zerocoin/ParamGeneration.h b/src/zerocoin/ParamGeneration.h deleted file mode 100644 index de2d452..0000000 --- a/src/zerocoin/ParamGeneration.h +++ /dev/null @@ -1,53 +0,0 @@ -/// \file ParamGeneration.h -/// -/// \brief Parameter generation routines for Zerocoin. -/// -/// \author Ian Miers, Christina Garman and Matthew Green -/// \date June 2013 -/// -/// \copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green -/// \license This project is released under the MIT license. - -#ifndef PARAMGENERATION_H_ -#define PARAMGENERATION_H_ - -namespace libzerocoin { - -void CalculateParams(Params ¶ms, Bignum N, std::string aux, uint32_t securityLevel); -void calculateGroupParamLengths(uint32_t maxPLen, uint32_t securityLevel, - uint32_t *pLen, uint32_t *qLen); - -// Constants -#define STRING_COMMIT_GROUP "COIN_COMMITMENT_GROUP" -#define STRING_AVC_GROUP "ACCUMULATED_VALUE_COMMITMENT_GROUP" -#define STRING_AVC_ORDER "ACCUMULATED_VALUE_COMMITMENT_ORDER" -#define STRING_AIC_GROUP "ACCUMULATOR_INTERNAL_COMMITMENT_GROUP" -#define STRING_QRNCOMMIT_GROUPG "ACCUMULATOR_QRN_COMMITMENT_GROUPG" -#define STRING_QRNCOMMIT_GROUPH "ACCUMULATOR_QRN_COMMITMENT_GROUPH" -#define ACCUMULATOR_BASE_CONSTANT 31 -#define MAX_PRIMEGEN_ATTEMPTS 10000 -#define MAX_ACCUMGEN_ATTEMPTS 10000 -#define MAX_GENERATOR_ATTEMPTS 10000 -#define NUM_SCHNORRGEN_ATTEMPTS 10000 - -// Prototypes -bool primalityTestByTrialDivision(uint32_t candidate); -uint256 calculateSeed(Bignum modulus, std::string auxString, uint32_t securityLevel, std::string groupName); -uint256 calculateGeneratorSeed(uint256 seed, uint256 pSeed, uint256 qSeed, std::string label, uint32_t index, uint32_t count); - -uint256 calculateHash(uint256 input); -IntegerGroupParams deriveIntegerGroupParams(uint256 seed, uint32_t pLen, uint32_t qLen); -IntegerGroupParams deriveIntegerGroupFromOrder(Bignum &groupOrder); -void calculateGroupModulusAndOrder(uint256 seed, uint32_t pLen, uint32_t qLen, - Bignum *resultModulus, Bignum *resultGroupOrder, - uint256 *resultPseed, uint256 *resultQseed); -Bignum calculateGroupGenerator(uint256 seed, uint256 pSeed, uint256 qSeed, Bignum modulus, - Bignum groupOrder, uint32_t index); -Bignum generateRandomPrime(uint32_t primeBitLen, uint256 in_seed, uint256 *out_seed, - uint32_t *prime_gen_counter); -Bignum generateIntegerFromSeed(uint32_t numBits, uint256 seed, uint32_t *numIterations); -bool primalityTestByTrialDivision(uint32_t candidate); - -}/* namespace libzerocoin */ - -#endif /* PARAMGENERATION_H_ */ diff --git a/src/zerocoin/Params.cpp b/src/zerocoin/Params.cpp deleted file mode 100644 index c275044..0000000 --- a/src/zerocoin/Params.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/** -* @file Params.cpp -* -* @brief Parameter class for Zerocoin. -* -* @author Ian Miers, Christina Garman and Matthew Green -* @date June 2013 -* -* @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green -* @license This project is released under the MIT license. -**/ -#include "Zerocoin.h" - -namespace libzerocoin { - -Params::Params(Bignum N, uint32_t securityLevel) { - this->zkp_hash_len = securityLevel; - this->zkp_iterations = securityLevel; - - this->accumulatorParams.k_prime = ACCPROOF_KPRIME; - this->accumulatorParams.k_dprime = ACCPROOF_KDPRIME; - - // Generate the parameters - CalculateParams(*this, N, ZEROCOIN_PROTOCOL_VERSION, securityLevel); - - this->accumulatorParams.initialized = true; - this->initialized = true; -} - -AccumulatorAndProofParams::AccumulatorAndProofParams() { - this->initialized = false; -} - -IntegerGroupParams::IntegerGroupParams() { - this->initialized = false; -} - -Bignum IntegerGroupParams::randomElement() const { - // The generator of the group raised - // to a random number less than the order of the group - // provides us with a uniformly distributed random number. - return this->g.pow_mod(Bignum::randBignum(this->groupOrder),this->modulus); -} - -} /* namespace libzerocoin */ diff --git a/src/zerocoin/Params.h b/src/zerocoin/Params.h deleted file mode 100644 index 60a5af4..0000000 --- a/src/zerocoin/Params.h +++ /dev/null @@ -1,216 +0,0 @@ -/** -* @file Params.h -* -* @brief Parameter classes for Zerocoin. -* -* @author Ian Miers, Christina Garman and Matthew Green -* @date June 2013 -* -* @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green -* @license This project is released under the MIT license. -**/ -#ifndef PARAMS_H_ -#define PARAMS_H_ - -namespace libzerocoin { - -class IntegerGroupParams { -public: - /** @brief Integer group class, default constructor - * - * Allocates an empty (uninitialized) set of parameters. - **/ - IntegerGroupParams(); - - /** - * Generates a random group element - * @return a random element in the group. - */ - Bignum randomElement() const; - bool initialized; - - /** - * A generator for the group. - */ - Bignum g; - - /** - * A second generator for the group. - * Note log_g(h) and log_h(g) must - * be unknown. - */ - Bignum h; - - /** - * The modulus for the group. - */ - Bignum modulus; - - /** - * The order of the group - */ - Bignum groupOrder; - - IMPLEMENT_SERIALIZE - ( - READWRITE(initialized); - READWRITE(g); - READWRITE(h); - READWRITE(modulus); - READWRITE(groupOrder); - ) -}; - -class AccumulatorAndProofParams { -public: - /** @brief Construct a set of Zerocoin parameters from a modulus "N". - * @param N A trusted RSA modulus - * @param securityLevel A security level expressed in symmetric bits (default 80) - * - * Allocates and derives a set of Zerocoin parameters from - * a trustworthy RSA modulus "N". This routine calculates all - * of the remaining parameters (group descriptions etc.) from N - * using a verifiable, deterministic procedure. - * - * Note: this constructor makes the fundamental assumption that "N" - * encodes a valid RSA-style modulus of the form "e1 * e2" where - * "e1" and "e2" are safe primes. The factors "e1", "e2" MUST NOT - * be known to any party, or the security of Zerocoin is - * compromised. The integer "N" must be a MINIMUM of 1024 - * in length. 3072 bits is strongly recommended. - **/ - AccumulatorAndProofParams(); - - //AccumulatorAndProofParams(Bignum accumulatorModulus); - - bool initialized; - - /** - * Modulus used for the accumulator. - * Product of two safe primes who's factorization is unknown. - */ - Bignum accumulatorModulus; - - /** - * The initial value for the accumulator - * A random Quadratic residue mod n thats not 1 - */ - Bignum accumulatorBase; - - /** - * Lower bound on the value for committed coin. - * Required by the accumulator proof. - */ - Bignum minCoinValue; - - /** - * Upper bound on the value for a comitted coin. - * Required by the accumulator proof. - */ - Bignum maxCoinValue; - - /** - * The second of two groups used to form a commitment to - * a coin (which it self is a commitment to a serial number). - * This one differs from serialNumberSokCommitment due to - * restrictions from Camenisch and Lysyanskaya's paper. - */ - IntegerGroupParams accumulatorPoKCommitmentGroup; - - /** - * Hidden order quadratic residue group mod N. - * Used in the accumulator proof. - */ - IntegerGroupParams accumulatorQRNCommitmentGroup; - - /** - * Security parameter. - * Bit length of the challenges used in the accumulator proof. - */ - uint32_t k_prime; - - /** - * Security parameter. - * The statistical zero-knowledgeness of the accumulator proof. - */ - uint32_t k_dprime; - - IMPLEMENT_SERIALIZE - ( - READWRITE(initialized); - READWRITE(accumulatorModulus); - READWRITE(accumulatorBase); - READWRITE(accumulatorPoKCommitmentGroup); - READWRITE(accumulatorQRNCommitmentGroup); - READWRITE(minCoinValue); - READWRITE(maxCoinValue); - READWRITE(k_prime); - READWRITE(k_dprime); - ) -}; - -class Params { -public: - /** @brief Construct a set of Zerocoin parameters from a modulus "N". - * @param N A trusted RSA modulus - * @param securityLevel A security level expressed in symmetric bits (default 80) - * - * Allocates and derives a set of Zerocoin parameters from - * a trustworthy RSA modulus "N". This routine calculates all - * of the remaining parameters (group descriptions etc.) from N - * using a verifiable, deterministic procedure. - * - * Note: this constructor makes the fundamental assumption that "N" - * encodes a valid RSA-style modulus of the form "e1 * e2" where - * "e1" and "e2" are safe primes. The factors "e1", "e2" MUST NOT - * be known to any party, or the security of Zerocoin is - * compromised. The integer "N" must be a MINIMUM of 1024 - * in length. 3072 bits is strongly recommended. - **/ - Params(Bignum accumulatorModulus, - uint32_t securityLevel = ZEROCOIN_DEFAULT_SECURITYLEVEL); - - bool initialized; - - AccumulatorAndProofParams accumulatorParams; - - /** - * The Quadratic Residue group from which we form - * a coin as a commitment to a serial number. - */ - IntegerGroupParams coinCommitmentGroup; - - /** - * One of two groups used to form a commitment to - * a coin (which it self is a commitment to a serial number). - * This is the one used in the serial number poof. - * It's order must be equal to the modulus of coinCommitmentGroup. - */ - IntegerGroupParams serialNumberSoKCommitmentGroup; - - /** - * The number of iterations to use in the serial - * number proof. - */ - uint32_t zkp_iterations; - - /** - * The amount of the hash function we use for - * proofs. - */ - uint32_t zkp_hash_len; - - IMPLEMENT_SERIALIZE - ( - READWRITE(initialized); - READWRITE(accumulatorParams); - READWRITE(coinCommitmentGroup); - READWRITE(serialNumberSoKCommitmentGroup); - READWRITE(zkp_iterations); - READWRITE(zkp_hash_len); - ) -}; - -} /* namespace libzerocoin */ - -#endif /* PARAMS_H_ */ diff --git a/src/zerocoin/SerialNumberSignatureOfKnowledge.cpp b/src/zerocoin/SerialNumberSignatureOfKnowledge.cpp deleted file mode 100644 index 1654c50..0000000 --- a/src/zerocoin/SerialNumberSignatureOfKnowledge.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/** -* @file SerialNumberSignatureOfKnowledge.cpp -* -* @brief SerialNumberSignatureOfKnowledge class for the Zerocoin library. -* -* @author Ian Miers, Christina Garman and Matthew Green -* @date June 2013 -* -* @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green -* @license This project is released under the MIT license. -**/ - -#include "Zerocoin.h" - -namespace libzerocoin { - -SerialNumberSignatureOfKnowledge::SerialNumberSignatureOfKnowledge(const Params* p): params(p) { } - -SerialNumberSignatureOfKnowledge::SerialNumberSignatureOfKnowledge(const - Params* p, const PrivateCoin& coin, const Commitment& commitmentToCoin, - uint256 msghash):params(p), - s_notprime(p->zkp_iterations), - sprime(p->zkp_iterations) { - - // Sanity check: verify that the order of the "accumulatedValueCommitmentGroup" is - // equal to the modulus of "coinCommitmentGroup". Otherwise we will produce invalid - // proofs. - if (params->coinCommitmentGroup.modulus != params->serialNumberSoKCommitmentGroup.groupOrder) { - throw ZerocoinException("Groups are not structured correctly."); - } - - Bignum a = params->coinCommitmentGroup.g; - Bignum b = params->coinCommitmentGroup.h; - Bignum g = params->serialNumberSoKCommitmentGroup.g; - Bignum h = params->serialNumberSoKCommitmentGroup.h; - - CHashWriter hasher(0,0); - hasher << *params << commitmentToCoin.getCommitmentValue() << coin.getSerialNumber(); - - vector r(params->zkp_iterations); - vector v(params->zkp_iterations); - vector c(params->zkp_iterations); - - - for(uint32_t i=0; i < params->zkp_iterations; i++) { - //FIXME we really ought to use one BN_CTX for all of these - // operations for performance reasons, not the one that - // is created individually by the wrapper - r[i] = Bignum::randBignum(params->coinCommitmentGroup.groupOrder); - v[i] = Bignum::randBignum(params->serialNumberSoKCommitmentGroup.groupOrder); - } - - // Openssl's rng is not thread safe, so we don't call it in a parallel loop, - // instead we generate the random values beforehand and run the calculations - // based on those values in parallel. -#ifdef ZEROCOIN_THREADING - #pragma omp parallel for -#endif - for(uint32_t i=0; i < params->zkp_iterations; i++) { - // compute g^{ {a^x b^r} h^v} mod p2 - c[i] = challengeCalculation(coin.getSerialNumber(), r[i], v[i]); - } - - // We can't hash data in parallel either - // because OPENMP cannot not guarantee loops - // execute in order. - for(uint32_t i=0; i < params->zkp_iterations; i++) { - hasher << c[i]; - } - this->hash = hasher.GetHash(); - unsigned char *hashbytes = (unsigned char*) &hash; - -#ifdef ZEROCOIN_THREADING - #pragma omp parallel for -#endif - for(uint32_t i = 0; i < params->zkp_iterations; i++) { - int bit = i % 8; - int byte = i / 8; - - bool challenge_bit = ((hashbytes[byte] >> bit) & 0x01); - if (challenge_bit) { - s_notprime[i] = r[i]; - sprime[i] = v[i]; - } else { - s_notprime[i] = r[i] - coin.getRandomness(); - sprime[i] = v[i] - (commitmentToCoin.getRandomness() * - b.pow_mod(r[i] - coin.getRandomness(), params->serialNumberSoKCommitmentGroup.groupOrder)); - } - } -} - -inline Bignum SerialNumberSignatureOfKnowledge::challengeCalculation(const Bignum& a_exp,const Bignum& b_exp, - const Bignum& h_exp) const { - - Bignum a = params->coinCommitmentGroup.g; - Bignum b = params->coinCommitmentGroup.h; - Bignum g = params->serialNumberSoKCommitmentGroup.g; - Bignum h = params->serialNumberSoKCommitmentGroup.h; - - Bignum exponent = (a.pow_mod(a_exp, params->serialNumberSoKCommitmentGroup.groupOrder) - * b.pow_mod(b_exp, params->serialNumberSoKCommitmentGroup.groupOrder)) % params->serialNumberSoKCommitmentGroup.groupOrder; - - return (g.pow_mod(exponent, params->serialNumberSoKCommitmentGroup.modulus) * h.pow_mod(h_exp, params->serialNumberSoKCommitmentGroup.modulus)) % params->serialNumberSoKCommitmentGroup.modulus; -} - -bool SerialNumberSignatureOfKnowledge::Verify(const Bignum& coinSerialNumber, const Bignum& valueOfCommitmentToCoin, - const uint256 msghash) const { - Bignum a = params->coinCommitmentGroup.g; - Bignum b = params->coinCommitmentGroup.h; - Bignum g = params->serialNumberSoKCommitmentGroup.g; - Bignum h = params->serialNumberSoKCommitmentGroup.h; - CHashWriter hasher(0,0); - hasher << *params << valueOfCommitmentToCoin < tprime(params->zkp_iterations); - unsigned char *hashbytes = (unsigned char*) &this->hash; -#ifdef ZEROCOIN_THREADING - #pragma omp parallel for -#endif - for(uint32_t i = 0; i < params->zkp_iterations; i++) { - int bit = i % 8; - int byte = i / 8; - bool challenge_bit = ((hashbytes[byte] >> bit) & 0x01); - if(challenge_bit) { - tprime[i] = challengeCalculation(coinSerialNumber, s_notprime[i], sprime[i]); - } else { - Bignum exp = b.pow_mod(s_notprime[i], params->serialNumberSoKCommitmentGroup.groupOrder); - tprime[i] = ((valueOfCommitmentToCoin.pow_mod(exp, params->serialNumberSoKCommitmentGroup.modulus) % params->serialNumberSoKCommitmentGroup.modulus) * - (h.pow_mod(sprime[i], params->serialNumberSoKCommitmentGroup.modulus) % params->serialNumberSoKCommitmentGroup.modulus)) % - params->serialNumberSoKCommitmentGroup.modulus; - } - } - for(uint32_t i = 0; i < params->zkp_iterations; i++) { - hasher << tprime[i]; - } - return hasher.GetHash() == hash; -} - -} /* namespace libzerocoin */ diff --git a/src/zerocoin/SerialNumberSignatureOfKnowledge.h b/src/zerocoin/SerialNumberSignatureOfKnowledge.h deleted file mode 100644 index 3177618..0000000 --- a/src/zerocoin/SerialNumberSignatureOfKnowledge.h +++ /dev/null @@ -1,75 +0,0 @@ -/** -* @file SerialNumberSignatureOfKnowledge.h -* -* @brief SerialNumberSignatureOfKnowledge class for the Zerocoin library. -* -* @author Ian Miers, Christina Garman and Matthew Green -* @date June 2013 -* -* @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green -* @license This project is released under the MIT license. -**/ - -#ifndef SERIALNUMBERPROOF_H_ -#define SERIALNUMBERPROOF_H_ - -#include -#include -#include -#include "Params.h" -#include "Coin.h" -#include "Commitment.h" -#include "../bignum.h" -#include "../serialize.h" -#include "Accumulator.h" -#include "../util.h" - -using namespace std; -namespace libzerocoin { - -/**A Signature of knowledge on the hash of metadata attesting that the signer knows the values - * necessary to open a commitment which contains a coin(which it self is of course a commitment) - * with a given serial number. - */ -class SerialNumberSignatureOfKnowledge { -public: - SerialNumberSignatureOfKnowledge(const Params* p); - /** Creates a Signature of knowledge object that a commitment to a coin contains a coin with serial number x - * - * @param p params - * @param coin the coin we are going to prove the serial number of. - * @param commitmentToCoin the commitment to the coin - * @param msghash hash of meta data to create a signature of knowledge on. - */ - SerialNumberSignatureOfKnowledge(const Params* p, const PrivateCoin& coin, const Commitment& commitmentToCoin, uint256 msghash); - - /** Verifies the Signature of knowledge. - * - * @param msghash hash of meta data to create a signature of knowledge on. - * @return - */ - bool Verify(const Bignum& coinSerialNumber, const Bignum& valueOfCommitmentToCoin,const uint256 msghash) const; - - IMPLEMENT_SERIALIZE - ( - READWRITE(s_notprime); - READWRITE(sprime); - READWRITE(hash); - ) -private: - const Params* params; - // challenge hash - uint256 hash; //TODO For efficiency, should this be a bitset where Templates define params? - - // challenge response values - // this is s_notprime instead of s - // because the serialization macros - // define something named s and it conflicts - vector s_notprime; - vector sprime; - inline Bignum challengeCalculation(const Bignum& a_exp, const Bignum& b_exp, - const Bignum& h_exp) const; -}; - -} /* namespace libzerocoin */ -#endif /* SERIALNUMBERPROOF_H_ */ diff --git a/src/zerocoin/SpendMetaData.cpp b/src/zerocoin/SpendMetaData.cpp deleted file mode 100644 index 83d5619..0000000 --- a/src/zerocoin/SpendMetaData.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/** -* @file SpendMetaData.cpp -* -* @brief SpendMetaData class for the Zerocoin library. -* -* @author Ian Miers, Christina Garman and Matthew Green -* @date June 2013 -* -* @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green -* @license This project is released under the MIT license. -**/ - -#include "Zerocoin.h" - -namespace libzerocoin { - -SpendMetaData::SpendMetaData(uint256 accumulatorId, uint256 txHash): accumulatorId(accumulatorId), txHash(txHash) {} - -} /* namespace libzerocoin */ diff --git a/src/zerocoin/SpendMetaData.h b/src/zerocoin/SpendMetaData.h deleted file mode 100644 index 855d8f9..0000000 --- a/src/zerocoin/SpendMetaData.h +++ /dev/null @@ -1,52 +0,0 @@ -/** -* @file SpendMetaData.h -* -* @brief SpendMetaData class for the Zerocoin library. -* -* @author Ian Miers, Christina Garman and Matthew Green -* @date June 2013 -* -* @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green -* @license This project is released under the MIT license. -**/ - -#ifndef SPENDMETADATA_H_ -#define SPENDMETADATA_H_ - -#include "../uint256.h" -#include "../serialize.h" - -using namespace std; -namespace libzerocoin { - -/** Any meta data needed for actual bitcoin integration. - * Can extended provided the getHash() function is updated - */ -class SpendMetaData { -public: - /** - * Creates meta data associated with a coin spend - * @param accumulatorId hash of block containing accumulator - * @param txHash hash of transaction - */ - SpendMetaData(uint256 accumulatorId, uint256 txHash); - - /** - * The hash of the block containing the accumulator CoinSpend - * proves membership in. - */ - uint256 accumulatorId; // The block the accumulator is in - /**Contains the hash of the rest of transaction - * spending a zerocoin (excluding the coinspend proof) - */ - uint256 txHash; // The Hash of the rest of the transaction the spend proof is n. - // Allows us to sign the transaction. - IMPLEMENT_SERIALIZE - ( - READWRITE(accumulatorId); - READWRITE(txHash); - ) -}; - -} /* namespace libzerocoin */ -#endif /* SPENDMETADATA_H_ */ diff --git a/src/zerocoin/ZeroTest.cpp b/src/zerocoin/ZeroTest.cpp deleted file mode 100644 index f00f0c5..0000000 --- a/src/zerocoin/ZeroTest.cpp +++ /dev/null @@ -1,421 +0,0 @@ -/** -* @file Tests.cpp -* -* @brief Test routines for Zerocoin. -* -* @author Ian Miers, Christina Garman and Matthew Green -* @date June 2013 -* -* @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green -* @license This project is released under the MIT license. -**/ - -using namespace std; - -#include -#include -#include -#include -#include "Zerocoin.h" -#include "../util.h" - -using namespace libzerocoin; -extern Params* ZCParams; - - -#define TESTS_COINS_TO_ACCUMULATE 10 - -// Global test counters -uint32_t gNumTests = 0; -uint32_t gSuccessfulTests = 0; - -// Proof size -uint32_t gProofSize = 0; -uint32_t gCoinSize = 0; -uint32_t gSerialNumberSize = 0; - -// Global coin array -PrivateCoin *gCoins[TESTS_COINS_TO_ACCUMULATE]; - -// Global params -Params *g_Params; - -////////// -// Utility routines -////////// - -void -LogTestResult(string testName, bool (*testPtr)()) -{ - printf("Testing if %s ...\n", testName.c_str()); - - bool testResult = testPtr(); - - if (testResult == true) { - printf("\t[PASS]\n"); - gSuccessfulTests++; - } else { - printf("\t[FAIL]\n"); - } - - gNumTests++; -} - -Bignum -GetTestModulus() -{ - static Bignum testModulus(0); - - // TODO: should use a hard-coded RSA modulus for testing - if (!testModulus) { - Bignum p, q; - - // Note: we are NOT using safe primes for testing because - // they take too long to generate. Don't do this in real - // usage. See the paramgen utility for better code. - p = Bignum::generatePrime(1024, false); - q = Bignum::generatePrime(1024, false); - testModulus = p * q; - } - - return testModulus; -} - -////////// -// Test routines -////////// - -bool -Test_GenRSAModulus() -{ - Bignum result = GetTestModulus(); - - if (!result) { - return false; - } - else { - return true; - } -} - -bool -Test_CalcParamSizes() -{ - bool result = true; -#if 0 - - uint32_t pLen, qLen; - - try { - calculateGroupParamLengths(4000, 80, &pLen, &qLen); - if (pLen < 1024 || qLen < 256) { - result = false; - } - calculateGroupParamLengths(4000, 96, &pLen, &qLen); - if (pLen < 2048 || qLen < 256) { - result = false; - } - calculateGroupParamLengths(4000, 112, &pLen, &qLen); - if (pLen < 3072 || qLen < 320) { - result = false; - } - calculateGroupParamLengths(4000, 120, &pLen, &qLen); - if (pLen < 3072 || qLen < 320) { - result = false; - } - calculateGroupParamLengths(4000, 128, &pLen, &qLen); - if (pLen < 3072 || qLen < 320) { - result = false; - } - } catch (exception &e) { - result = false; - } -#endif - - return result; -} - -bool -Test_GenerateGroupParams() -{ - int32_t pLen = 1024, qLen = 256, count; - IntegerGroupParams group; - - for (count = 0; count < 1; count++) { - - try { - group = deriveIntegerGroupParams(calculateSeed(GetTestModulus(), "test", ZEROCOIN_DEFAULT_SECURITYLEVEL, "TEST GROUP"), pLen, qLen); - } catch (std::runtime_error e) { - printf("Caught exception %s\n", e.what()); - return false; - } - - // Now perform some simple tests on the resulting parameters - if (group.groupOrder.bitSize() < qLen || group.modulus.bitSize() < pLen) { - return false; - } - - Bignum c = group.g.pow_mod(group.groupOrder, group.modulus); - if (!(c.isOne())) return false; - - // Try at multiple parameter sizes - pLen = pLen * 1.5; - qLen = qLen * 1.5; - } - - return true; -} - -bool -Test_ParamGen() -{ - bool result = true; - - try { - // Instantiating testParams runs the parameter generation code - Params testParams(GetTestModulus(),ZEROCOIN_DEFAULT_SECURITYLEVEL); - } catch (runtime_error e) { - printf("ParamGen exception %s\n", e.what()); - result = false; - } - - return result; -} - -bool -Test_Accumulator() -{ - // This test assumes a list of coins were generated during - // the Test_MintCoin() test. - if (gCoins[0] == NULL) { - return false; - } - try { - // Accumulate the coin list from first to last into one accumulator - Accumulator accOne(&g_Params->accumulatorParams); - Accumulator accTwo(&g_Params->accumulatorParams); - Accumulator accThree(&g_Params->accumulatorParams); - Accumulator accFour(&g_Params->accumulatorParams); - AccumulatorWitness wThree(g_Params, accThree, gCoins[0]->getPublicCoin()); - - for (uint32_t i = 0; i < TESTS_COINS_TO_ACCUMULATE; i++) { - accOne += gCoins[i]->getPublicCoin(); - accTwo += gCoins[TESTS_COINS_TO_ACCUMULATE - (i+1)]->getPublicCoin(); - accThree += gCoins[i]->getPublicCoin(); - wThree += gCoins[i]->getPublicCoin(); - if(i != 0) { - accFour += gCoins[i]->getPublicCoin(); - } - } - - // Compare the accumulated results - if (accOne.getValue() != accTwo.getValue() || accOne.getValue() != accThree.getValue()) { - printf("Accumulators don't match\n"); - return false; - } - - if(accFour.getValue() != wThree.getValue()) { - printf("Witness math not working,\n"); - return false; - } - - // Verify that the witness is correct - if (!wThree.VerifyWitness(accThree, gCoins[0]->getPublicCoin()) ) { - printf("Witness not valid\n"); - return false; - } - - // Serialization test: see if we can serialize the accumulator - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << accOne; - - // Deserialize it into a new object - Accumulator newAcc(g_Params, ss); - - // Compare the results - if (accOne.getValue() != newAcc.getValue()) { - return false; - } - - } catch (runtime_error e) { - return false; - } - - return true; -} - -bool -Test_EqualityPoK() -{ - // Run this test 10 times - for (uint32_t i = 0; i < 10; i++) { - try { - // Generate a random integer "val" - Bignum val = Bignum::randBignum(g_Params->coinCommitmentGroup.groupOrder); - - // Manufacture two commitments to "val", both - // under different sets of parameters - Commitment one(&g_Params->accumulatorParams.accumulatorPoKCommitmentGroup, val); - - Commitment two(&g_Params->serialNumberSoKCommitmentGroup, val); - - // Now generate a proof of knowledge that "one" and "two" are - // both commitments to the same value - CommitmentProofOfKnowledge pok(&g_Params->accumulatorParams.accumulatorPoKCommitmentGroup, - &g_Params->serialNumberSoKCommitmentGroup, - one, two); - - // Serialize the proof into a stream - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << pok; - - // Deserialize back into a PoK object - CommitmentProofOfKnowledge newPok(&g_Params->accumulatorParams.accumulatorPoKCommitmentGroup, - &g_Params->serialNumberSoKCommitmentGroup, - ss); - - if (newPok.Verify(one.getCommitmentValue(), two.getCommitmentValue()) != true) { - return false; - } - - // Just for fun, deserialize the proof a second time - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << pok; - - // This time tamper with it, then deserialize it back into a PoK - ss2[15] = 0; - CommitmentProofOfKnowledge newPok2(&g_Params->accumulatorParams.accumulatorPoKCommitmentGroup, - &g_Params->serialNumberSoKCommitmentGroup, - ss2); - - // If the tampered proof verifies, that's a failure! - if (newPok2.Verify(one.getCommitmentValue(), two.getCommitmentValue()) == true) { - return false; - } - - } catch (runtime_error &e) { - return false; - } - } - - return true; -} - -bool -Test_MintCoin() -{ - gCoinSize = 0; - - try { - // Generate a list of coins - for (uint32_t i = 0; i < TESTS_COINS_TO_ACCUMULATE; i++) { - gCoins[i] = new PrivateCoin(g_Params); - - PublicCoin pc = gCoins[i]->getPublicCoin(); - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << pc; - gCoinSize += ss.size(); - } - - gCoinSize /= TESTS_COINS_TO_ACCUMULATE; - - } catch (exception &e) { - return false; - } - - return true; -} - -bool -Test_MintAndSpend() -{ - try { - // This test assumes a list of coins were generated in Test_MintCoin() - if (gCoins[0] == NULL) - { - // No coins: mint some. - Test_MintCoin(); - if (gCoins[0] == NULL) { - return false; - } - } - - // Accumulate the list of generated coins into a fresh accumulator. - // The first one gets marked as accumulated for a witness, the - // others just get accumulated normally. - Accumulator acc(&g_Params->accumulatorParams); - AccumulatorWitness wAcc(g_Params, acc, gCoins[0]->getPublicCoin()); - - for (uint32_t i = 0; i < TESTS_COINS_TO_ACCUMULATE; i++) { - acc += gCoins[i]->getPublicCoin(); - wAcc +=gCoins[i]->getPublicCoin(); - } - - // Now spend the coin - SpendMetaData m(1,1); - - CoinSpend spend(g_Params, *(gCoins[0]), acc, wAcc, m); - - // Serialize the proof and deserialize into newSpend - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << spend; - gProofSize = ss.size(); - CoinSpend newSpend(g_Params, ss); - - // See if we can verify the deserialized proof (return our result) - bool ret = newSpend.Verify(acc, m); - - // Extract the serial number - Bignum serialNumber = newSpend.getCoinSerialNumber(); - gSerialNumberSize = ceil((double)serialNumber.bitSize() / 8.0); - - return ret; - } catch (runtime_error &e) { - printf("MintAndSpend exception %s\n", e.what()); - return false; - } - - return false; -} - -void -Test_RunAllTests() -{ - printf("ZeroCoin v%s self-test routine\n", ZEROCOIN_VERSION_STRING); - - // Make a new set of parameters from a random RSA modulus - //g_Params = new Params(GetTestModulus()); - g_Params = ZCParams; - - gNumTests = gSuccessfulTests = gProofSize = 0; - for (uint32_t i = 0; i < TESTS_COINS_TO_ACCUMULATE; i++) { - gCoins[i] = NULL; - } - - // Run through all of the Zerocoin tests - LogTestResult("an RSA modulus can be generated", Test_GenRSAModulus); - LogTestResult("parameter sizes are correct", Test_CalcParamSizes); - LogTestResult("group/field parameters can be generated", Test_GenerateGroupParams); - LogTestResult("parameter generation is correct", Test_ParamGen); - LogTestResult("coins can be minted", Test_MintCoin); - LogTestResult("the accumulator works", Test_Accumulator); - LogTestResult("the commitment equality PoK works", Test_EqualityPoK); - LogTestResult("a minted coin can be spent", Test_MintAndSpend); - - printf("\nAverage coin size is %d bytes.\n", gCoinSize); - printf("Serial number size is %d bytes.\n", gSerialNumberSize); - printf("Spend proof size is %d bytes.\n", gProofSize); - - // Summarize test results - if (gSuccessfulTests < gNumTests) { - printf("\nERROR: SOME TESTS FAILED\n"); - } - - // Clear any generated coins - for (uint32_t i = 0; i < TESTS_COINS_TO_ACCUMULATE; i++) { - delete gCoins[i]; - } - - printf("\n%d out of %d tests passed.\n\n", gSuccessfulTests, gNumTests); - delete g_Params; -} diff --git a/src/zerocoin/ZeroTest.h b/src/zerocoin/ZeroTest.h deleted file mode 100644 index 36ab6b7..0000000 --- a/src/zerocoin/ZeroTest.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef ZEROTEST_H_ -#define ZEROTEST_H_ - -void Test_RunAllTests(); - -#endif diff --git a/src/zerocoin/Zerocoin.h b/src/zerocoin/Zerocoin.h deleted file mode 100644 index 326e143..0000000 --- a/src/zerocoin/Zerocoin.h +++ /dev/null @@ -1,61 +0,0 @@ -/** -* @file Zerocoin.h -* -* @brief Exceptions and constants for Zerocoin -* -* @author Ian Miers, Christina Garman and Matthew Green -* @date June 2013 -* -* @copyright Copyright 2013 Ian Miers, Christina Garman and Matthew Green -* @license This project is released under the MIT license. -**/ - -#ifndef ZEROCOIN_H_ -#define ZEROCOIN_H_ - -#include - -#define ZEROCOIN_DEFAULT_SECURITYLEVEL 80 -#define ZEROCOIN_MIN_SECURITY_LEVEL 80 -#define ZEROCOIN_MAX_SECURITY_LEVEL 80 -#define ACCPROOF_KPRIME 160 -#define ACCPROOF_KDPRIME 128 -#define MAX_COINMINT_ATTEMPTS 10000 -#define ZEROCOIN_MINT_PRIME_PARAM 20 -#define ZEROCOIN_VERSION_STRING "0.11" -#define ZEROCOIN_VERSION_INT 11 -#define ZEROCOIN_PROTOCOL_VERSION "1" -#define HASH_OUTPUT_BITS 256 -#define ZEROCOIN_COMMITMENT_EQUALITY_PROOF "COMMITMENT_EQUALITY_PROOF" -#define ZEROCOIN_ACCUMULATOR_PROOF "ACCUMULATOR_PROOF" -#define ZEROCOIN_SERIALNUMBER_PROOF "SERIALNUMBER_PROOF" - -// Activate multithreaded mode for proof verification - -//#define ZEROCOIN_THREADING 1 - -// Uses a fast technique for coin generation. Could be more vulnerable -// to timing attacks. Turn off if an attacker can measure coin minting time. -#define ZEROCOIN_FAST_MINT 1 - -// Errors thrown by the Zerocoin library - -class ZerocoinException : public std::runtime_error -{ -public: - explicit ZerocoinException(const std::string& str) : std::runtime_error(str) {} -}; - -#include "../serialize.h" -#include "../bignum.h" -#include "../hash.h" -#include "Params.h" -#include "Coin.h" -#include "Commitment.h" -#include "Accumulator.h" -#include "AccumulatorProofOfKnowledge.h" -#include "CoinSpend.h" -#include "SerialNumberSignatureOfKnowledge.h" -#include "ParamGeneration.h" - -#endif /* ZEROCOIN_H_ */ -- 1.7.1