# TODO: rename to libzcash
LIBZEROCASH_H = \
zcash/IncrementalMerkleTree.h \
- zerocash/Address.h \
- zerocash/CoinCommitment.h \
- zerocash/Coin.h \
- zerocash/IncrementalMerkleTree.h \
- zerocash/MintTransaction.h \
- zerocash/PourInput.h \
- zerocash/PourOutput.h \
- zerocash/PourProver.h \
- zerocash/PourTransaction.h \
- zerocash/Zerocash.h \
- zerocash/ZerocashParams.h \
- zerocash/zerocash_pour_params.hpp \
zerocash/utils/util.h \
zcash/NoteEncryption.hpp \
zcash/Address.hpp \
# zerocash protocol primitives #
libzerocash_a_SOURCES = \
zcash/IncrementalMerkleTree.cpp \
- zerocash/Address.cpp \
- zerocash/CoinCommitment.cpp \
- zerocash/Coin.cpp \
- zerocash/IncrementalMerkleTree.cpp \
- zerocash/MintTransaction.cpp \
- zerocash/PourInput.cpp \
- zerocash/PourOutput.cpp \
- zerocash/PourProver.cpp \
- zerocash/PourTransaction.cpp \
- zerocash/ZerocashParams.cpp \
zerocash/utils/util.cpp \
zcash/NoteEncryption.cpp \
zcash/Address.cpp \
DISTCLEANFILES = obj/build.h
-EXTRA_DIST = leveldb libzerocash/Makefile
+EXTRA_DIST = leveldb
clean-local:
-$(MAKE) -C leveldb clean
bin_PROGRAMS += \
zcash/GenerateParams \
- zerocash/tests/utilTest \
- zerocash/tests/zerocashTest \
- zerocash/tests/test_zerocash_pour_ppzksnark
+ zerocash/tests/utilTest
# tool for generating our public parameters
zcash_GenerateParams_SOURCES = zcash/GenerateParams.cpp
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO) \
$(LIBZEROCASH_LIBS)
-
-# tests for libzerocash APIs
-zerocash_tests_zerocashTest_SOURCES = \
- zerocash/tests/zerocashTest.cpp \
- zerocash/tests/timer.cpp
-
-zerocash_tests_zerocashTest_LDADD = \
- $(BOOST_LIBS) \
- $(LIBZEROCASH) \
- $(LIBBITCOIN_UTIL) \
- $(LIBBITCOIN_CRYPTO) \
- $(LIBZEROCASH_LIBS)
-
-# tests for our zkSNARK circuit
-
-zerocash_tests_test_zerocash_pour_ppzksnark_SOURCES = zerocash/tests/test_zerocash_pour_ppzksnark.cpp
-zerocash_tests_test_zerocash_pour_ppzksnark_LDADD = \
- $(BOOST_LIBS) \
- $(LIBZEROCASH) \
- $(LIBBITCOIN_UTIL) \
- $(LIBBITCOIN_CRYPTO) \
- $(LIBZEROCASH_LIBS)
-
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Implementation of interfaces for the classes Address and PublicAddress.
-
- See Address.h .
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include "zcash/NoteEncryption.hpp"
-
-#include "Zerocash.h"
-#include "Address.h"
-
-namespace libzerocash {
-
-PrivateAddress::PrivateAddress(const uint256 &a_sk, const uint256 &sk_enc) {
- this->a_sk = a_sk;
- this->sk_enc = sk_enc;
-}
-
-PrivateAddress::PrivateAddress() {
-
-}
-
-bool PrivateAddress::operator==(const PrivateAddress& rhs) const {
- return ((this->a_sk == rhs.a_sk) && (this->sk_enc == rhs.sk_enc));
-}
-
-bool PrivateAddress::operator!=(const PrivateAddress& rhs) const {
- return !(*this == rhs);
-}
-
-const uint256& PrivateAddress::getEncryptionSecretKey() const {
- return this->sk_enc;
-}
-
-const uint256& PrivateAddress::getAddressSecret() const {
- return this->a_sk;
-}
-
-PublicAddress::PublicAddress() {
-
-}
-
-PublicAddress::PublicAddress(const uint256& a_pk, uint256& pk_enc) : a_pk(a_pk), pk_enc(pk_enc) {}
-
-PublicAddress::PublicAddress(const PrivateAddress& addr_sk) {
- std::vector<bool> a_sk_bool(ZC_A_SK_SIZE * 8);
-
- std::vector<unsigned char> a_sk_v(addr_sk.getAddressSecret().begin(),
- addr_sk.getAddressSecret().end());
-
- convertBytesVectorToVector(a_sk_v, a_sk_bool);
-
- std::vector<bool> zeros_256(256, 0);
-
- std::vector<bool> a_pk_internal;
- concatenateVectors(a_sk_bool, zeros_256, a_pk_internal);
-
- std::vector<bool> a_pk_bool(ZC_A_PK_SIZE * 8);
- hashVector(a_pk_internal, a_pk_bool);
-
- std::vector<unsigned char> a_pk_vv(ZC_A_PK_SIZE);
-
- convertVectorToBytesVector(a_pk_bool, a_pk_vv);
-
- this->a_pk = uint256(a_pk_vv);
-
- this->pk_enc = ZCNoteEncryption::generate_pubkey(addr_sk.getEncryptionSecretKey());
-}
-
-const uint256& PublicAddress::getEncryptionPublicKey() const {
- return this->pk_enc;
-}
-
-const uint256& PublicAddress::getPublicAddressSecret() const {
- return this->a_pk;
-}
-
-bool PublicAddress::operator==(const PublicAddress& rhs) const {
- return ((this->a_pk == rhs.a_pk) && (this->pk_enc == rhs.pk_enc));
-}
-
-bool PublicAddress::operator!=(const PublicAddress& rhs) const {
- return !(*this == rhs);
-}
-
-Address::Address(PrivateAddress& priv) : addr_pk(priv), addr_sk(priv) {
-
-}
-
-Address::Address() : addr_pk(), addr_sk() {
-
-}
-
-const PublicAddress& Address::getPublicAddress() const {
- return this->addr_pk;
-}
-
-const PrivateAddress& Address::getPrivateAddress() const {
- return this->addr_sk;
-}
-
-bool Address::operator==(const Address& rhs) const {
- return ((this->addr_sk == rhs.addr_sk) && (this->addr_pk == rhs.addr_pk));
-}
-
-bool Address::operator!=(const Address& rhs) const {
- return !(*this == rhs);
-}
-
-Address Address::CreateNewRandomAddress() {
- std::vector<unsigned char> a_sk(ZC_A_SK_SIZE);
-
- unsigned char a_sk_bytes[ZC_A_SK_SIZE];
- getRandBytes(a_sk_bytes, ZC_A_SK_SIZE);
- convertBytesToBytesVector(a_sk_bytes, a_sk);
-
- uint256 a_sk_u(a_sk);
-
- uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk_u);
-
- PrivateAddress addr_sk(a_sk_u, sk_enc);
- return Address(addr_sk);
-}
-
-} /* namespace libzerocash */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of interfaces for the classes Address and PublicAddress.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef ADDRESS_H_
-#define ADDRESS_H_
-
-#include <vector>
-#include <string>
-
-#include "uint256.h"
-
-namespace libzerocash {
-
-/***************************** Private address ********************************/
-
-class PrivateAddress {
-public:
- /* This constructor is to be used ONLY for deserialization. */
- PrivateAddress();
- PrivateAddress(const uint256 &a_sk, const uint256 &sk_enc);
-
- bool operator==(const PrivateAddress& rhs) const;
- bool operator!=(const PrivateAddress& rhs) const;
-
- const uint256& getAddressSecret() const;
- const uint256& getEncryptionSecretKey() const;
-
-private:
- uint256 a_sk;
- uint256 sk_enc;
-
-};
-
-/***************************** Public address ********************************/
-
-class PublicAddress {
-public:
- /* This constructor is to be used ONLY for deserialization. */
- PublicAddress();
- PublicAddress(const uint256& a_pk, uint256& pk_enc);
- PublicAddress(const PrivateAddress& addr_sk);
-
- bool operator==(const PublicAddress& rhs) const;
- bool operator!=(const PublicAddress& rhs) const;
-
-
- const uint256& getPublicAddressSecret() const;
- const uint256& getEncryptionPublicKey() const;
-
-private:
- uint256 a_pk;
- uint256 pk_enc;
-};
-
-/******************************** Address ************************************/
-
-class Address {
-public:
- /* This constructor is to be used ONLY for deserialization. */
- Address();
- Address(PrivateAddress&);
-
- const PublicAddress& getPublicAddress() const;
- const PrivateAddress& getPrivateAddress() const;
-
- bool operator==(const Address& rhs) const;
- bool operator!=(const Address& rhs) const;
-
-
- static Address CreateNewRandomAddress();
-
-private:
- PublicAddress addr_pk;
- PrivateAddress addr_sk;
-};
-
-} /* namespace libzerocash */
-
-#endif /* ADDRESS_H_ */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Implementation of interfaces for the class Coin.
-
- See coin.h .
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include <stdexcept>
-
-#include "Zerocash.h"
-#include "Coin.h"
-
-namespace libzerocash {
-
-Coin::Coin(): addr_pk(), cm(), rho(ZC_RHO_SIZE), r(ZC_R_SIZE), coinValue(ZC_V_SIZE) {
-
-}
-
-Coin::Coin(const ZCNoteEncryption::Ciphertext& bucket,
- Address& addr,
- uint256& epk,
- unsigned char nonce
- ): addr_pk(), cm(), rho(ZC_RHO_SIZE), r(ZC_R_SIZE), k(ZC_K_SIZE), coinValue(ZC_V_SIZE) {
-
- ZCNoteDecryption decrypter(addr.getPrivateAddress().getEncryptionSecretKey());
- auto plaintext = decrypter.decrypt(bucket,
- epk,
- uint256(),
- nonce);
-
- // Grab the byte vectors
- std::vector<unsigned char> value_v(plaintext.begin(),
- plaintext.begin() + ZC_V_SIZE);
- std::vector<unsigned char> r_v(plaintext.begin() + ZC_V_SIZE,
- plaintext.begin() + ZC_V_SIZE + ZC_R_SIZE);
- std::vector<unsigned char> rho_v(plaintext.begin() + ZC_V_SIZE + ZC_R_SIZE,
- plaintext.begin() + ZC_V_SIZE + ZC_R_SIZE + ZC_RHO_SIZE);
-
- this->coinValue = value_v;
- this->r = r_v;
- this->rho = rho_v;
- this->addr_pk = addr.getPublicAddress();
-
- std::vector<unsigned char> a_pk(addr.getPublicAddress().getPublicAddressSecret().begin(),
- addr.getPublicAddress().getPublicAddressSecret().end());
-
- this->computeCommitments(a_pk);
-}
-
-Coin::Coin(const PublicAddress& addr, uint64_t value): addr_pk(addr), cm(), rho(ZC_RHO_SIZE), r(ZC_R_SIZE), k(ZC_K_SIZE), coinValue(ZC_V_SIZE)
-{
- convertIntToBytesVector(value, this->coinValue);
-
- std::vector<unsigned char> a_pk(addr.getPublicAddressSecret().begin(),
- addr.getPublicAddressSecret().end());
-
- unsigned char rho_bytes[ZC_RHO_SIZE];
- getRandBytes(rho_bytes, ZC_RHO_SIZE);
- convertBytesToBytesVector(rho_bytes, this->rho);
-
- unsigned char r_bytes[ZC_R_SIZE];
- getRandBytes(r_bytes, ZC_R_SIZE);
- convertBytesToBytesVector(r_bytes, this->r);
-
- this->computeCommitments(a_pk);
-}
-
-
-Coin::Coin(const PublicAddress& addr, uint64_t value,
- const std::vector<unsigned char>& rho, const std::vector<unsigned char>& r): addr_pk(addr), rho(rho), r(r), k(ZC_K_SIZE), coinValue(ZC_V_SIZE)
-{
- convertIntToBytesVector(value, this->coinValue);
-
- std::vector<unsigned char> a_pk(addr.getPublicAddressSecret().begin(), addr.getPublicAddressSecret().end());
-
- this->computeCommitments(a_pk);
-}
-
-void
-Coin::computeCommitments(std::vector<unsigned char>& a_pk)
-{
- std::vector<unsigned char> k_internal;
- std::vector<unsigned char> k_internalhash_trunc(16);
-
- std::vector<unsigned char> k_internalhash_internal;
- concatenateVectors(a_pk, this->rho, k_internalhash_internal);
-
- std::vector<unsigned char> k_internalhash(ZC_K_SIZE);
- hashVector(k_internalhash_internal, k_internalhash);
-
- copy(k_internalhash.begin(), k_internalhash.begin()+16, k_internalhash_trunc.begin());
- concatenateVectors(this->r, k_internalhash_trunc, k_internal);
- hashVector(k_internal, this->k);
-
- CoinCommitment com(this->coinValue, this->k);
- this->cm = com;
-}
-
-bool Coin::operator==(const Coin& rhs) const {
- return ((this->cm == rhs.cm) && (this->rho == rhs.rho) && (this->r == rhs.r) && (this->k == rhs.k) && (this->coinValue == rhs.coinValue) && (this->addr_pk == rhs.addr_pk));
-}
-
-bool Coin::operator!=(const Coin& rhs) const {
- return !(*this == rhs);
-}
-
-const PublicAddress& Coin::getPublicAddress() const {
- return this->addr_pk;
-}
-
-const CoinCommitment& Coin::getCoinCommitment() const {
- return this->cm;
-}
-
-const std::vector<unsigned char>& Coin::getInternalCommitment() const {
- return this->k;
-}
-
-const std::vector<unsigned char>& Coin::getRho() const {
- return this->rho;
-}
-
-const std::vector<unsigned char>& Coin::getR() const {
- return this->r;
-}
-
-uint64_t Coin::getValue() const {
- return convertBytesVectorToInt(this->coinValue);
-}
-
-} /* namespace libzerocash */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of interfaces for the class Coin.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef COIN_H_
-#define COIN_H_
-
-#include <vector>
-
-#include "Address.h"
-#include "CoinCommitment.h"
-
-#include "zcash/NoteEncryption.hpp"
-
-namespace libzerocash {
-
-/********************************* Coin **************************************/
-
-class Coin {
-
-friend class MintTransaction;
-friend class PourTransaction;
-
-public:
- /* This constructor is to be used ONLY for deserialization. */
- Coin();
- /**
- * @param addr the address the coin will belong to when minted or poured into
- * @param value the monetary value of the coin
- */
- Coin(const PublicAddress& addr,
- uint64_t value);
-
- Coin(const PublicAddress& addr,
- uint64_t value,
- const std::vector<unsigned char>& rho,
- const std::vector<unsigned char>& r);
-
- Coin(const ZCNoteEncryption::Ciphertext&, Address& addr, uint256& epk, unsigned char nonce);
-
- const PublicAddress& getPublicAddress() const;
-
- const CoinCommitment& getCoinCommitment() const;
-
- bool operator==(const Coin& rhs) const;
- bool operator!=(const Coin& rhs) const;
-
- uint64_t getValue() const;
-
- const std::vector<unsigned char>& getRho() const;
-
- const std::vector<unsigned char>& getR() const;
-
-private:
- PublicAddress addr_pk;
- CoinCommitment cm;
- std::vector<unsigned char> rho;
- std::vector<unsigned char> r;
- std::vector<unsigned char> k;
- std::vector<unsigned char> coinValue;
-
- const std::vector<unsigned char>& getInternalCommitment() const;
-
- void computeCommitments(std::vector<unsigned char>& a_pk);
-};
-
-} /* namespace libzerocash */
-
-#endif /* COIN_H_ */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Implementation of interfaces for the class CoinCommitment.
-
- See CoinCommitment.h .
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include <stdexcept>
-#include <stdint.h>
-
-#include "Zerocash.h"
-#include "CoinCommitment.h"
-
-namespace libzerocash {
-
-CoinCommitment::CoinCommitment() : commitmentValue(ZC_CM_SIZE)
-{ }
-
-CoinCommitment::CoinCommitment(const std::vector<unsigned char>& val,
- const std::vector<unsigned char>& k) : commitmentValue(ZC_CM_SIZE)
-{
- std::vector<bool> zeros_192(192, 0);
- std::vector<bool> cm_internal;
- std::vector<bool> value_bool(ZC_V_SIZE * 8, 0);
- std::vector<bool> k_bool(ZC_K_SIZE * 8, 0);
-
- if (val.size() > ZC_V_SIZE || k.size() > ZC_K_SIZE) {
- throw std::runtime_error("CoinCommitment: inputs are too large");
- }
-
- libzerocash::convertBytesVectorToVector(val, value_bool);
- libzerocash::convertBytesVectorToVector(k, k_bool);
-
- libzerocash::concatenateVectors(k_bool, zeros_192, value_bool, cm_internal);
- std::vector<bool> cm_bool(ZC_CM_SIZE * 8);
- libzerocash::hashVector(cm_internal, cm_bool);
- libzerocash::convertVectorToBytesVector(cm_bool, this->commitmentValue);
-}
-
-bool CoinCommitment::operator==(const CoinCommitment& rhs) const {
- return (this->commitmentValue == rhs.commitmentValue);
-}
-
-bool CoinCommitment::operator!=(const CoinCommitment& rhs) const {
- return !(*this == rhs);
-}
-
-const std::vector<unsigned char>& CoinCommitment::getCommitmentValue() const {
- return this->commitmentValue;
-}
-
-} /* namespace libzerocash */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of interfaces for the class CoinCommitment.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef COINCOMMITMENT_H_
-#define COINCOMMITMENT_H_
-
-#include <vector>
-
-namespace libzerocash {
-
-/****************************** Coin commitment ******************************/
-
-class CoinCommitment {
-
-friend class PourTransaction;
-friend class PourProver;
-
-public:
- CoinCommitment();
-
- CoinCommitment(const std::vector<unsigned char>& val,
- const std::vector<unsigned char>& k);
-
- const std::vector<unsigned char>& getCommitmentValue() const;
-
- bool operator==(const CoinCommitment& rhs) const;
- bool operator!=(const CoinCommitment& rhs) const;
-
-
-private:
- std::vector<unsigned char> commitmentValue;
-};
-
-} /* namespace libzerocash */
-
-#endif /* COINCOMMITMENT_H_ */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Functionality to generate files containing the Zerocash public parameters.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include <fstream>
-
-#include "Zerocash.h"
-#include "ZerocashParams.h"
-#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp"
-#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp"
-
-using namespace libzerocash;
-
-int main(int argc, char **argv)
-{
- if(argc != 4) {
- std::cerr << "Usage: " << argv[0] << " treeDepth provingKeyFileName verificationKeyFileName" << std::endl;
- return 1;
- }
-
- unsigned int tree_depth = atoi(argv[1]);
- std::string pkFile = argv[2];
- std::string vkFile = argv[3];
-
- auto keypair = libzerocash::ZerocashParams::GenerateNewKeyPair(tree_depth);
- libzerocash::ZerocashParams p(
- tree_depth,
- &keypair
- );
-
- libzerocash::ZerocashParams::SaveProvingKeyToFile(&p.getProvingKey(), pkFile);
- libzerocash::ZerocashParams::SaveVerificationKeyToFile(&p.getVerificationKey(), vkFile);
-
- return 0;
-}
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Implementation of interfaces for the classes IncrementalMerkleTreeCompact,
- IncrementalMerkleNode, and IncrementalMerkleTree.
-
- See IncrementalMerkleTree.h .
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include "IncrementalMerkleTree.h"
-#include "Zerocash.h"
-
-#include <cmath>
-#include <iostream>
-#include <vector>
-
-namespace libzerocash {
-
- /////////////////////////////////////////////
- // IncrementalMerkleTreeCompact class
- /////////////////////////////////////////////
-
- std::vector<unsigned char> IncrementalMerkleTreeCompact::serialize() const {
- /* Serialization format:
- * treeHeight (4 bytes, big endian)
- * hashList (ceil(treeHeight / 8) bytes)
- * hashVec (32 bytes for every 1 bit in hashList)
- */
- std::vector<unsigned char> serialized;
-
- /* treeHeight (4 bytes, big endian) */
- std::vector<unsigned char> treeHeightBytes(4);
- convertIntToBytesVector((uint64_t)this->treeHeight, treeHeightBytes);
- serialized.insert(serialized.end(), treeHeightBytes.begin(), treeHeightBytes.end());
-
- /* hashList */
- assert(this->hashList.size() == this->treeHeight);
-
- /* Pad it out to a multiple of 8 bits. */
- std::vector<bool> hashList = this->hashList;
- if (hashList.size() % 8 != 0) {
- hashList.insert(hashList.begin(), 8 - (hashList.size() % 8), false);
- }
- assert(hashList.size() % 8 == 0);
-
- /* Convert it to a byte vector. */
- std::vector<unsigned char> hashListBytes(hashList.size() / 8);
- convertVectorToBytesVector(hashList, hashListBytes);
- serialized.insert(serialized.end(), hashListBytes.begin(), hashListBytes.end());
-
- /* hashVec */
- assert(this->hashVec.size() == countOnes(this->hashList));
- for (uint32_t i = 0; i < this->hashVec.size(); i++) {
- assert(this->hashVec.at(i).size() == 32);
- serialized.insert(serialized.end(), this->hashVec.at(i).begin(), this->hashVec.at(i).end());
- }
-
- return serialized;
- }
-
- IncrementalMerkleTreeCompact IncrementalMerkleTreeCompact::deserialize(const std::vector<unsigned char>& serialized) {
- IncrementalMerkleTreeCompact deserialized;
-
- size_t currentPos = 0;
-
-
- /* treeHeight */
- std::vector<unsigned char> treeHeightBytes = vectorSlice(serialized, 0, 4);
- currentPos += 4;
- deserialized.treeHeight = convertBytesVectorToInt(treeHeightBytes);
-
- /* hashList */
- uint32_t hashListBytesLength = ceil(deserialized.treeHeight / 8.0);
- std::vector<unsigned char> hashListBytes = vectorSlice(serialized, currentPos, hashListBytesLength);
- currentPos += hashListBytesLength;
- convertBytesVectorToVector(hashListBytes, deserialized.hashList);
- /* Remove the multiple-of-8-bits padding. */
- deserialized.hashList.erase(deserialized.hashList.begin(),
- deserialized.hashList.end() - deserialized.treeHeight
- );
-
- /* hashVec */
- size_t hashVecSize = countOnes(deserialized.hashList);
- for (size_t i = 0; i < hashVecSize; i++) {
- std::vector<unsigned char> hashVecElement = vectorSlice(serialized, currentPos, 32);
- currentPos += 32;
- deserialized.hashVec.push_back(hashVecElement);
- }
-
- if (currentPos != serialized.size()) {
- throw std::runtime_error("Serialized vector is longer than expected.");
- }
-
- return deserialized;
- }
-
- /////////////////////////////////////////////
- // IncrementalMerkleTree class
- /////////////////////////////////////////////
-
- // Custom tree constructor (initialize tree of specified height)
- IncrementalMerkleTree::IncrementalMerkleTree(uint32_t height) : root(0, height) {
- treeHeight = height;
- }
-
- // Vector constructor. Initializes and inserts a list of elements.
- IncrementalMerkleTree::IncrementalMerkleTree(std::vector< std::vector<bool> > &valueVector, uint32_t height) : root(0, height)
- {
- // Initialize the tree
- treeHeight = height;
-
- // Load the tree with all the given values
- if (this->insertVector(valueVector) == false) {
- throw std::runtime_error("Could not insert vector into Merkle Tree: too many elements");
- }
- }
-
- // Custom tree constructor (initialize tree from compact representation)
- //
- IncrementalMerkleTree::IncrementalMerkleTree(IncrementalMerkleTreeCompact &compact) : root(0, 0)
- {
- // Initialize the tree
- this->treeHeight = compact.getHeight();
- root.treeHeight = treeHeight;
-
- // Reconstitute tree from compact representation
- this->fromCompactRepresentation(compact);
- }
-
- bool
- IncrementalMerkleTree::insertElement(const std::vector<bool> &hashV, std::vector<bool> &index) {
-
- // Resize the index vector
- index.resize(this->treeHeight);
-
- // Insert the element
- return this->root.insertElement(hashV, index);
- }
-
- bool
- IncrementalMerkleTree::insertElement(const std::vector<unsigned char> &hashV, std::vector<unsigned char> &index) {
-
- // Create a temporary vector to hold hashV
- std::vector<bool> hashVBool(hashV.size() * 8);
- convertBytesVectorToVector(hashV, hashVBool);
-
- // Create a temporary vector to hold the index
- std::vector<bool> indexBool(this->treeHeight, 0);
-
- // Insert the element
- bool result = this->insertElement(hashVBool, indexBool);
-
- // Convert the returned vector
- index.resize(index.size() / 8); // this might need to include a ceil
- convertVectorToBytesVector(indexBool, index);
-
- return result;
- }
-
- bool
- IncrementalMerkleTree::getWitness(const std::vector<bool> &index, merkle_authentication_path &witness) {
-
- // Resize the witness if necessary
- if (witness.size() < this->treeHeight) {
- witness.resize(treeHeight);
- }
-
- std::vector<bool> indexPadded = index;
-
- // Discard leading bits of the index if necessary
- if (indexPadded.size() > this->treeHeight) {
- indexPadded.erase(indexPadded.begin(), indexPadded.begin() + (indexPadded.size() - this->treeHeight));
- }
-
- // If the index vector is less than 'treeHeight' bits, pad the leftmost bits with 0 (false)
- // This is to deal with the situation where somebody encodes e.g., a 32-bit integer as an index
- // into a 64 height tree and does not explicitly pad to length.
- if (indexPadded.size() < this->treeHeight) {
- indexPadded.insert(indexPadded.begin(), (this->treeHeight - 1) - indexPadded.size(), false);
- }
-
- return this->root.getWitness(indexPadded, witness);
- }
-
- bool
- IncrementalMerkleTree::insertVector(std::vector< std::vector<bool> > &valueVector)
- {
- std::vector<bool> index;
-
- for (std::vector< std::vector<bool> >::iterator iter = valueVector.begin();
- iter != valueVector.end(); ++iter) {
-
- if (this->insertElement(*iter, index) == false) {
- return false;
- }
-
- }
-
- return true;
- }
-
- bool
- IncrementalMerkleTree::getRootValue(std::vector<bool>& r) const {
-
- // Query the root for its hash
- this->root.getValue(r);
- return true;
- }
-
- bool
- IncrementalMerkleTree::getRootValue(std::vector<unsigned char>& r) const {
-
- // Create a temporary byte vector
- std::vector<bool> tempR(r.size() * 8, 0);
-
- // Query the root for its hash
- this->root.getValue(tempR);
-
- // Convert the result back into the given vector
- convertVectorToBytesVector(tempR, r);
-
- return true;
- }
- std::vector<unsigned char>
- IncrementalMerkleTree::getRoot(){
- std::vector<unsigned char> temp(8);
- this->getRootValue(temp);
- return temp;
- }
-
- bool
- IncrementalMerkleTree::prune()
- {
- return this->root.prune();
- }
-
- IncrementalMerkleTreeCompact
- IncrementalMerkleTree::getCompactRepresentation() const
- {
- IncrementalMerkleTreeCompact rep;
- rep.hashList.resize(this->treeHeight);
- rep.treeHeight = this->treeHeight;
- std::fill (rep.hashList.begin(), rep.hashList.end(), false);
-
- this->root.getCompactRepresentation(rep);
- return rep;
- }
-
- bool
- IncrementalMerkleTree::fromCompactRepresentation(IncrementalMerkleTreeCompact &rep)
- {
- return this->root.fromCompactRepresentation(rep, 0);
- }
-
- /////////////////////////////////////////////
- // IncrementalMerkleNode class
- /////////////////////////////////////////////
-
- // Standard constructor
- //
- IncrementalMerkleNode::IncrementalMerkleNode(uint32_t depth, uint32_t height) : left(NULL), right(NULL), value(CSHA256::OUTPUT_SIZE * 8, 0), nodeDepth(depth), treeHeight(height),
- subtreeFull(false), subtreePruned(false)
- {
-
- }
-
- // Copy constructor
- //
- IncrementalMerkleNode::IncrementalMerkleNode(const IncrementalMerkleNode& toCopy) : left(NULL), right(NULL), value(CSHA256::OUTPUT_SIZE * 8, 0)
- {
- this->nodeDepth = toCopy.nodeDepth;
- this->subtreePruned = toCopy.subtreePruned;
- this->subtreeFull = toCopy.subtreeFull;
- this->value = toCopy.value;
- this->treeHeight = toCopy.treeHeight;
-
- // Recursively copy the subtrees
- if (toCopy.left) {
- this->left = new IncrementalMerkleNode(toCopy.left->nodeDepth, toCopy.left->treeHeight);
- *(this->left) = *(toCopy.left);
- }
-
- if (toCopy.right) {
- this->right = new IncrementalMerkleNode(toCopy.right->nodeDepth, toCopy.right->treeHeight);
- *(this->right) = *(toCopy.right);
- }
- }
-
- IncrementalMerkleNode::~IncrementalMerkleNode()
- {
- if (this->left) {
- delete this->left;
- this->left = NULL;
- }
-
- if (this->right) {
- delete this->right;
- this->right = NULL;
- }
- }
-
- bool
- IncrementalMerkleNode::insertElement(const std::vector<bool> &hashV, std::vector<bool> &index)
- {
- bool result = false;
-
- // Check if we have any free leaves. If not, bail.
- if (this->subtreeFull == true) {
- return false;
- }
-
- // Are we a leaf? If so, store the hash value.
- if (this->isLeaf()) {
- // Store the given hash value here and return success.
- this->value = hashV;
- this->subtreeFull = true;
- return true;
- }
-
- // We're not a leaf. Try to insert into subtrees, creating them if necessary.
- // Try to recurse on left subtree
- if (!this->left) {
- this->left = new IncrementalMerkleNode(this->nodeDepth + 1, this->treeHeight);
- }
- result = this->left->insertElement(hashV, index);
- if (result == true) {
- // Update the index value to indicate where the new node went
- index.at(this->nodeDepth) = false;
- }
-
- // If that failed, try to recurse on right subtree.
- if (result == false) {
- if (!this->right) {
- this->right = new IncrementalMerkleNode(this->nodeDepth + 1, this->treeHeight);
- }
- result = this->right->insertElement(hashV, index);
- if (result == true) {
- index.at(this->nodeDepth) = true;
- }
- }
-
- // If one of the inserts succeeded, update our 'fullness' status.
- if (result == true) {
- this->updateHashValue();
- if (this->isLeaf()) { this->subtreeFull = true; }
- else {
- this->subtreeFull = this->checkIfNodeFull();
- }
- }
-
- // Return the result
- return result;
- }
-
- bool
- IncrementalMerkleNode::getWitness(const std::vector<bool> &index, merkle_authentication_path &witness)
- {
- bool result = false;
-
- // If this node is a leaf: do nothing and return success
- if (this->isLeaf()) {
- return true;
- }
-
- // If this node is pruned, we can't fetch a witness. Return failure.
- if (this->isPruned()) {
- return false;
- }
-
- // If the index path leads to the left, we grab the hash value on the
- // right -- then recurse on the left node.
- if (index.at(nodeDepth) == false) {
-
- // Make sure there is a value on the right. If not we put the 'null' hash (0) into that element.
- if (this->right == NULL) {
- witness.at(nodeDepth).resize(CSHA256::OUTPUT_SIZE * 8);
- std::fill (witness.at(nodeDepth).begin(), witness.at(nodeDepth).end(), false);
- } else {
- this->right->getValue(witness.at(nodeDepth));
- //printVectorAsHex(witness.at(nodeDepth));
- }
-
- // Recurse on the left node
- if (this->left) {
- result = this->left->getWitness(index, witness);
- }
- }
-
- // If the index path leads to the right, we grab the hash value on the
- // left -- then recurse on the right node.
- if (index.at(nodeDepth) == true) {
- this->left->getValue(witness.at(nodeDepth));
-
- // Recurse on the right node
- if (this->right) {
- result = this->right->getWitness(index, witness);
- }
- }
-
- return result;
- }
-
- bool
- IncrementalMerkleNode::prune()
- {
- bool result = true;
-
- // If we're already pruned, return.
- if (this->isPruned() == true) {
- return true;
- }
-
- // Check to see if this node is full. If so, delete the subtrees.
- if (this->subtreeFull == true) {
- if (this->left) {
- delete this->left;
- this->left = NULL;
- }
-
- if (this->right) {
- delete this->right;
- this->right = NULL;
- }
-
- this->subtreePruned = true;
- } else {
- // Node is not full. Recurse on left and right.
- if (this->left) {
- result &= this->left->prune();
- }
-
- if (this->right) {
- result &= this->right->prune();
- }
- }
-
- return result;
- }
-
- void
- IncrementalMerkleNode::updateHashValue()
- {
- // Take no action on leaves or pruned nodes.
- if (this->isLeaf() || this->isPruned()) {
- return;
- }
-
- // Obtain the hash of the two subtrees and hash the
- // concatenation of the two.
- std::vector<bool> hash(CSHA256::OUTPUT_SIZE * 8);
- std::vector<bool> zero(CSHA256::OUTPUT_SIZE * 8);
- std::fill (zero.begin(), zero.end(), false);
-
- // The following code is ugly and should be refactored. It runs
- // four special cases depending on whether left/right is NULL.
- // It also ensures that the "hash" of (0 || 0) is 0.
- if (this->left && !(this->right)) {
- if (VectorIsZero(this->left->getValue())) {
- hash = zero;
- } else {
- hashVectors(this->left->getValue(), zero, hash);
- }
- } else if (!(this->left) && this->right) {
- if (VectorIsZero(this->right->getValue())) {
- hash = zero;
- } else {
- hashVectors(zero, this->left->getValue(), hash);
- }
- } else if (this->left && this->right) {
- if (VectorIsZero(this->left->getValue()) && VectorIsZero(this->right->getValue())) {
- hash = zero;
- } else {
- hashVectors(this->left->getValue(), this->right->getValue(), hash);
- }
- } else {
- hash = zero;
- }
-
- this->value = hash;
- }
-
- bool
- IncrementalMerkleNode::checkIfNodeFull()
- {
- if (this->isPruned()) {
- return true;
- }
-
- if (this->left == NULL || this->right == NULL) {
- return false;
- }
-
- return (this->left->subtreeFull && this->right->subtreeFull);
- }
-
- void
- IncrementalMerkleNode::getCompactRepresentation(IncrementalMerkleTreeCompact &rep) const
- {
- // Do nothing at the bottom level
- if (this->isLeaf()) {
- return;
- }
-
- // There's no content below us. We're done
- if (!this->left) {
- return;
- }
-
- // If we have no right elements, don't include any hashes. Recurse to the left.
- if (this->hasRightChildren() == false && this->left->isLeaf() == false && this->left->subtreeFull == false) {
- rep.hashList.at(this->nodeDepth) = false;
- this->left->getCompactRepresentation(rep);
- return;
- }
-
- // Otherwise: Add our left child hash to the tree.
- rep.hashList.at(this->nodeDepth) = true;
- std::vector<unsigned char> hash(CSHA256::OUTPUT_SIZE, 0);
- convertVectorToBytesVector(this->left->getValue(), hash);
- rep.hashVec.push_back(hash);
-
- // If we have a right child, recurse to the right
- if (this->hasRightChildren()) {
- this->right->getCompactRepresentation(rep);
- return;
- }
-
- // We get here in one of the following cases:
- // 1. Our left child is a leaf, and there's no right child.
- // 2. Our left child is a full tree, and there's no right child.
-
- // We've gone right for the last time, now we go left until we reach the
- // bottom.
- for (uint32_t i = this->nodeDepth + 1; i < this->treeHeight; i++) {
- rep.hashList.at(i) = false;
- }
- }
-
- bool
- IncrementalMerkleNode::fromCompactRepresentation(IncrementalMerkleTreeCompact &rep, uint32_t pos)
- {
- bool result = false;
-
- // Do nothing at the bottom level
- if (this->isLeaf()) {
- return true;
- }
-
- // If we have any subtrees (or this tree already has stuff in it), clean it out.
- if (this->left) {
- // XXX memory leak: left might have the only pointers to its heap
- // allocated children!
- delete this->left;
- this->left = NULL;
- }
- if (this->right) {
- // XXX memory leak: right might have the only pointers to its heap
- // allocated children!
- delete this->right;
- this->right = NULL;
- }
- this->subtreeFull = this->subtreePruned = false;
-
- // If the hashList[nodeDepth] is true, insert the next hash into the left tree
- // and mark it full AND pruned. Then recurse to the right.
- if (rep.hashList.at(this->nodeDepth) == true) {
- // Create a left node
- this->left = new IncrementalMerkleNode(this->nodeDepth + 1, this->treeHeight);
-
- // Fill the left node with the value and mark it full/pruned
- std::vector<bool> hash(CSHA256::OUTPUT_SIZE * 8, 0);
- convertBytesVectorToVector(rep.hashVec.at(pos), hash);
- this->left->value = hash;
- this->left->subtreePruned = this->left->subtreeFull = true;
-
- // Create a right node and recurse on it (incrementing pos)
- this->right = new IncrementalMerkleNode(this->nodeDepth + 1, this->treeHeight);
- result = this->right->fromCompactRepresentation(rep, pos + 1);
- } else if (this->nodeDepth < (this->treeHeight - 1)) {
- // Otherwise --
- // * If we're about to create a leaf level, do nothing.
- // * Else create a left node and recurse on it.
- this->left = new IncrementalMerkleNode(this->nodeDepth + 1, this->treeHeight);
-
- // Otherwise recurse on the left node. Do not increment pos.
- result = this->left->fromCompactRepresentation(rep, pos);
- }
-
- // Update the hash value of this node
- this->updateHashValue();
-
- return result;
- }
-
- IncrementalMerkleNode
- IncrementalMerkleNode::operator=(const IncrementalMerkleNode &rhs) {
- IncrementalMerkleNode dup(rhs);
- return dup;
- }
-
-} /* namespace libzerocash */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of interfaces for the classes IncrementalMerkleTreeCompact,
- IncrementalMerkleNode, and IncrementalMerkleTree.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef INCREMENTALMERKLETREE_H_
-#define INCREMENTALMERKLETREE_H_
-
-#include "crypto/sha256.h"
-
-#include "Zerocash.h"
-#include <vector>
-#include <iostream>
-#include <map>
-#include <cstring>
-
-#include "libsnark/common/data_structures/merkle_tree.hpp"
-
-namespace libzerocash {
-
-/******************* Incremental Merkle tree compact *************************/
-
-/* This is a comapct way to represent an incremental merkle tree, where all full
- * subtrees are replaced by their hashes. It contains just enough information
- * that you can continue addding elements to the tree.
- *
- * This class can only be constructed by IncrementalMerkleTree, and after that,
- * it is immutable. To act on a compact representation, it must first be
- * de-compactified by loading it into an IncrementalMerkleTree.
- */
-class IncrementalMerkleTreeCompact {
- friend class IncrementalMerkleTree;
- friend class IncrementalMerkleNode;
-public:
- uint32_t getHeight() { return this->treeHeight; }
-
- uint32_t getTreeHeight() { return treeHeight; }
- std::vector< std::vector<unsigned char> > const& getHashVec() { return hashVec; }
- std::vector< bool > const& getHashList() { return hashList; }
-
- std::vector<unsigned char> serialize() const;
- static IncrementalMerkleTreeCompact deserialize(const std::vector<unsigned char>& serialized);
-
-private:
- IncrementalMerkleTreeCompact() : treeHeight(0) {}
- uint32_t treeHeight;
- std::vector< std::vector<unsigned char> > hashVec;
- std::vector< bool > hashList;
-};
-
-/********************* Incremental Merkle tree node **************************/
-
-class IncrementalMerkleNode {
-public:
- CSHA256 ctx256;
- IncrementalMerkleNode* left;
- IncrementalMerkleNode* right;
- std::vector<bool> value;
- uint32_t nodeDepth;
- uint32_t treeHeight;
- bool subtreeFull;
- bool subtreePruned;
-
- IncrementalMerkleNode(uint32_t depth, uint32_t height);
- IncrementalMerkleNode(const IncrementalMerkleNode& toCopy);
- ~IncrementalMerkleNode();
-
- // Methods
- bool insertElement(const std::vector<bool> &hashV, std::vector<bool> &index);
- bool getWitness(const std::vector<bool> &index, merkle_authentication_path &witness);
- bool prune();
- void getCompactRepresentation(IncrementalMerkleTreeCompact &rep) const;
- bool fromCompactRepresentation(IncrementalMerkleTreeCompact &rep, uint32_t pos);
-
- // Utility methods
- bool isLeaf() const { return (nodeDepth == treeHeight); }
- bool isPruned() const { return subtreePruned; }
- bool hasFreeLeaves() const { return (!subtreeFull); }
- bool hasRightChildren() const { if (!right) return false; return true; }
- void getValue(std::vector<bool> &r) const { r = value; }
- const std::vector<bool>& getValue() const { return value; }
-
- bool checkIfNodeFull();
- void updateHashValue();
-
- IncrementalMerkleNode operator=(const IncrementalMerkleNode &rhs);
-};
-
-/************************ Incremental Merkle tree ****************************/
-
-class IncrementalMerkleTree {
-protected:
-
- IncrementalMerkleNode root;
- uint32_t treeHeight;
-
-public:
- IncrementalMerkleTree(uint32_t height = ZEROCASH_DEFAULT_TREE_SIZE);
- IncrementalMerkleTree(std::vector< std::vector<bool> > &valueVector, uint32_t height);
- IncrementalMerkleTree(IncrementalMerkleTreeCompact &compact);
-
- void setTo(const IncrementalMerkleTree &other) {
- auto compact = other.getCompactRepresentation();
- fromCompactRepresentation(compact);
- }
-
- bool insertElement(const std::vector<bool> &hashV, std::vector<bool> &index);
- bool insertElement(const std::vector<unsigned char> &hashV, std::vector<unsigned char> &index);
- bool insertVector(std::vector< std::vector<bool> > &valueVector);
- bool getWitness(const std::vector<bool> &index, merkle_authentication_path &witness);
- bool getRootValue(std::vector<bool>& r) const;
- bool getRootValue(std::vector<unsigned char>& r) const;
- std::vector<unsigned char>getRoot();
- bool prune();
- IncrementalMerkleTreeCompact getCompactRepresentation() const;
- std::vector<unsigned char> serialize() const {
- auto compact = getCompactRepresentation();
- return compact.serialize();
- }
-
- static IncrementalMerkleTree deserialize(const std::vector<unsigned char>& serialized) {
- auto deserialized = IncrementalMerkleTreeCompact::deserialize(serialized);
- return IncrementalMerkleTree(deserialized);
- }
-
- bool fromCompactRepresentation(IncrementalMerkleTreeCompact &rep);
-
-};
-
-} /* namespace libzerocash */
-
-#endif /* INCREMENTALMERKLETREE_H_ */
-
+++ /dev/null
-OPTFLAGS = -march=native -mtune=native -O2
-CXXFLAGS += -g -Wall -Wextra -Wno-unused-parameter -std=c++11 -fPIC -Wno-unused-variable
-LDFLAGS += -flto
-
-DEPSRC=depsrc
-DEPINST=depinst
-
-LIBZEROCASH=libzerocash
-UTILS=$(LIBZEROCASH)/utils
-TESTUTILS=tests
-LDLIBS += -L $(DEPINST)/lib -Wl,-rpath $(DEPINST)/lib -L . -lsnark -lgmpxx -lgmp
-
-ifeq ($(USE_MT),1)
- LDLIBS += -lboost_system-mt
- LDLIBS += -lboost_unit_test_framework-mt
-else
- LDLIBS += -lboost_system
- LDLIBS += -lboost_unit_test_framework
-endif
-
-LDLIBS += -lcrypto -lcryptopp -lz -ldl
-
-ifeq ($(LINK_RT),1)
-LDLIBS += -lrt
-endif
-
-
-CXXFLAGS += -I $(DEPINST)/include -I $(DEPINST)/include/libsnark -I . -DUSE_ASM -DCURVE_ALT_BN128
-
-LIBPATH = /usr/local/lib
-
-SRCS= \
- $(UTILS)/sha256.cpp \
- $(UTILS)/util.cpp \
- $(LIBZEROCASH)/IncrementalMerkleTree.cpp \
- $(LIBZEROCASH)/Address.cpp \
- $(LIBZEROCASH)/CoinCommitment.cpp \
- $(LIBZEROCASH)/Coin.cpp \
- $(LIBZEROCASH)/MintTransaction.cpp \
- $(LIBZEROCASH)/PourInput.cpp \
- $(LIBZEROCASH)/PourOutput.cpp \
- $(LIBZEROCASH)/PourProver.cpp \
- $(LIBZEROCASH)/PourTransaction.cpp \
- $(LIBZEROCASH)/ZerocashParams.cpp \
- $(TESTUTILS)/timer.cpp
-
-EXECUTABLES= \
- zerocash_pour_ppzksnark/tests/test_zerocash_pour_ppzksnark \
- zerocash_pour_ppzksnark/profiling/profile_zerocash_pour_gadget \
- tests/zerocashTest \
- tests/utilTest \
- tests/merkleTest \
- libzerocash/GenerateParamsForFiles
-
-OBJS=$(patsubst %.cpp,%.o,$(SRCS))
-
-ifeq ($(MINDEPS),1)
- CXXFLAGS += -DMINDEPS
-else
- LDLIBS += -lboost_program_options
- LDLIBS += -lprocps
-endif
-
-ifeq ($(LOWMEM),1)
- CXXFLAGS += -DLOWMEM
-endif
-
-ifeq ($(STATIC),1)
- CXXFLAGS += -static -DSTATIC
-endif
-
-ifeq ($(PROFILE_CURVE),1)
- CXXFLAGS += -static -DPROFILE_CURVE
-endif
-
-ifeq ($(MULTICORE),1)
- # When running ./get-libsnark to prepare for this build, use:
- # $ LIBSNARK_FLAGS='MULTICORE=1 STATIC=1' ./get-libsnark.
- # If you're missing some static libraries, it may help to also add
- # $ NO_PROCPS=1 ... ./get-libsnark
- # and pass MINDEPS=1 to this makefile
- # and run ./get-cryptopp to build the static cryptopp library.
- CXXFLAGS += -static -fopenmp -DMULTICORE
-endif
-
-all: $(EXECUTABLES) libzerocash.a
-
-cppdebug: CXXFLAGS += -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
-cppdebug: debug
-
-debug: CXXFLAGS += -DDEBUG -g -ggdb3
-debug: all
-
-noasserts: CXXFLAGS += -DNDEBUG -Wno-unused-variable -Wno-unused-but-set-variable
-noasserts: all
-
-# In order to detect changes to #include dependencies. -MMD below generates a .d file for .cpp file. Include the .d file.
--include $(SRCS:.cpp=.d)
-
-$(OBJS) ${patsubst %,%.o,${EXECUTABLES}}: %.o: %.cpp
- $(CXX) -o $@ $< -c -MMD $(CXXFLAGS)
-
-$(EXECUTABLES): %: %.o $(OBJS)
- $(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS) $(LDLIBS)
-
-libzerocash: $(OBJS) $(USER_OBJS)
- @echo 'Building target: $@'
- @echo 'Invoking: Cross G++ Linker'
- $(CXX) -shared -o "libzerocash.so" $(OBJS) $(CXXFLAGS) $(LDFLAGS) $(LDLIBS)
- @echo 'Finished building target: $@'
- @echo 'Copying libzerocash.so'
- sudo cp libzerocash.so $(LIBPATH)/libzerocash.so
- sudo ldconfig
- @echo 'Finished copying libzerocash.so'
- @echo ' '
-
-libzerocash.a: $(OBJS) $(USER_OBJS)
- @echo 'Building target: $@'
- @echo 'Invoking: Cross G++ Linker'
- $(AR) rcvs $@ $(OBJS)
- @echo 'Finished building target: $@'
- #@echo 'Copying libzerocash.a'
- #sudo cp libzerocash.a $(LIBPATH)/libzerocash.a
- #sudo ldconfig
- #@echo 'Finished copying libzerocash.a'
- @echo ' '
-
-test_library: %: tests/zerocashTest.o $(OBJS)
- $(CXX) -o tests/$@ $^ $(CXXFLAGS) $(LDFLAGS) $(LDLIBS) -lzerocash
-
-banktest_library: %: bankTest.o $(OBJS)
- $(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS) $(LDLIBS) -lzerocash
-
-merkletest_library: %: merkleTest.o $(OBJS)
- $(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS) $(LDLIBS) -lzerocash
-
-.PHONY: clean install
-
-clean:
- $(RM) \
- $(OBJS) \
- $(EXECUTABLES) \
- ${patsubst %,%.o,${EXECUTABLES}} \
- ${patsubst %,%.d,${EXECUTABLES}} \
- ${patsubst %.cpp,%.d,${SRCS}} \
- libzerocash.a \
- tests/test_library
-
-
-HEADERS_SRC=$(shell find . -name '*.hpp' -o -name '*.tcc' -o -name '*.h')
-HEADERS_DEST=$(patsubst %,$(PREFIX)/include/libzerocash/%,$(HEADERS_SRC))
-
-$(HEADERS_DEST): $(PREFIX)/include/libzerocash/%: %
- mkdir -p $(shell dirname $@)
- cp $< $@
-
-install: all $(HEADERS_DEST)
- mkdir -p $(PREFIX)/lib
- install -m 0755 libzerocash.a $(PREFIX)/lib/
- mkdir -p $(PREFIX)/bin
- install -m 0755 -t $(PREFIX)/bin/ $(EXECUTABLES)
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Implementation of interfaces for the class MintTransaction.
-
- See MintTransaction.h .
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include "Zerocash.h"
-#include "MintTransaction.h"
-
-namespace libzerocash {
-
-MintTransaction::MintTransaction(): coinValue(0), internalCommitment(), externalCommitment()
-{ }
-
-/**
- * Creates a transaction minting the coin c.
- *
- * @param c the coin to mint.
- */
-MintTransaction::MintTransaction(const Coin& c): coinValue(ZC_V_SIZE)
-{
- convertIntToBytesVector(c.getValue(), this->coinValue);
-
- internalCommitment = c.getInternalCommitment();
- externalCommitment = c.getCoinCommitment();
-}
-
-/**
- * Verify the correctness of a Mint transaction.
- *
- * @return true if correct, false otherwise.
- */
-bool MintTransaction::verify() const{
-
- // Check that the internal commitment is the right size
- if (this->internalCommitment.size() != ZC_K_SIZE) {
- return false;
- }
-
- // The external commitment should formulated as:
- // H( internalCommitment || 0^192 || coinValue)
- //
- // To check the structure of our proof we simply reconstruct
- // a version of the external commitment and check that it's
- // equal to the value we store.
- //
- // We use the constructor for CoinCommitment to do this.
-
- try {
- CoinCommitment comp(this->coinValue, this->internalCommitment);
-
- return (comp == this->externalCommitment);
- } catch (std::runtime_error) {
- return false;
- }
-
- return false;
-}
-
-const CoinCommitmentValue& MintTransaction::getMintedCoinCommitmentValue() const{
- return this->externalCommitment.getCommitmentValue();
-}
-
-uint64_t MintTransaction::getMonetaryValue() const {
- return convertBytesVectorToInt(this->coinValue);
-}
-
-} /* namespace libzerocash */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of interfaces for the class MintTransaction.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef MINTTRANSACTION_H_
-#define MINTTRANSACTION_H_
-
-#include "CoinCommitment.h"
-#include "Coin.h"
-
-typedef std::vector<unsigned char> CoinCommitmentValue;
-
-namespace libzerocash{
-
-/***************************** Mint transaction ******************************/
-
-class MintTransaction {
-public:
- MintTransaction();
-
- /**
- * Creates a transaction minting the provided coin.
- *
- * @param c the coin to mint.
- */
- MintTransaction(const Coin& c);
-
- /**
- * Verifies the MintTransaction.
- * In particular, this checks that output coin commitment
- * actually is to a coin of the claimed value.
- *
- * @return true if valid, false otherwise.
- */
- bool verify() const;
-
- /**
- *Gets the commitment to the coin that was minted by this transaction.
- *
- * @return the commitment
- */
- const CoinCommitmentValue& getMintedCoinCommitmentValue() const;
-
- /**
- * Gets the monetary value of the minted coin.
- *
- * @return the value
- */
- uint64_t getMonetaryValue() const;
-
-
-private:
- std::vector<unsigned char> coinValue; // coin value
- std::vector<unsigned char> internalCommitment; // "k" in paper notation
- CoinCommitment externalCommitment; // "cm" in paper notation
-
- const CoinCommitment& getCoinCommitment() const { return this->externalCommitment; }
-};
-
-} /* namespace libzerocash */
-
-#endif /* MINTTRANSACTION_H_ */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Implementation of interfaces for the class PourInput.
-
- See PourInput.h .
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include "PourInput.h"
-
-namespace libzerocash {
-
-PourInput::PourInput(int tree_depth): old_coin(), merkle_index(), path() {
- this->old_address = Address::CreateNewRandomAddress();
-
- this->old_coin = Coin(this->old_address.getPublicAddress(), 0);
-
- ZCIncrementalMerkleTree merkleTree;
- merkleTree.append(uint256(this->old_coin.getCoinCommitment().getCommitmentValue()));
-
- auto witness = merkleTree.witness();
- auto merkle_path = witness.path();
-
- this->path = merkle_path.authentication_path;
- this->merkle_index = convertVectorToInt(merkle_path.index);
-}
-
-PourInput::PourInput(Coin old_coin,
- Address old_address,
- const libzcash::MerklePath &path) : old_address(old_address), old_coin(old_coin), path(path.authentication_path) {
- this->merkle_index = convertVectorToInt(path.index);
-};
-
-} /* namespace libzerocash */
\ No newline at end of file
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of interfaces for the class PourInput.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef POURINPUT_H_
-#define POURINPUT_H_
-
-#include "Coin.h"
-#include "ZerocashParams.h"
-
-#include "zcash/IncrementalMerkleTree.hpp"
-
-namespace libzerocash {
-
-class PourInput {
-public:
- PourInput(int tree_depth);
-
- PourInput(Coin old_coin,
- Address old_address,
- const libzcash::MerklePath& path);
-
- Coin old_coin;
- Address old_address;
- size_t merkle_index;
- merkle_authentication_path path;
-};
-
-} /* namespace libzerocash */
-
-#endif /* POURINPUT_H_ */
\ No newline at end of file
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Implementation of interfaces for the class PourOutput.
-
- See PourOutput.h .
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include "PourOutput.h"
-
-namespace libzerocash {
-
-PourOutput::PourOutput(uint64_t val) {
- Address dummy_to_address = Address::CreateNewRandomAddress();
-
- this->to_address = dummy_to_address.getPublicAddress();
- this->new_coin = Coin(dummy_to_address.getPublicAddress(), val);
-}
-
-PourOutput::PourOutput(const Coin new_coin,
- const PublicAddress to_address) : new_coin(new_coin), to_address(to_address) {
-}
-
-} /* namespace libzerocash */
\ No newline at end of file
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of interfaces for the class PourOutput.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef POUROUTPUT_H_
-#define POUROUTPUT_H_
-
-#include "Coin.h"
-#include "ZerocashParams.h"
-
-namespace libzerocash {
-
-class PourOutput {
-public:
- PourOutput(uint64_t val);
- PourOutput(const Coin new_coin,
- const PublicAddress to_address);
-
- Coin new_coin;
- PublicAddress to_address;
-};
-
-} /* namespace libzerocash */
-
-#endif /* POUROUTPUT_H_ */
\ No newline at end of file
+++ /dev/null
-/** @file
-*****************************************************************************
-
-Implementation of interfaces for the class PourProver.
-
-*****************************************************************************
-* @author This file is part of libzerocash, developed by the Zerocash
-* project and contributors (see AUTHORS).
-* @copyright MIT license (see LICENSE file)
-*****************************************************************************/
-
-#include "PourProver.h"
\ No newline at end of file
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of interfaces for the class PourProver.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef POURPROVER_H_
-#define POURPROVER_H_
-
-#include "ZerocashParams.h"
-#include "boost/array.hpp"
-#include "PourTransaction.h"
-#include "CoinCommitment.h"
-
-namespace libzerocash {
-
-class PourProver {
-public:
- static bool VerifyProof(
- ZerocashParams& params,
- const std::vector<unsigned char>& pubkeyHash,
- const std::vector<unsigned char>& rt,
- const uint64_t vpub_old,
- const uint64_t vpub_new,
- const boost::array<std::vector<unsigned char>, 2> serials,
- const boost::array<std::vector<unsigned char>, 2> commitments,
- const boost::array<std::vector<unsigned char>, 2> macs,
- const std::string &zkSNARK
- ) {
- PourTransaction pourtx;
-
- pourtx.version = 1;
- pourtx.publicOldValue.resize(8);
- pourtx.publicNewValue.resize(8);
- convertIntToBytesVector(vpub_old, pourtx.publicOldValue);
- convertIntToBytesVector(vpub_new, pourtx.publicNewValue);
- pourtx.serialNumber_1 = serials[0];
- pourtx.serialNumber_2 = serials[1];
- {
- CoinCommitment cm;
- cm.commitmentValue = commitments[0];
- pourtx.cm_1 = cm;
- }
- {
- CoinCommitment cm;
- cm.commitmentValue = commitments[1];
- pourtx.cm_2 = cm;
- }
- pourtx.MAC_1 = macs[0];
- pourtx.MAC_2 = macs[1];
- pourtx.zkSNARK = zkSNARK;
-
- return pourtx.verify(params, pubkeyHash, rt);
- }
-};
-
-
-}
-
-#endif /* POURPROVER_H_ */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Implementation of interfaces for the class PourTransaction.
-
- See PourTransaction.h .
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include "Zerocash.h"
-#include "PourTransaction.h"
-#include "PourInput.h"
-#include "PourOutput.h"
-
-#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp"
-#include "zerocash_pour_gadget.hpp"
-#include "zerocash_pour_ppzksnark.hpp"
-
-namespace libzerocash {
-
-PourTransaction::PourTransaction(): cm_1(), cm_2() {
-
-}
-
-PourTransaction::PourTransaction(ZerocashParams& params,
- const std::vector<unsigned char>& pubkeyHash,
- const MerkleRootType& rt,
- std::vector<PourInput> inputs,
- std::vector<PourOutput> outputs,
- uint64_t vpub_old,
- uint64_t vpub_new
- ) :
- publicOldValue(ZC_V_SIZE), publicNewValue(ZC_V_SIZE), serialNumber_1(ZC_SN_SIZE), serialNumber_2(ZC_SN_SIZE), MAC_1(ZC_H_SIZE), MAC_2(ZC_H_SIZE)
-{
- if (inputs.size() > 2 || outputs.size() > 2) {
- throw std::length_error("Too many inputs or outputs specified");
- }
-
- while (inputs.size() < 2) {
- // Push a dummy input of value 0.
- inputs.push_back(PourInput(params.getTreeDepth()));
- }
-
- while (outputs.size() < 2) {
- // Push a dummy output of value 0.
- outputs.push_back(PourOutput(0));
- }
-
- init(1,
- params,
- rt,
- inputs[0].old_coin,
- inputs[1].old_coin,
- inputs[0].old_address,
- inputs[1].old_address,
- inputs[0].merkle_index,
- inputs[1].merkle_index,
- inputs[0].path,
- inputs[1].path,
- outputs[0].to_address,
- outputs[1].to_address,
- vpub_old,
- vpub_new,
- pubkeyHash,
- outputs[0].new_coin,
- outputs[1].new_coin);
-}
-
-PourTransaction::PourTransaction(uint16_t version_num,
- ZerocashParams& params,
- const MerkleRootType& rt,
- const Coin& c_1_old,
- const Coin& c_2_old,
- const Address& addr_1_old,
- const Address& addr_2_old,
- const size_t patMerkleIdx_1,
- const size_t patMerkleIdx_2,
- const merkle_authentication_path& patMAC_1,
- const merkle_authentication_path& patMAC_2,
- const PublicAddress& addr_1_new,
- const PublicAddress& addr_2_new,
- uint64_t v_pub_old,
- uint64_t v_pub_new,
- const std::vector<unsigned char>& pubkeyHash,
- const Coin& c_1_new,
- const Coin& c_2_new) :
- publicOldValue(ZC_V_SIZE), publicNewValue(ZC_V_SIZE), serialNumber_1(ZC_SN_SIZE), serialNumber_2(ZC_SN_SIZE), MAC_1(ZC_H_SIZE), MAC_2(ZC_H_SIZE)
-{
- init(version_num, params, rt, c_1_old, c_2_old, addr_1_old, addr_2_old, patMerkleIdx_1, patMerkleIdx_2,
- patMAC_1, patMAC_2, addr_1_new, addr_2_new, v_pub_old, v_pub_new, pubkeyHash, c_1_new, c_2_new);
-}
-
-std::vector<unsigned char> from_uint256(const uint256 &in)
-{
- return std::vector<unsigned char>(in.begin(), in.end());
-}
-
-void PourTransaction::init(uint16_t version_num,
- ZerocashParams& params,
- const MerkleRootType& rt,
- const Coin& c_1_old,
- const Coin& c_2_old,
- const Address& addr_1_old,
- const Address& addr_2_old,
- const size_t patMerkleIdx_1,
- const size_t patMerkleIdx_2,
- const merkle_authentication_path& patMAC_1,
- const merkle_authentication_path& patMAC_2,
- const PublicAddress& addr_1_new,
- const PublicAddress& addr_2_new,
- uint64_t v_pub_old,
- uint64_t v_pub_new,
- const std::vector<unsigned char>& pubkeyHash,
- const Coin& c_1_new,
- const Coin& c_2_new)
-{
- params.loadProvingKey();
- this->version = version_num;
-
- convertIntToBytesVector(v_pub_old, this->publicOldValue);
- convertIntToBytesVector(v_pub_new, this->publicNewValue);
-
- this->cm_1 = c_1_new.getCoinCommitment();
- this->cm_2 = c_2_new.getCoinCommitment();
-
- std::vector<bool> root_bv(ZC_ROOT_SIZE * 8);
- std::vector<bool> addr_pk_new_1_bv(ZC_A_PK_SIZE * 8);
- std::vector<bool> addr_pk_new_2_bv(ZC_A_PK_SIZE * 8);
- std::vector<bool> addr_sk_old_1_bv(ZC_A_SK_SIZE * 8);
- std::vector<bool> addr_sk_old_2_bv(ZC_A_SK_SIZE * 8);
- std::vector<bool> rand_new_1_bv(ZC_R_SIZE * 8);
- std::vector<bool> rand_new_2_bv(ZC_R_SIZE * 8);
- std::vector<bool> rand_old_1_bv(ZC_R_SIZE * 8);
- std::vector<bool> rand_old_2_bv(ZC_R_SIZE * 8);
- std::vector<bool> nonce_new_1_bv(ZC_RHO_SIZE * 8);
- std::vector<bool> nonce_new_2_bv(ZC_RHO_SIZE * 8);
- std::vector<bool> nonce_old_1_bv(ZC_RHO_SIZE * 8);
- std::vector<bool> nonce_old_2_bv(ZC_RHO_SIZE * 8);
- std::vector<bool> val_new_1_bv(ZC_V_SIZE * 8);
- std::vector<bool> val_new_2_bv(ZC_V_SIZE * 8);
- std::vector<bool> val_old_pub_bv(ZC_V_SIZE * 8);
- std::vector<bool> val_new_pub_bv(ZC_V_SIZE * 8);
- std::vector<bool> val_old_1_bv(ZC_V_SIZE * 8);
- std::vector<bool> val_old_2_bv(ZC_V_SIZE * 8);
- std::vector<bool> cm_new_1_bv(ZC_CM_SIZE * 8);
- std::vector<bool> cm_new_2_bv(ZC_CM_SIZE * 8);
-
- convertBytesVectorToVector(rt, root_bv);
-
- convertBytesVectorToVector(c_1_new.getCoinCommitment().getCommitmentValue(), cm_new_1_bv);
- convertBytesVectorToVector(c_2_new.getCoinCommitment().getCommitmentValue(), cm_new_2_bv);
-
- {
- auto a = from_uint256(addr_1_old.getPrivateAddress().getAddressSecret());
- auto b = from_uint256(addr_2_old.getPrivateAddress().getAddressSecret());
-
- convertBytesVectorToVector(a, addr_sk_old_1_bv);
- convertBytesVectorToVector(b, addr_sk_old_2_bv);
- }
-
- {
- auto a = from_uint256(addr_1_new.getPublicAddressSecret());
- auto b = from_uint256(addr_2_new.getPublicAddressSecret());
-
- convertBytesVectorToVector(a, addr_pk_new_1_bv);
- convertBytesVectorToVector(b, addr_pk_new_2_bv);
- }
-
- convertBytesVectorToVector(c_1_old.getR(), rand_old_1_bv);
- convertBytesVectorToVector(c_2_old.getR(), rand_old_2_bv);
-
- convertBytesVectorToVector(c_1_new.getR(), rand_new_1_bv);
- convertBytesVectorToVector(c_2_new.getR(), rand_new_2_bv);
-
- convertBytesVectorToVector(c_1_old.getRho(), nonce_old_1_bv);
- convertBytesVectorToVector(c_2_old.getRho(), nonce_old_2_bv);
-
- convertBytesVectorToVector(c_1_new.getRho(), nonce_new_1_bv);
- convertBytesVectorToVector(c_2_new.getRho(), nonce_new_2_bv);
-
- std::vector<unsigned char> v_old_1_conv(ZC_V_SIZE, 0);
- convertIntToBytesVector(c_1_old.getValue(), v_old_1_conv);
- libzerocash::convertBytesVectorToVector(v_old_1_conv, val_old_1_bv);
-
- std::vector<unsigned char> v_old_2_conv(ZC_V_SIZE, 0);
- convertIntToBytesVector(c_2_old.getValue(), v_old_2_conv);
- libzerocash::convertBytesVectorToVector(v_old_2_conv, val_old_2_bv);
-
- std::vector<unsigned char> v_new_1_conv(ZC_V_SIZE, 0);
- convertIntToBytesVector(c_1_new.getValue(), v_new_1_conv);
- libzerocash::convertBytesVectorToVector(v_new_1_conv, val_new_1_bv);
-
- std::vector<unsigned char> v_new_2_conv(ZC_V_SIZE, 0);
- convertIntToBytesVector(c_2_new.getValue(), v_new_2_conv);
- libzerocash::convertBytesVectorToVector(v_new_2_conv, val_new_2_bv);
-
- convertBytesVectorToVector(this->publicOldValue, val_old_pub_bv);
- convertBytesVectorToVector(this->publicNewValue, val_new_pub_bv);
-
- std::vector<bool> nonce_old_1(ZC_RHO_SIZE * 8);
- copy(nonce_old_1_bv.begin(), nonce_old_1_bv.end(), nonce_old_1.begin());
- nonce_old_1.erase(nonce_old_1.end()-2, nonce_old_1.end());
-
- nonce_old_1.insert(nonce_old_1.begin(), 1);
- nonce_old_1.insert(nonce_old_1.begin(), 0);
-
- std::vector<bool> sn_internal_1;
- concatenateVectors(addr_sk_old_1_bv, nonce_old_1, sn_internal_1);
- std::vector<bool> sn_old_1_bv(ZC_SN_SIZE * 8);
- hashVector(sn_internal_1, sn_old_1_bv);
-
- convertVectorToBytesVector(sn_old_1_bv, this->serialNumber_1);
-
- std::vector<bool> nonce_old_2(ZC_RHO_SIZE * 8);
- copy(nonce_old_2_bv.begin(), nonce_old_2_bv.end(), nonce_old_2.begin());
- nonce_old_2.erase(nonce_old_2.end()-2, nonce_old_2.end());
-
- nonce_old_2.insert(nonce_old_2.begin(), 1);
- nonce_old_2.insert(nonce_old_2.begin(), 0);
-
- std::vector<bool> sn_internal_2;
- concatenateVectors(addr_sk_old_2_bv, nonce_old_2, sn_internal_2);
- std::vector<bool> sn_old_2_bv(ZC_SN_SIZE * 8);
- hashVector(sn_internal_2, sn_old_2_bv);
-
- convertVectorToBytesVector(sn_old_2_bv, this->serialNumber_2);
-
- unsigned char h_S_bytes[ZC_H_SIZE];
- unsigned char pubkeyHash_bytes[ZC_H_SIZE];
- convertBytesVectorToBytes(pubkeyHash, pubkeyHash_bytes);
- SHA256_CTX sha256;
- SHA256_Init(&sha256);
- SHA256_Update(&sha256, pubkeyHash_bytes, ZC_H_SIZE);
- SHA256_Final(h_S_bytes, &sha256);
-
- std::vector<bool> h_S_bv(ZC_H_SIZE * 8);
- convertBytesToVector(h_S_bytes, h_S_bv);
-
- std::vector<bool> h_S_internal1(ZC_H_SIZE * 8);
- convertBytesToVector(h_S_bytes, h_S_internal1);
- h_S_internal1.erase(h_S_internal1.end()-3, h_S_internal1.end());
- std::vector<bool> h_S_internal2 = h_S_internal1;
-
- h_S_internal1.insert(h_S_internal1.begin(), 0);
- h_S_internal1.insert(h_S_internal1.begin(), 0);
- h_S_internal1.insert(h_S_internal1.begin(), 1);
-
- h_S_internal2.insert(h_S_internal2.begin(), 1);
- h_S_internal2.insert(h_S_internal2.begin(), 0);
- h_S_internal2.insert(h_S_internal2.begin(), 1);
-
- std::vector<bool> MAC_1_internal;
- concatenateVectors(addr_sk_old_1_bv, h_S_internal1, MAC_1_internal);
- std::vector<bool> MAC_1_bv(ZC_H_SIZE * 8);
- hashVector(MAC_1_internal, MAC_1_bv);
- convertVectorToBytesVector(MAC_1_bv, this->MAC_1);
-
- std::vector<bool> MAC_2_internal;
- concatenateVectors(addr_sk_old_2_bv, h_S_internal2, MAC_2_internal);
- std::vector<bool> MAC_2_bv(ZC_H_SIZE * 8);
- hashVector(MAC_2_internal, MAC_2_bv);
- convertVectorToBytesVector(MAC_2_bv, this->MAC_2);
-
- if(this->version > 0){
- auto proofObj = zerocash_pour_ppzksnark_prover<ZerocashParams::zerocash_pp>(params.getProvingKey(),
- { patMAC_1, patMAC_2 },
- { patMerkleIdx_1, patMerkleIdx_2 },
- root_bv,
- { addr_pk_new_1_bv, addr_pk_new_2_bv },
- { addr_sk_old_1_bv, addr_sk_old_2_bv },
- { rand_new_1_bv, rand_new_2_bv },
- { rand_old_1_bv, rand_old_2_bv },
- { nonce_new_1_bv, nonce_new_2_bv },
- { nonce_old_1_bv, nonce_old_2_bv },
- { val_new_1_bv, val_new_2_bv },
- val_old_pub_bv,
- val_new_pub_bv,
- { val_old_1_bv, val_old_2_bv },
- h_S_bv);
-
- std::stringstream ss;
- ss << proofObj;
- this->zkSNARK = ss.str();
- } else {
- this->zkSNARK = std::string(1235,'A');
- }
-
- // TODO: when h_Sig is constructed properly as per spec
- // replace uint256() with it
- ZCNoteEncryption encryptor = ZCNoteEncryption(uint256());
- {
- std::vector<unsigned char> plaintext_internals;
- plaintext_internals.insert(plaintext_internals.end(), c_1_new.coinValue.begin(), c_1_new.coinValue.end());
- plaintext_internals.insert(plaintext_internals.end(), c_1_new.r.begin(), c_1_new.r.end());
- plaintext_internals.insert(plaintext_internals.end(), c_1_new.rho.begin(), c_1_new.rho.end());
-
- std::vector<unsigned char> memo(ZC_MEMO_SIZE, 0x00);
- plaintext_internals.insert(plaintext_internals.end(), memo.begin(), memo.end());
-
- // This is all going away.
- assert(plaintext_internals.size() >= 201);
-
- boost::array<unsigned char, 201> pt;
- memcpy(&pt[0], &plaintext_internals[0], 201);
-
- this->ciphertext_1 = encryptor.encrypt(addr_1_new.getEncryptionPublicKey(),
- pt);
- }
- {
- std::vector<unsigned char> plaintext_internals;
- plaintext_internals.insert(plaintext_internals.end(), c_2_new.coinValue.begin(), c_2_new.coinValue.end());
- plaintext_internals.insert(plaintext_internals.end(), c_2_new.r.begin(), c_2_new.r.end());
- plaintext_internals.insert(plaintext_internals.end(), c_2_new.rho.begin(), c_2_new.rho.end());
-
- std::vector<unsigned char> memo(ZC_MEMO_SIZE, 0x00);
- plaintext_internals.insert(plaintext_internals.end(), memo.begin(), memo.end());
-
- // This is all going away.
- assert(plaintext_internals.size() >= 201);
-
- boost::array<unsigned char, 201> pt;
- memcpy(&pt[0], &plaintext_internals[0], 201);
-
- this->ciphertext_2 = encryptor.encrypt(addr_2_new.getEncryptionPublicKey(),
- pt);
- }
-
- this->ephemeralKey = encryptor.get_epk();
-}
-
-bool PourTransaction::verify(ZerocashParams& params,
- const std::vector<unsigned char> &pubkeyHash,
- const MerkleRootType &merkleRoot) const
-{
- if(this->version == 0){
- return true;
- }
-
- zerocash_pour_proof<ZerocashParams::zerocash_pp> proof_SNARK;
- std::stringstream ss;
- ss.str(this->zkSNARK);
- ss >> proof_SNARK;
-
- if (merkleRoot.size() != ZC_ROOT_SIZE) { return false; }
- if (pubkeyHash.size() != ZC_H_SIZE) { return false; }
- if (this->serialNumber_1.size() != ZC_SN_SIZE) { return false; }
- if (this->serialNumber_2.size() != ZC_SN_SIZE) { return false; }
- if (this->publicOldValue.size() != ZC_V_SIZE) { return false; }
- if (this->publicNewValue.size() != ZC_V_SIZE) { return false; }
- if (this->MAC_1.size() != ZC_H_SIZE) { return false; }
- if (this->MAC_2.size() != ZC_H_SIZE) { return false; }
-
- std::vector<bool> root_bv(ZC_ROOT_SIZE * 8);
- std::vector<bool> sn_old_1_bv(ZC_SN_SIZE * 8);
- std::vector<bool> sn_old_2_bv(ZC_SN_SIZE * 8);
- std::vector<bool> cm_new_1_bv(ZC_CM_SIZE * 8);
- std::vector<bool> cm_new_2_bv(ZC_CM_SIZE * 8);
- std::vector<bool> val_old_pub_bv(ZC_V_SIZE * 8);
- std::vector<bool> val_new_pub_bv(ZC_V_SIZE * 8);
- std::vector<bool> MAC_1_bv(ZC_H_SIZE * 8);
- std::vector<bool> MAC_2_bv(ZC_H_SIZE * 8);
-
- convertBytesVectorToVector(merkleRoot, root_bv);
- convertBytesVectorToVector(this->serialNumber_1, sn_old_1_bv);
- convertBytesVectorToVector(this->serialNumber_2, sn_old_2_bv);
- convertBytesVectorToVector(this->cm_1.getCommitmentValue(), cm_new_1_bv);
- convertBytesVectorToVector(this->cm_2.getCommitmentValue(), cm_new_2_bv);
- convertBytesVectorToVector(this->publicOldValue, val_old_pub_bv);
- convertBytesVectorToVector(this->publicNewValue, val_new_pub_bv);
- convertBytesVectorToVector(this->MAC_1, MAC_1_bv);
- convertBytesVectorToVector(this->MAC_2, MAC_2_bv);
-
- unsigned char h_S_bytes[ZC_H_SIZE];
- unsigned char pubkeyHash_bytes[ZC_H_SIZE];
- convertBytesVectorToBytes(pubkeyHash, pubkeyHash_bytes);
- SHA256_CTX sha256;
- SHA256_Init(&sha256);
- SHA256_Update(&sha256, pubkeyHash_bytes, ZC_H_SIZE);
- SHA256_Final(h_S_bytes, &sha256);
-
- std::vector<bool> h_S_internal(ZC_H_SIZE * 8);
- convertBytesToVector(h_S_bytes, h_S_internal);
- h_S_internal.erase(h_S_internal.end()-2, h_S_internal.end());
- h_S_internal.insert(h_S_internal.begin(), 0);
- h_S_internal.insert(h_S_internal.begin(), 1);
-
- std::vector<bool> h_S_bv(ZC_H_SIZE * 8);
- convertBytesToVector(h_S_bytes, h_S_bv);
-
- bool snark_result = zerocash_pour_ppzksnark_verifier<ZerocashParams::zerocash_pp>(params.getVerificationKey(),
- root_bv,
- { sn_old_1_bv, sn_old_2_bv },
- { cm_new_1_bv, cm_new_2_bv },
- val_old_pub_bv,
- val_new_pub_bv,
- h_S_bv,
- { MAC_1_bv, MAC_2_bv },
- proof_SNARK);
-
- return snark_result;
-}
-
-const std::vector<unsigned char>& PourTransaction::getSpentSerial1() const{
- return this->serialNumber_1;
-}
-
-const std::vector<unsigned char>& PourTransaction::getSpentSerial2() const{
- return this->serialNumber_2;
-}
-
-const ZCNoteEncryption::Ciphertext& PourTransaction::getCiphertext1() const {
- return this->ciphertext_1;
-}
-
-const ZCNoteEncryption::Ciphertext& PourTransaction::getCiphertext2() const {
- return this->ciphertext_2;
-}
-
-/**
- * Returns the hash of the first new coin commitment output by this Pour.
- */
-const CoinCommitmentValue& PourTransaction::getNewCoinCommitmentValue1() const{
- return this->cm_1.getCommitmentValue();
-}
-
-/**
- * Returns the hash of the second new coin commitment output by this Pour.
- */
-const CoinCommitmentValue& PourTransaction::getNewCoinCommitmentValue2() const{
- return this->cm_2.getCommitmentValue();
-}
-
-uint64_t PourTransaction::getPublicValueIn() const{
- return convertBytesVectorToInt(this->publicOldValue);
-}
-
-uint64_t PourTransaction::getPublicValueOut() const{
- return convertBytesVectorToInt(this->publicNewValue);
-}
-
-} /* namespace libzerocash */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of interfaces for the class PourTransaction.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef POURTRANSACTION_H_
-#define POURTRANSACTION_H_
-
-#include "Coin.h"
-#include "ZerocashParams.h"
-#include "Zerocash.h"
-#include "PourInput.h"
-#include "PourOutput.h"
-#include <stdexcept>
-#include <bitset>
-
-#include <boost/array.hpp>
-
-#include "uint256.h"
-#include "zcash/NoteEncryption.hpp"
-
-typedef std::vector<unsigned char> CoinCommitmentValue;
-
-namespace libzerocash {
-
-/***************************** Pour transaction ******************************/
-
-class PourTransaction {
-friend class PourProver;
-public:
- PourTransaction();
- PourTransaction(ZerocashParams& params,
- const std::vector<unsigned char>& pubkeyHash,
- const MerkleRootType& rt,
- const std::vector<PourInput> inputs,
- const std::vector<PourOutput> outputs,
- uint64_t vpub_old,
- uint64_t vpub_new
- );
- /**
- * Generates a transaction pouring the funds in two existing coins into two new coins and optionally
- * converting some of those funds back into the base currency.
- *
- *
- * @param version_num the version of the transaction to create
- * @param params the cryptographic parameters used to generate the proofs.
- * @param root the root of the merkle tree containing the two existing coins
- * @param c_1_old the first existing coin
- * @param c_2_old the second existing coin
- * @param addr_1_old the address the first coin was paid to
- * @param addr_2_old the address the second coin was paid to
- * @param path_1 path showing that first coin is in the merkle tree rooted at root
- * @param path_2 path showing that the second coin is n the merkle tree rooted at root
- * @param addr_1_new the public address to pay the first new coin to
- * @param addr_2_new the public address to pay the second new coin to
- * @param v_pub the amount of funds to convert back to the base currency
- * @param pubkeyHash the hash of a public key to bind into the transaction
- * @param c_1_new the first of the new coins the funds are being poured into
- * @param c_2_new the second of the new coins the funds are being poured into
- */
- PourTransaction(uint16_t version_num,
- ZerocashParams& params,
- const MerkleRootType& roott,
- const Coin& c_1_old,
- const Coin& c_2_old,
- const Address& addr_1_old,
- const Address& addr_2_old,
- const size_t patMerkleIdx_1,
- const size_t patMerkleIdx_2,
- const merkle_authentication_path& path_1,
- const merkle_authentication_path& path_2,
- const PublicAddress& addr_1_new,
- const PublicAddress& addr_2_new,
- uint64_t v_pub_in,
- uint64_t v_pub_out,
- const std::vector<unsigned char>& pubkeyHash,
- const Coin& c_1_new,
- const Coin& c_2_new);
-
- void init(uint16_t version_num,
- ZerocashParams& params,
- const MerkleRootType& roott,
- const Coin& c_1_old,
- const Coin& c_2_old,
- const Address& addr_1_old,
- const Address& addr_2_old,
- const size_t patMerkleIdx_1,
- const size_t patMerkleIdx_2,
- const merkle_authentication_path& path_1,
- const merkle_authentication_path& path_2,
- const PublicAddress& addr_1_new,
- const PublicAddress& addr_2_new,
- uint64_t v_pub_in,
- uint64_t v_pub_out,
- const std::vector<unsigned char>& pubkeyHash,
- const Coin& c_1_new,
- const Coin& c_2_new);
-
- /**
- * Verifies the pour transaction.
- *
- * @param params the cryptographic parameters used to verify the proofs.
- * @param pubkeyHash the hash of a public key that we verify is bound to the transaction
- * @param merkleRoot the root of the merkle tree the coins were in.
- * @return ture if correct, false otherwise.
- */
- bool verify(ZerocashParams& params,
- const std::vector<unsigned char> &pubkeyHash,
- const MerkleRootType &merkleRoot) const;
-
- const std::vector<unsigned char>& getSpentSerial1() const;
- const std::vector<unsigned char>& getSpentSerial2() const;
- const ZCNoteEncryption::Ciphertext& getCiphertext1() const;
- const ZCNoteEncryption::Ciphertext& getCiphertext2() const;
-
- /**
- * Returns the hash of the first new coin generated by this Pour.
- *
- * @return the coin hash
- */
- const CoinCommitmentValue& getNewCoinCommitmentValue1() const;
-
- /**
- * Returns the hash of the second new coin generated by this Pour.
- *
- * @return the coin hash
- */
- const CoinCommitmentValue& getNewCoinCommitmentValue2() const;
-
- uint64_t getPublicValueIn() const;
-
- uint64_t getPublicValueOut() const;
-
- std::string unpack(boost::array<std::vector<unsigned char>, 2>& serials,
- boost::array<std::vector<unsigned char>, 2>& commitments,
- boost::array<std::vector<unsigned char>, 2>& macs,
- boost::array<ZCNoteEncryption::Ciphertext, 2>& ciphertexts,
- uint256& epk
- ) const {
- serials[0] = this->serialNumber_1;
- serials[1] = this->serialNumber_2;
- commitments[0] = this->cm_1.getCommitmentValue();
- commitments[1] = this->cm_2.getCommitmentValue();
- macs[0] = this->MAC_1;
- macs[1] = this->MAC_2;
- ciphertexts[0] = this->ciphertext_1;
- ciphertexts[1] = this->ciphertext_2;
- epk = this->ephemeralKey;
-
- return this->zkSNARK;
- }
-
- // just hashes a few fields to see if integrity is correct.
- // useful for debugging since there's such bad error handling
- // currently
- void debug_print() {
- #define DEBUG_PRINT_POUR_FIELD(X, NAME) {\
- std::hash<std::string> h; \
- std::cout << NAME << ": " << h(std::string(X.begin(), X.end())) << std::endl;\
- }
-
- DEBUG_PRINT_POUR_FIELD(publicOldValue, "publicOldValue");
- DEBUG_PRINT_POUR_FIELD(publicNewValue, "publicNewValue");
- DEBUG_PRINT_POUR_FIELD(serialNumber_1, "serialNumber_1");
- DEBUG_PRINT_POUR_FIELD(serialNumber_2, "serialNumber_2");
- {
- auto v = cm_1.getCommitmentValue();
- DEBUG_PRINT_POUR_FIELD(v, "cm_1");
- }
- {
- auto v = cm_2.getCommitmentValue();
- DEBUG_PRINT_POUR_FIELD(v, "cm_2");
- }
- DEBUG_PRINT_POUR_FIELD(MAC_1, "MAC_1");
- DEBUG_PRINT_POUR_FIELD(MAC_2, "MAC_2");
-
- }
-
-private:
-
- std::vector<unsigned char> publicOldValue; // public input value of the Pour transaction
- std::vector<unsigned char> publicNewValue; // public output value of the Pour transaction
- std::vector<unsigned char> serialNumber_1; // serial number of input (old) coin #1
- std::vector<unsigned char> serialNumber_2; // serial number of input (old) coin #1
- CoinCommitment cm_1; // coin commitment for output coin #1
- CoinCommitment cm_2; // coin commitment for output coin #2
- std::vector<unsigned char> MAC_1; // first MAC (h_1 in paper notation)
- std::vector<unsigned char> MAC_2; // second MAC (h_2 in paper notation)
- ZCNoteEncryption::Ciphertext ciphertext_1; // ciphertext #1
- ZCNoteEncryption::Ciphertext ciphertext_2; // ciphertext #2
- uint256 ephemeralKey; // epk
- std::string zkSNARK; // contents of the zkSNARK proof itself
- uint16_t version; // version for the Pour transaction
-};
-
-} /* namespace libzerocash */
-
-#endif /* POURTRANSACTION_H_ */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of exceptions and constants for Zerocash.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef ZEROCASH_H_
-#define ZEROCASH_H_
-
-#include <stdexcept>
-#include <vector>
-
-/* The version of this library. */
-#define ZEROCASH_VERSION_STRING "0.1"
-#define ZEROCASH_VERSION_INT 1
-#define ZEROCASH_PROTOCOL_VERSION "1"
-#define ZEROCASH_DEFAULT_TREE_SIZE 64
-
-#define ZC_A_PK_SIZE 32
-#define ZC_PK_ENC_SIZE 311
-#define ZC_SIG_PK_SIZE 32
-#define ZC_ADDR_PK_SIZE (ZC_A_PK_SIZE+ZC_PK_ENC_SIZE)
-
-#define ZC_A_SK_SIZE 32
-#define ZC_SK_ENC_SIZE 287
-#define ZC_ADDR_SK_SIZE (ZC_A_SK_SIZE+ZC_SK_ENC_SIZE)
-
-#define ZC_V_SIZE 8
-#define ZC_RHO_SIZE 32
-#define ZC_R_SIZE 48
-#define ZC_MEMO_SIZE 128
-#define ZC_S_SIZE 0
-#define ZC_K_SIZE 32
-#define ZC_CM_SIZE 32
-#define ZC_COIN_SIZE (ZC_ADDR_PK_SIZE+ZC_V_SIZE+ZC_RHO_SIZE+ZC_R_SIZE+ZC_S_SIZE+ZC_CM_SIZE)
-#define ZC_TX_MINT_SIZE (ZC_CM_SIZE+ZC_V_SIZE+ZC_K_SIZE+ZC_S_SIZE)
-
-#define ZC_ROOT_SIZE 32
-#define ZC_SN_SIZE 32
-#define ZC_PK_SIG_SIZE 66
-#define ZC_H_SIZE 32
-#define ZC_POUR_PROOF_SIZE 288
-#define ZC_C_SIZE 173
-#define ZC_SIGMA_SIZE 72
-#define ZC_TX_POUR_SIZE (ZC_ROOT_SIZE+(2*ZC_SN_SIZE)+(2*ZC_CM_SIZE)+ZC_V_SIZE+ZC_PK_SIG_SIZE+(2*ZC_H_SIZE)+ZC_POUR_PROOF_SIZE+(2*ZC_C_SIZE)+ZC_SIGMA_SIZE)
-
-#define SNARK
-
-typedef std::vector<unsigned char> MerkleRootType;
-
-namespace libsnark {
-};
-
-namespace libzerocash {
- using namespace libsnark;
-};
-
-#include "zerocash/utils/util.h"
-
-#endif /* ZEROCASH_H_ */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Implementation of interfaces for the class ZerocashParams.
-
- See ZerocashParams.h .
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include <fstream>
-#include <boost/format.hpp>
-
-#include "Zerocash.h"
-#include "ZerocashParams.h"
-
-static void throw_missing_param_file_exception(std::string paramtype, std::string path) {
- /* paramtype should be either "proving" or "verifying". */
- const char* tmpl = ("Could not open %s key file: %s\n"
- "Please refer to user documentation for installing this file.");
- throw std::runtime_error((boost::format(tmpl) % paramtype % path).str());
-}
-
-namespace libzerocash {
-
-int ZerocashParams::getTreeDepth()
-{
- return treeDepth;
-}
-
-zerocash_pour_keypair<ZerocashParams::zerocash_pp> ZerocashParams::GenerateNewKeyPair(const unsigned int tree_depth)
-{
- libzerocash::ZerocashParams::zerocash_pp::init_public_params();
- libzerocash::zerocash_pour_keypair<libzerocash::ZerocashParams::zerocash_pp> kp_v1 =
- libzerocash::zerocash_pour_ppzksnark_generator<libzerocash::ZerocashParams::zerocash_pp>(
- libzerocash::ZerocashParams::numPourInputs,
- libzerocash::ZerocashParams::numPourOutputs,
- tree_depth
- );
- return kp_v1;
-}
-
-void ZerocashParams::SaveProvingKeyToFile(const zerocash_pour_proving_key<ZerocashParams::zerocash_pp>* p_pk_1, std::string path)
-{
- std::stringstream ssProving;
- ssProving << p_pk_1->r1cs_pk;
- std::ofstream pkFilePtr;
- pkFilePtr.open(path, std::ios::binary);
- ssProving.rdbuf()->pubseekpos(0, std::ios_base::out);
- pkFilePtr << ssProving.rdbuf();
- pkFilePtr.flush();
- pkFilePtr.close();
-}
-
-
-void ZerocashParams::SaveVerificationKeyToFile(const zerocash_pour_verification_key<ZerocashParams::zerocash_pp>* p_vk_1, std::string path)
-{
- std::stringstream ssVerification;
- ssVerification << p_vk_1->r1cs_vk;
- std::ofstream vkFilePtr;
- vkFilePtr.open(path, std::ios::binary);
- ssVerification.rdbuf()->pubseekpos(0, std::ios_base::out);
- vkFilePtr << ssVerification.rdbuf();
- vkFilePtr.flush();
- vkFilePtr.close();
-}
-
-zerocash_pour_proving_key<ZerocashParams::zerocash_pp> ZerocashParams::LoadProvingKeyFromFile(std::string path, const unsigned int tree_depth)
-{
- std::stringstream ssProving;
- std::ifstream fileProving(path, std::ios::binary);
-
- if(!fileProving.is_open()) {
- throw_missing_param_file_exception("proving", path);
- }
-
- ssProving << fileProving.rdbuf();
- fileProving.close();
-
- ssProving.rdbuf()->pubseekpos(0, std::ios_base::in);
-
- r1cs_ppzksnark_proving_key<ZerocashParams::zerocash_pp> pk_temp;
- ssProving >> pk_temp;
-
- return zerocash_pour_proving_key<ZerocashParams::zerocash_pp>(
- libzerocash::ZerocashParams::numPourInputs,
- libzerocash::ZerocashParams::numPourOutputs,
- tree_depth,
- std::move(pk_temp)
- );
-}
-
-zerocash_pour_verification_key<ZerocashParams::zerocash_pp> ZerocashParams::LoadVerificationKeyFromFile(std::string path, const unsigned int tree_depth)
-{
- std::stringstream ssVerification;
- std::ifstream fileVerification(path, std::ios::binary);
-
- if(!fileVerification.is_open()) {
- throw_missing_param_file_exception("verification", path);
- }
-
- ssVerification << fileVerification.rdbuf();
- fileVerification.close();
-
- ssVerification.rdbuf()->pubseekpos(0, std::ios_base::in);
-
- r1cs_ppzksnark_verification_key<ZerocashParams::zerocash_pp> vk_temp;
- ssVerification >> vk_temp;
-
- return zerocash_pour_verification_key<ZerocashParams::zerocash_pp>(
- libzerocash::ZerocashParams::numPourInputs,
- libzerocash::ZerocashParams::numPourOutputs,
- std::move(vk_temp)
- );
-}
-
-ZerocashParams::ZerocashParams(
- const unsigned int tree_depth,
- zerocash_pour_keypair<ZerocashParams::zerocash_pp> *keypair
-) :
- treeDepth(tree_depth)
-{
- params_pk_v1 = new zerocash_pour_proving_key<ZerocashParams::zerocash_pp>(keypair->pk);
- params_vk_v1 = new zerocash_pour_verification_key<ZerocashParams::zerocash_pp>(keypair->vk);
-}
-
-ZerocashParams::ZerocashParams(
- const unsigned int tree_depth,
- std::string proving_key_path,
- zerocash_pour_verification_key<ZerocashParams::zerocash_pp>* p_vk_1
-) :
- treeDepth(tree_depth), provingKeyPath(proving_key_path)
-{
- params_vk_v1 = new zerocash_pour_verification_key<ZerocashParams::zerocash_pp>(*p_vk_1);
- params_pk_v1 = NULL;
-}
-
-ZerocashParams::ZerocashParams(
- const unsigned int tree_depth,
- zerocash_pour_proving_key<ZerocashParams::zerocash_pp>* p_pk_1,
- zerocash_pour_verification_key<ZerocashParams::zerocash_pp>* p_vk_1
-) :
- treeDepth(tree_depth)
-{
- assert(p_pk_1 != NULL || p_vk_1 != NULL);
-
- if (p_pk_1 == NULL) {
- params_pk_v1 = NULL;
- } else {
- params_pk_v1 = new zerocash_pour_proving_key<ZerocashParams::zerocash_pp>(*p_pk_1);
- }
-
- if (p_vk_1 == NULL) {
- params_vk_v1 = NULL;
- } else {
- params_vk_v1 = new zerocash_pour_verification_key<ZerocashParams::zerocash_pp>(*p_vk_1);
- }
-}
-
-ZerocashParams::~ZerocashParams()
-{
- if (params_pk_v1 != NULL) {
- delete params_pk_v1;
- }
- if (params_vk_v1 != NULL) {
- delete params_vk_v1;
- }
-}
-
-const zerocash_pour_proving_key<ZerocashParams::zerocash_pp>& ZerocashParams::getProvingKey()
-{
- if (params_pk_v1 != NULL) {
- return *params_pk_v1;
- } else {
- throw std::runtime_error("Pour proving key not set.");
- }
-}
-
-const zerocash_pour_verification_key<ZerocashParams::zerocash_pp>& ZerocashParams::getVerificationKey()
-{
- if (params_vk_v1 != NULL) {
- return *params_vk_v1;
- } else {
- throw std::runtime_error("Pour verification key not set.");
- }
-}
-
-} /* namespace libzerocash */
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of interfaces for the class ZerocashParams.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef PARAMS_H_
-#define PARAMS_H_
-
-#include "Zerocash.h"
-#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp"
-#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp"
-#include "zerocash_pour_ppzksnark.hpp"
-
-namespace libzerocash {
-
-class ZerocashParams {
-
-public:
- typedef default_r1cs_ppzksnark_pp zerocash_pp;
-
- ZerocashParams(
- const unsigned int tree_depth,
- zerocash_pour_keypair<ZerocashParams::zerocash_pp> *keypair
- );
-
- ZerocashParams(
- const unsigned int tree_depth,
- zerocash_pour_proving_key<ZerocashParams::zerocash_pp>* p_pk_1,
- zerocash_pour_verification_key<ZerocashParams::zerocash_pp>* p_vk_1
- );
-
- ZerocashParams(
- const unsigned int tree_depth,
- std::string proving_key_path,
- zerocash_pour_verification_key<ZerocashParams::zerocash_pp>* p_vk_1
- );
-
- const zerocash_pour_proving_key<zerocash_pp>& getProvingKey();
- const zerocash_pour_verification_key<zerocash_pp>& getVerificationKey();
- int getTreeDepth();
- ~ZerocashParams();
-
- static const size_t numPourInputs = 2;
- static const size_t numPourOutputs = 2;
-
- static zerocash_pour_keypair<ZerocashParams::zerocash_pp> GenerateNewKeyPair(const unsigned int tree_depth);
-
- static void SaveProvingKeyToFile(const zerocash_pour_proving_key<ZerocashParams::zerocash_pp>* p_pk_1, std::string path);
- static void SaveVerificationKeyToFile(const zerocash_pour_verification_key<ZerocashParams::zerocash_pp>* p_vk_1, std::string path);
- static zerocash_pour_proving_key<ZerocashParams::zerocash_pp> LoadProvingKeyFromFile(std::string path, const unsigned int tree_depth);
- static zerocash_pour_verification_key<ZerocashParams::zerocash_pp> LoadVerificationKeyFromFile(std::string path, const unsigned int tree_depth);
-
- void loadProvingKey()
- {
- if (params_pk_v1 == NULL) {
- std::cout << "loading proving key from path: " << provingKeyPath << std::endl;
- params_pk_v1 = new zerocash_pour_proving_key<ZerocashParams::zerocash_pp>(
- LoadProvingKeyFromFile(provingKeyPath, treeDepth));
- std::cout << "done loading proving key!" << std::endl;
- }
- }
-private:
- int treeDepth;
- zerocash_pour_proving_key<ZerocashParams::zerocash_pp>* params_pk_v1;
- zerocash_pour_verification_key<ZerocashParams::zerocash_pp>* params_vk_v1;
- std::string provingKeyPath;
-};
-
-} /* namespace libzerocash */
-
-#endif /* PARAMS_H_ */
+++ /dev/null
-/** @file
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp"
-#include "libsnark/common/profiling.hpp"
-#include "zerocash_pour_ppzksnark/zerocash_pour_gadget.hpp"
-
-using namespace libsnark;
-
-int main(int argc, const char* argv[])
-{
- start_profiling();
- default_r1cs_ppzksnark_pp::init_public_params();
-#ifndef DEBUG
- printf("this program needs to be compiled with constraint annotations (make debug/make cppdebug)\n");
- return 2;
-#else
- if (argc != 4)
- {
- printf("usage: %s num_old_coins num_new_coins tree_depth\n", argv[0]);
- return 1;
- }
-
-
- int num_old_coins = atoi(argv[1]);
- int num_new_coins = atoi(argv[2]);
- int tree_depth = atoi(argv[3]);
- protoboard<Fr<default_r1cs_ppzksnark_pp> > pb;
- libzerocash::zerocash_pour_gadget<Fr<default_r1cs_ppzksnark_pp> > g(pb, num_old_coins, num_new_coins, tree_depth, "pour");
- g.generate_r1cs_constraints();
- for (auto it : pb.get_constraint_system().constraint_annotations)
- {
- printf("%s\n", it.second.c_str());
- }
-#endif
-}
+++ /dev/null
-/** @file
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include <algorithm>
-#include <random>
-#include <set>
-#include <vector>
-
-#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp"
-#include "libsnark/common/data_structures/merkle_tree.hpp"
-#include "libsnark/common/utils.hpp"
-#include "libsnark/common/profiling.hpp"
-#include "libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp"
-#include "zerocash/zerocash_pour_gadget.hpp"
-#include "zerocash/zerocash_pour_ppzksnark.hpp"
-
-using namespace libzerocash;
-
-bit_vector int_to_bit_vector(const size_t value, const size_t length)
-{
- /* the returned result will have 0-th position equal to MSB of
- `value`, when written as `length`-bit integer */
-
- assert(log2(value) < length);
- bit_vector result(length, false);
-
- for (size_t i = 0; i < length; ++i)
- {
- result[length-1-i] = ((value >> i) & 1) ? true : false;
- }
-
- return result;
-}
-
-bit_vector get_random_bit_vector(const size_t length)
-{
- bit_vector result(length);
- std::generate(result.begin(), result.end(), [] { return std::rand() % 2; });
- return result;
-}
-
-std::vector<size_t> sample_random_positions(const size_t num_positions, const size_t log2_universe_size)
-{
- /* not asymptotically optimal, but likely not to be a problem in
- practice, where num_positions is much smaller than
- universe_size */
- assert(log2(num_positions) <= log2_universe_size);
- assert(log2_universe_size <= 8 * sizeof(size_t));
- std::set<size_t> positions;
- std::vector<size_t> result;
- while (positions.size() != num_positions)
- {
- size_t new_pos = std::rand();
- if (log2_universe_size < 8 * sizeof(size_t))
- {
- new_pos &= ((1ul << log2_universe_size) - 1); /* clear higher bits appropriately */
- }
- if (positions.find(new_pos) == positions.end())
- {
- positions.insert(new_pos);
- result.emplace_back(new_pos);
- }
- }
-
- return result;
-}
-
-template<typename FieldT>
-bit_vector compute_coin_commitment(const bit_vector &address_public_key,
- const bit_vector &coin_value,
- const bit_vector &serial_number_nonce,
- const bit_vector &address_commitment_nonce)
-{
- /* commitment_to_address_public_key = H(address_public_key || serial_number_nonce) */
- bit_vector commitment_to_address_public_key_hash_input;
- commitment_to_address_public_key_hash_input.insert(commitment_to_address_public_key_hash_input.end(),
- address_public_key.begin(),
- address_public_key.end());
- commitment_to_address_public_key_hash_input.insert(commitment_to_address_public_key_hash_input.end(),
- serial_number_nonce.begin(),
- serial_number_nonce.end());
- const bit_vector commitment_to_address_public_key = sha256_two_to_one_hash_gadget<FieldT>::get_hash(commitment_to_address_public_key_hash_input);
-
- /* coin_value_commitment_nonce = H(address_commitment_nonce || commitment_to_address_public_key[0..128]) */
- bit_vector coin_value_commitment_nonce_hash_input;
- coin_value_commitment_nonce_hash_input.insert(coin_value_commitment_nonce_hash_input.end(),
- address_commitment_nonce.begin(),
- address_commitment_nonce.end());
- coin_value_commitment_nonce_hash_input.insert(coin_value_commitment_nonce_hash_input.end(),
- commitment_to_address_public_key.begin(),
- commitment_to_address_public_key.begin() + truncated_coin_commitment_length);
-
- const bit_vector coin_value_commitment_nonce = sha256_two_to_one_hash_gadget<FieldT>::get_hash(coin_value_commitment_nonce_hash_input);
-
- /* coin_commitment = H(coin_value_commitment_nonce || 0^{192} || coin_value) */
- bit_vector coin_commitment_hash_input;
- coin_commitment_hash_input.insert(coin_commitment_hash_input.end(),
- coin_value_commitment_nonce.begin(),
- coin_value_commitment_nonce.end());
- coin_commitment_hash_input.resize(coin_commitment_hash_input.size() + coin_commitment_padding_length, false);
- coin_commitment_hash_input.insert(coin_commitment_hash_input.end(),
- coin_value.begin(),
- coin_value.end());
- const bit_vector coin_commitment = sha256_two_to_one_hash_gadget<FieldT>::get_hash(coin_commitment_hash_input);
-
- return coin_commitment;
-}
-
-std::vector<size_t> randomly_split_up_value(const size_t value, const size_t num_parts)
-{
- std::vector<size_t> points(num_parts-1);
- std::generate(points.begin(), points.end(), [value] { return std::rand() % value; });
- points.emplace_back(0);
- points.emplace_back(value);
- std::sort(points.begin(), points.end()); /* now points is a num_parts+1-length vector with endpoints of 0 and value */
-
- std::vector<size_t> result(num_parts);
- for (size_t i = 0; i < num_parts; ++i)
- {
- result[i] = points[i+1] - points[i];
- }
- /* the resulting sum telescopes to value-0 = value */
-
- return result;
-}
-
-template<typename ppT>
-void test_zerocash_pour_ppzksnark(const size_t num_old_coins, const size_t num_new_coins, const size_t tree_depth)
-{
- typedef Fr<ppT> FieldT;
-
- assert(log2(num_old_coins) <= tree_depth);
-
- /* information used by the prover in the witness map */
- std::vector<merkle_authentication_path> old_coin_authentication_paths(num_old_coins); //
- std::vector<size_t> old_coin_merkle_tree_positions; //
- bit_vector merkle_tree_root; //
- std::vector<bit_vector> new_address_public_keys(num_new_coins); //
- std::vector<bit_vector> old_address_secret_keys(num_old_coins); //
- std::vector<bit_vector> new_address_commitment_nonces(num_new_coins); //
- std::vector<bit_vector> old_address_commitment_nonces(num_old_coins); //
- std::vector<bit_vector> new_coin_serial_number_nonces(num_new_coins); //
- std::vector<bit_vector> old_coin_serial_number_nonces(num_old_coins); //
- std::vector<bit_vector> new_coin_values(num_new_coins); //
- bit_vector public_in_value; //
- bit_vector public_out_value; //
- std::vector<bit_vector> old_coin_values(num_old_coins); //
- bit_vector signature_public_key_hash; //
-
- /* generate split for the money */
- std::vector<size_t> old_coin_values_as_integers(num_old_coins);
- std::generate(old_coin_values_as_integers.begin(), old_coin_values_as_integers.end(), [] { return std::rand() % 10000; });
- const size_t total_value_as_integer = std::accumulate(old_coin_values_as_integers.begin(), old_coin_values_as_integers.end(), 0);
- std::vector<size_t> all_new_values_as_integers = randomly_split_up_value(total_value_as_integer, num_new_coins + 1);
-
- std::transform(old_coin_values_as_integers.begin(), old_coin_values_as_integers.end(),
- old_coin_values.begin(),
- [] (const size_t value) { return int_to_bit_vector(value, coin_value_length); });
- public_in_value = int_to_bit_vector(0, coin_value_length);
- public_out_value = int_to_bit_vector(all_new_values_as_integers[0], coin_value_length);
- std::transform(all_new_values_as_integers.begin() + 1, all_new_values_as_integers.end(),
- new_coin_values.begin(),
- [] (const size_t value) { return int_to_bit_vector(value, coin_value_length); });
-
- /* generate random private values for the prover */
- old_coin_merkle_tree_positions = sample_random_positions(num_old_coins, tree_depth);
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- old_address_secret_keys[i] = get_random_bit_vector(address_secret_key_length);
- old_address_commitment_nonces[i] = get_random_bit_vector(address_commitment_nonce_length);
- old_coin_serial_number_nonces[i] = get_random_bit_vector(serial_number_nonce_length);
- }
-
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- new_address_public_keys[i] = get_random_bit_vector(address_public_key_length);
- new_address_commitment_nonces[i] = get_random_bit_vector(address_commitment_nonce_length);
- new_coin_serial_number_nonces[i] = get_random_bit_vector(serial_number_nonce_length);
- }
-
- merkle_tree<sha256_two_to_one_hash_gadget<FieldT> > tree(tree_depth, coin_commitment_length);
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- /* calculate old coin and place it in the Merkle tree */
-
- /* old_address_public_key = H(old_address_secret_key || 00...) */
- bit_vector old_address_public_key_hash_input = old_address_secret_keys[i];
- old_address_public_key_hash_input.resize(sha256_block_len);
- const bit_vector old_address_public_key = sha256_two_to_one_hash_gadget<FieldT>::get_hash(old_address_public_key_hash_input);
-
- const bit_vector old_coin = compute_coin_commitment<FieldT>(old_address_public_key,
- old_coin_values[i],
- old_coin_serial_number_nonces[i],
- old_address_commitment_nonces[i]);
- tree.set_value(old_coin_merkle_tree_positions[i], old_coin);
- }
-
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- /* get the corresponding authentication paths */
- old_coin_authentication_paths[i] = tree.get_path(old_coin_merkle_tree_positions[i]);
- }
-
- merkle_tree_root = tree.get_root();
- signature_public_key_hash = get_random_bit_vector(sha256_digest_len);
-
- /* calculate the values used by the verifier */
- std::vector<bit_vector> old_coin_serial_numbers(num_old_coins); //
- std::vector<bit_vector> new_coin_commitments(num_new_coins); //
- std::vector<bit_vector> signature_public_key_hash_macs(num_old_coins); //
-
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- /* serial_number = H(address_secret_key || 01 || serial_number_nonce[0..254]) */
- bit_vector old_coin_serial_number_hash_input;
- old_coin_serial_number_hash_input.insert(old_coin_serial_number_hash_input.end(),
- old_address_secret_keys[i].begin(),
- old_address_secret_keys[i].end());
- old_coin_serial_number_hash_input.push_back(false);
- old_coin_serial_number_hash_input.push_back(true);
- old_coin_serial_number_hash_input.insert(old_coin_serial_number_hash_input.end(),
- old_coin_serial_number_nonces[i].begin(),
- old_coin_serial_number_nonces[i].begin() + truncated_serial_number_length);
-
- old_coin_serial_numbers[i] = sha256_two_to_one_hash_gadget<FieldT>::get_hash(old_coin_serial_number_hash_input);
-
- /* signature_public_key_hash_macs[i] = H(old_address_secret_keys[i] || 10 || i || signature_public_key_hash) */
- const size_t truncated_signature_public_key_hash_length = indexed_signature_public_key_hash_length - log2(num_old_coins);
-
- bit_vector signature_public_key_hash_macs_hash_input;
- signature_public_key_hash_macs_hash_input.insert(signature_public_key_hash_macs_hash_input.end(),
- old_address_secret_keys[i].begin(),
- old_address_secret_keys[i].end());
- signature_public_key_hash_macs_hash_input.push_back(true);
- signature_public_key_hash_macs_hash_input.push_back(false);
- const bit_vector i_as_bits = int_to_bit_vector(i, log2(num_old_coins));
- signature_public_key_hash_macs_hash_input.insert(signature_public_key_hash_macs_hash_input.end(),
- i_as_bits.begin(),
- i_as_bits.end());
- signature_public_key_hash_macs_hash_input.insert(signature_public_key_hash_macs_hash_input.end(),
- signature_public_key_hash.begin(),
- signature_public_key_hash.begin() + truncated_signature_public_key_hash_length);
- signature_public_key_hash_macs[i] = sha256_two_to_one_hash_gadget<FieldT>::get_hash(signature_public_key_hash_macs_hash_input);
- }
-
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- new_coin_commitments[i] = compute_coin_commitment<FieldT>(new_address_public_keys[i],
- new_coin_values[i],
- new_coin_serial_number_nonces[i],
- new_address_commitment_nonces[i]);
- }
-
- /* perform basic sanity checks */
- {
- protoboard<FieldT> pb;
- zerocash_pour_gadget<FieldT> pour(pb, num_old_coins, num_new_coins, tree_depth, "pour");
- pour.generate_r1cs_constraints();
- pour.generate_r1cs_witness(old_coin_authentication_paths,
- old_coin_merkle_tree_positions,
- merkle_tree_root,
- new_address_public_keys,
- old_address_secret_keys,
- new_address_commitment_nonces,
- old_address_commitment_nonces,
- new_coin_serial_number_nonces,
- old_coin_serial_number_nonces,
- new_coin_values,
- public_in_value,
- public_out_value,
- old_coin_values,
- signature_public_key_hash);
- assert(pb.is_satisfied());
- printf("gadget test OK for num_old_coins = %zu, num_new_coins = %zu, tree_depth = %zu\n",
- num_old_coins, num_new_coins, tree_depth);
- }
-
- /* do the end-to-end test */
- zerocash_pour_keypair<ppT> keypair = zerocash_pour_ppzksnark_generator<ppT>(num_old_coins, num_new_coins, tree_depth);
- keypair = reserialize<zerocash_pour_keypair<ppT> >(keypair);
-
- zerocash_pour_proof<ppT> proof = zerocash_pour_ppzksnark_prover<ppT>(keypair.pk,
- old_coin_authentication_paths,
- old_coin_merkle_tree_positions,
- merkle_tree_root,
- new_address_public_keys,
- old_address_secret_keys,
- new_address_commitment_nonces,
- old_address_commitment_nonces,
- new_coin_serial_number_nonces,
- old_coin_serial_number_nonces,
- new_coin_values,
- public_in_value,
- public_out_value,
- old_coin_values,
- signature_public_key_hash);
- proof = reserialize<zerocash_pour_proof<ppT> >(proof);
-
- const bool verification_result = zerocash_pour_ppzksnark_verifier<ppT>(keypair.vk,
- merkle_tree_root,
- old_coin_serial_numbers,
- new_coin_commitments,
- public_in_value,
- public_out_value,
- signature_public_key_hash,
- signature_public_key_hash_macs,
- proof);
- printf("Verification result: %s\n", verification_result ? "pass" : "FAIL");
- assert(verification_result);
-}
-
-int main(int argc, const char * argv[])
-{
- start_profiling();
- default_r1cs_ppzksnark_pp::init_public_params();
- test_zerocash_pour_ppzksnark<default_r1cs_ppzksnark_pp>(2, 2, 4);
- test_zerocash_pour_ppzksnark<default_r1cs_ppzksnark_pp>(2, 3, 4);
- test_zerocash_pour_ppzksnark<default_r1cs_ppzksnark_pp>(3, 2, 4);
- test_zerocash_pour_ppzksnark<default_r1cs_ppzksnark_pp>(3, 3, 4);
- test_zerocash_pour_ppzksnark<default_r1cs_ppzksnark_pp>(2, 2, 32);
-}
+++ /dev/null
-/** @file
- *****************************************************************************
-
- A test for Zerocash.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include <stdlib.h>
-#include <iostream>
-
-#define BOOST_TEST_MODULE zerocashTest
-#include <boost/test/included/unit_test.hpp>
-
-#include "timer.h"
-
-#include "zerocash/Zerocash.h"
-#include "zerocash/ZerocashParams.h"
-#include "zerocash/Address.h"
-#include "zerocash/CoinCommitment.h"
-#include "zerocash/Coin.h"
-#include "zerocash/IncrementalMerkleTree.h"
-#include "zerocash/MintTransaction.h"
-#include "zerocash/PourTransaction.h"
-#include "zerocash/PourInput.h"
-#include "zerocash/PourOutput.h"
-#include "zerocash/utils/util.h"
-
-#include "uint256.h"
-
-using namespace std;
-using namespace libsnark;
-
-BOOST_AUTO_TEST_CASE( SaveAndLoadKeysFromFiles ) {
- cout << "\nSaveAndLoadKeysFromFiles TEST\n" << endl;
-
- cout << "Creating Params...\n" << endl;
-
- libzerocash::timer_start("Param Generation");
- auto keypair = libzerocash::ZerocashParams::GenerateNewKeyPair(INCREMENTAL_MERKLE_TREE_DEPTH);
- libzerocash::ZerocashParams p(
- INCREMENTAL_MERKLE_TREE_DEPTH,
- &keypair
- );
- libzerocash::timer_stop("Param Generation");
- print_mem("after param generation");
-
- cout << "Successfully created Params.\n" << endl;
-
- std::string vk_path = "./zerocashTest-verification-key";
- std::string pk_path = "./zerocashTest-proving-key";
-
- libzerocash::timer_start("Saving Proving Key");
-
- libzerocash::ZerocashParams::SaveProvingKeyToFile(
- &p.getProvingKey(),
- pk_path
- );
-
- libzerocash::timer_stop("Saving Proving Key");
-
- libzerocash::timer_start("Saving Verification Key");
-
- libzerocash::ZerocashParams::SaveVerificationKeyToFile(
- &p.getVerificationKey(),
- vk_path
- );
-
- libzerocash::timer_stop("Saving Verification Key");
-
- libzerocash::timer_start("Loading Proving Key");
- auto pk_loaded = libzerocash::ZerocashParams::LoadProvingKeyFromFile(pk_path, INCREMENTAL_MERKLE_TREE_DEPTH);
- libzerocash::timer_stop("Loading Proving Key");
-
- libzerocash::timer_start("Loading Verification Key");
- auto vk_loaded = libzerocash::ZerocashParams::LoadVerificationKeyFromFile(vk_path, INCREMENTAL_MERKLE_TREE_DEPTH);
- libzerocash::timer_stop("Loading Verification Key");
-
- cout << "Comparing Proving and Verification key.\n" << endl;
-
- if ( !( p.getProvingKey() == pk_loaded && p.getVerificationKey() == vk_loaded) ) {
- BOOST_ERROR("Proving and verification key are not equal.");
- }
-
- vector<libzerocash::Coin> coins;
- vector<libzerocash::Address> addrs;
-
- cout << "Creating Addresses and Coins...\n" << endl;
- for(size_t i = 0; i < 5; i++) {
- addrs.push_back(libzerocash::Address::CreateNewRandomAddress());
- coins.push_back(libzerocash::Coin(addrs.at(i).getPublicAddress(), i));
- }
- cout << "Successfully created address and coins.\n" << endl;
-
- cout << "Creating a Mint Transaction...\n" << endl;
- libzerocash::MintTransaction minttx(coins.at(0));
- cout << "Successfully created a Mint Transaction.\n" << endl;
-
- vector<std::vector<bool>> coinValues(5);
- vector<bool> temp_comVal(ZC_CM_SIZE * 8);
- for(size_t i = 0; i < coinValues.size(); i++) {
- libzerocash::convertBytesVectorToVector(coins.at(i).getCoinCommitment().getCommitmentValue(), temp_comVal);
- coinValues.at(i) = temp_comVal;
- }
-
- cout << "Creating Merkle Tree...\n" << endl;
- libzerocash::IncrementalMerkleTree merkleTree(coinValues, INCREMENTAL_MERKLE_TREE_DEPTH);
- cout << "Successfully created Merkle Tree.\n" << endl;
-
- std::vector<bool> index;
-
- cout << "Creating Witness 1...\n" << endl;
- merkle_authentication_path witness_1(INCREMENTAL_MERKLE_TREE_DEPTH);
- libzerocash::convertIntToVector(1, index);
- merkleTree.getWitness(index, witness_1);
- cout << "Successfully created Witness 1.\n" << endl;
-
- cout << "Creating Witness 2...\n" << endl;
- merkle_authentication_path witness_2(INCREMENTAL_MERKLE_TREE_DEPTH);
- libzerocash::convertIntToVector(3, index);
- merkleTree.getWitness(index, witness_2);
- cout << "Successfully created Witness 2.\n" << endl;
-
- cout << "Creating coins to spend...\n" << endl;
- libzerocash::Address newAddress3 = libzerocash::Address::CreateNewRandomAddress();
- libzerocash::PublicAddress pubAddress3 = newAddress3.getPublicAddress();
-
- libzerocash::Address newAddress4 = libzerocash::Address::CreateNewRandomAddress();
- libzerocash::PublicAddress pubAddress4 = newAddress4.getPublicAddress();
-
- libzerocash::Coin c_1_new(pubAddress3, 2);
- libzerocash::Coin c_2_new(pubAddress4, 2);
- cout << "Successfully created coins to spend.\n" << endl;
-
- vector<unsigned char> rt(ZC_ROOT_SIZE);
- merkleTree.getRootValue(rt);
-
- // XXX: debugging
- std::cout << "Root: " << rt.size() << endl;
- std::cout << "wit1: " << witness_1.size() << endl;
- std::cout << "wit2: " << witness_1.size() << endl;
-
- vector<unsigned char> as(ZC_SIG_PK_SIZE, 'a');
-
- cout << "Creating a pour transaction...\n" << endl;
- libzerocash::PourTransaction pourtx(1, p,
- rt,
- coins.at(1), coins.at(3),
- addrs.at(1), addrs.at(3),
- 1, 3,
- witness_1, witness_2,
- pubAddress3, pubAddress4,
- 0,
- 0,
- as,
- c_1_new, c_2_new);
- cout << "Successfully created a pour transaction.\n" << endl;
-
- std::vector<unsigned char> pubkeyHash(ZC_SIG_PK_SIZE, 'a');
-
- cout << "Verifying a pour transaction...\n" << endl;
- bool pourtx_res = pourtx.verify(p, pubkeyHash, rt);
-
- BOOST_CHECK(pourtx_res);
-}
-
-BOOST_AUTO_TEST_CASE( PourInputOutputTest ) {
- // dummy input
- {
- libzerocash::PourInput input(INCREMENTAL_MERKLE_TREE_DEPTH);
-
- BOOST_CHECK(input.old_coin.getValue() == 0);
- BOOST_CHECK(input.old_address.getPublicAddress() == input.old_coin.getPublicAddress());
- }
-
- // dummy output
- {
- libzerocash::PourOutput output(0);
-
- BOOST_CHECK(output.new_coin.getValue() == 0);
- BOOST_CHECK(output.to_address == output.new_coin.getPublicAddress());
- }
-}
-
-// testing with general situational setup
-void test_pour(libzerocash::ZerocashParams& p,
- uint64_t vpub_in,
- uint64_t vpub_out,
- std::vector<uint64_t> inputs, // values of the inputs (max 2)
- std::vector<uint64_t> outputs) // values of the outputs (max 2)
-{
- using pour_input_state = std::tuple<libzerocash::Address, libzerocash::Coin, ZCIncrementalWitness>;
-
- // Construct incremental merkle tree
- ZCIncrementalMerkleTree merkleTree;
-
- // Dummy sig_pk
- vector<unsigned char> as(ZC_SIG_PK_SIZE, 'a');
-
- vector<libzerocash::PourInput> pour_inputs;
- vector<libzerocash::PourOutput> pour_outputs;
-
- vector<pour_input_state> input_state;
-
- for(std::vector<uint64_t>::iterator it = inputs.begin(); it != inputs.end(); ++it) {
- libzerocash::Address addr = libzerocash::Address::CreateNewRandomAddress();
- libzerocash::Coin coin(addr.getPublicAddress(), *it);
-
- // commitment from coin
- uint256 commitment(coin.getCoinCommitment().getCommitmentValue());
-
- // insert commitment into the merkle tree
- merkleTree.append(commitment);
-
- // and append to any witnesses
- for(vector<pour_input_state>::iterator wit = input_state.begin(); wit != input_state.end(); ++wit) {
- std::get<2>(*wit).append(commitment);
- }
-
- // store the state temporarily
- input_state.push_back(std::make_tuple(addr, coin, merkleTree.witness()));
- }
-
- // compute the merkle root we will be working with
- auto rt_u = merkleTree.root();
- std::vector<unsigned char> rt(rt_u.begin(), rt_u.end());
-
- // get witnesses for all the input coins and construct the pours
- for(vector<pour_input_state>::iterator it = input_state.begin(); it != input_state.end(); ++it) {
- auto witness = std::get<2>(*it);
- auto path = witness.path();
-
- pour_inputs.push_back(libzerocash::PourInput(std::get<1>(*it), std::get<0>(*it), path));
- }
-
- // construct dummy outputs with the given values
- for(vector<uint64_t>::iterator it = outputs.begin(); it != outputs.end(); ++it) {
- pour_outputs.push_back(libzerocash::PourOutput(*it));
- }
-
- libzerocash::PourTransaction pourtx(p, as, rt, pour_inputs, pour_outputs, vpub_in, vpub_out);
-
- BOOST_CHECK(pourtx.verify(p, as, rt));
-}
-
-BOOST_AUTO_TEST_CASE( PourVpubInTest ) {
- auto keypair = libzerocash::ZerocashParams::GenerateNewKeyPair(INCREMENTAL_MERKLE_TREE_DEPTH);
- libzerocash::ZerocashParams p(
- INCREMENTAL_MERKLE_TREE_DEPTH,
- &keypair
- );
-
- // Things that should work..
- test_pour(p, 0, 0, {1}, {1});
- test_pour(p, 0, 0, {2}, {1, 1});
- test_pour(p, 0, 0, {2, 2}, {3, 1});
- test_pour(p, 0, 1, {1}, {});
- test_pour(p, 0, 1, {2}, {1});
- test_pour(p, 0, 1, {2, 2}, {2, 1});
- test_pour(p, 1, 0, {}, {1});
- test_pour(p, 1, 0, {1}, {1, 1});
- test_pour(p, 1, 0, {2, 2}, {2, 3});
-
- // Things that should not work...
- BOOST_CHECK_THROW(test_pour(p, 0, 1, {1}, {1}), std::invalid_argument);
- BOOST_CHECK_THROW(test_pour(p, 0, 1, {2}, {1, 1}), std::invalid_argument);
- BOOST_CHECK_THROW(test_pour(p, 0, 1, {2, 2}, {3, 1}), std::invalid_argument);
- BOOST_CHECK_THROW(test_pour(p, 0, 2, {1}, {}), std::invalid_argument);
- BOOST_CHECK_THROW(test_pour(p, 0, 2, {2}, {1}), std::invalid_argument);
- BOOST_CHECK_THROW(test_pour(p, 0, 2, {2, 2}, {2, 1}), std::invalid_argument);
- BOOST_CHECK_THROW(test_pour(p, 1, 1, {}, {1}), std::invalid_argument);
- BOOST_CHECK_THROW(test_pour(p, 1, 1, {1}, {1, 1}), std::invalid_argument);
- BOOST_CHECK_THROW(test_pour(p, 1, 1, {2, 2}, {2, 3}), std::invalid_argument);
-
- BOOST_CHECK_THROW(test_pour(p, 0, 0, {2, 2}, {2, 3}), std::invalid_argument);
-}
-
-BOOST_AUTO_TEST_CASE( CoinTest ) {
- cout << "\nCOIN TEST\n" << endl;
-
- libzerocash::Address newAddress = libzerocash::Address::CreateNewRandomAddress();
- libzerocash::PublicAddress pubAddress = newAddress.getPublicAddress();
-
- libzerocash::Coin coin(pubAddress, 0);
-
- cout << "Successfully created a coin.\n" << endl;
-
- ///////////////////////////////////////////////////////////////////////////
-
- libzerocash::timer_start("Coin");
- libzerocash::Coin coin2(pubAddress, 0);
- libzerocash::timer_stop("Coin");
-
- cout << "Successfully created a coin.\n" << endl;
-}
-
-BOOST_AUTO_TEST_CASE( MintTxTest ) {
- cout << "\nMINT TRANSACTION TEST\n" << endl;
-
- libzerocash::Address newAddress = libzerocash::Address::CreateNewRandomAddress();
- libzerocash::PublicAddress pubAddress = newAddress.getPublicAddress();
-
- vector<unsigned char> value(ZC_V_SIZE, 0);
-
- libzerocash::timer_start("Coin");
- const libzerocash::Coin coin(pubAddress, 0);
- libzerocash::timer_stop("Coin");
-
- libzerocash::timer_start("Mint Transaction");
- libzerocash::MintTransaction minttx(coin);
- libzerocash::timer_stop("Mint Transaction");
-
- cout << "Successfully created a mint transaction.\n" << endl;
-
- libzerocash::timer_start("Mint Transaction Verify");
- bool minttx_res = minttx.verify();
- libzerocash::timer_stop("Mint Transaction Verify");
-
- BOOST_CHECK(minttx_res);
-}
-
-BOOST_AUTO_TEST_CASE( PourTxTest ) {
- cout << "\nPOUR TRANSACTION TEST\n" << endl;
-
- cout << "Creating Params...\n" << endl;
-
- libzerocash::timer_start("Param Generation");
- auto keypair = libzerocash::ZerocashParams::GenerateNewKeyPair(INCREMENTAL_MERKLE_TREE_DEPTH);
- libzerocash::ZerocashParams p(
- INCREMENTAL_MERKLE_TREE_DEPTH,
- &keypair
- );
- libzerocash::timer_stop("Param Generation");
- print_mem("after param generation");
-
- cout << "Successfully created Params.\n" << endl;
-
- vector<libzerocash::Coin> coins;
- vector<libzerocash::Address> addrs;
-
- for(size_t i = 0; i < 5; i++) {
- addrs.push_back(libzerocash::Address::CreateNewRandomAddress());
- coins.push_back(libzerocash::Coin(addrs.at(i).getPublicAddress(), i));
- }
-
- cout << "Successfully created coins.\n" << endl;
-
- vector<std::vector<bool>> coinValues(5);
-
- vector<bool> temp_comVal(ZC_CM_SIZE * 8);
- for(size_t i = 0; i < coinValues.size(); i++) {
- libzerocash::convertBytesVectorToVector(coins.at(i).getCoinCommitment().getCommitmentValue(), temp_comVal);
- coinValues.at(i) = temp_comVal;
- libzerocash::printVectorAsHex("Coin => ", coinValues.at(i));
- }
-
- cout << "Creating Merkle Tree...\n" << endl;
-
- libzerocash::timer_start("Merkle Tree");
- libzerocash::IncrementalMerkleTree merkleTree(coinValues, INCREMENTAL_MERKLE_TREE_DEPTH);
- libzerocash::timer_stop("Merkle Tree");
-
- cout << "Successfully created Merkle Tree.\n" << endl;
-
- merkle_authentication_path witness_1(INCREMENTAL_MERKLE_TREE_DEPTH);
-
- libzerocash::timer_start("Witness");
- std::vector<bool> index;
- libzerocash::convertIntToVector(1, index);
- if (merkleTree.getWitness(index, witness_1) == false) {
- BOOST_ERROR("Could not get witness");
- }
- libzerocash::timer_stop("Witness");
-
- cout << "Witness 1: " << endl;
- for(size_t i = 0; i < witness_1.size(); i++) {
- libzerocash::printVectorAsHex(witness_1.at(i));
- }
- cout << "\n" << endl;
-
- merkle_authentication_path witness_2(INCREMENTAL_MERKLE_TREE_DEPTH);
- libzerocash::convertIntToVector(3, index);
- if (merkleTree.getWitness(index, witness_2) == false) {
- cout << "Could not get witness" << endl;
- }
-
- cout << "Witness 2: " << endl;
- for(size_t i = 0; i < witness_2.size(); i++) {
- libzerocash::printVectorAsHex(witness_2.at(i));
- }
- cout << "\n" << endl;
-
- libzerocash::Address newAddress3 = libzerocash::Address::CreateNewRandomAddress();
- libzerocash::PublicAddress pubAddress3 = newAddress3.getPublicAddress();
-
- libzerocash::Address newAddress4 = libzerocash::Address::CreateNewRandomAddress();
- libzerocash::PublicAddress pubAddress4 = newAddress4.getPublicAddress();
-
- libzerocash::Coin c_1_new(pubAddress3, 2);
- libzerocash::Coin c_2_new(pubAddress4, 2);
-
- vector<bool> root_bv(ZC_ROOT_SIZE * 8);
- merkleTree.getRootValue(root_bv);
- vector<unsigned char> rt(ZC_ROOT_SIZE);
- libzerocash::convertVectorToBytesVector(root_bv, rt);
-
- vector<unsigned char> ones(ZC_V_SIZE, 1);
- vector<unsigned char> twos(ZC_V_SIZE, 2);
- vector<unsigned char> as(ZC_SIG_PK_SIZE, 'a');
-
- cout << "Creating a pour transaction...\n" << endl;
-
- libzerocash::timer_start("Pour Transaction");
- libzerocash::PourTransaction pourtx(1, p, rt, coins.at(1), coins.at(3), addrs.at(1), addrs.at(3), 1, 3, witness_1, witness_2, pubAddress3, pubAddress4, 0, 0, as, c_1_new, c_2_new);
- libzerocash::timer_stop("Pour Transaction");
- print_mem("after pour transaction");
-
- cout << "Successfully created a pour transaction.\n" << endl;
-
- std::vector<unsigned char> pubkeyHash(ZC_SIG_PK_SIZE, 'a');
-
- libzerocash::timer_start("Pour Transaction Verify");
- bool pourtx_res = pourtx.verify(p, pubkeyHash, rt);
- libzerocash::timer_stop("Pour Transaction Verify");
-
- BOOST_CHECK(pourtx_res);
-}
-
-BOOST_AUTO_TEST_CASE( MerkleTreeSimpleTest ) {
- cout << "\nMERKLE TREE SIMPLE TEST\n" << endl;
-
- vector<libzerocash::Coin> coins;
- vector<libzerocash::Address> addrs;
-
- cout << "Creating coins...\n" << endl;
-
- for(size_t i = 0; i < 5; i++) {
- addrs.push_back(libzerocash::Address::CreateNewRandomAddress());
- coins.push_back(libzerocash::Coin(addrs.at(i).getPublicAddress(), i));
- }
-
- cout << "Successfully created coins.\n" << endl;
-
- vector<std::vector<bool>> coinValues(coins.size());
-
- vector<bool> temp_comVal(ZC_CM_SIZE * 8);
- for(size_t i = 0; i < coinValues.size(); i++) {
- libzerocash::convertBytesVectorToVector(coins.at(i).getCoinCommitment().getCommitmentValue(), temp_comVal);
- coinValues.at(i) = temp_comVal;
- libzerocash::printVectorAsHex(coinValues.at(i));
- }
-
- cout << "Creating Merkle Tree...\n" << endl;
-
- libzerocash::IncrementalMerkleTree merkleTree(64);
- vector<bool> root;
- merkleTree.getRootValue(root);
- cout << "Root: ";
- libzerocash::printVectorAsHex(root);
- cout << endl;
-
- cout << "Successfully created Merkle Tree.\n" << endl;
-
- cout << "Copying and pruning Merkle Tree...\n" << endl;
- libzerocash::IncrementalMerkleTree copyTree = merkleTree;
- copyTree.prune();
-
- cout << "Obtaining compact representation and reconstituting tree...\n" << endl;
- libzerocash::IncrementalMerkleTreeCompact compactTree = merkleTree.getCompactRepresentation();
-
- cout << "Compact representation vector: ";
- libzerocash::printVector(compactTree.getHashList());
-
- libzerocash::IncrementalMerkleTree reconstitutedTree(compactTree);
- reconstitutedTree.getRootValue(root);
- cout << "New root: ";
- libzerocash::printVectorAsHex(root);
- cout << endl;
-
- reconstitutedTree.insertVector(coinValues);
- merkleTree.insertVector(coinValues);
-
- reconstitutedTree.getRootValue(root);
- cout << "New root (added a bunch more): ";
- libzerocash::printVectorAsHex(root);
- cout << endl;
-
- merkleTree.getRootValue(root);
- cout << "Old root (added a bunch more): ";
- libzerocash::printVectorAsHex(root);
- cout << endl;
-
- merkle_authentication_path witness(16);
- std::vector<bool> index;
- libzerocash::convertIntToVector(3, index);
- if (merkleTree.getWitness(index, witness) == false) {
- BOOST_ERROR("Witness generation failed.");
- }
-
- cout << "Successfully created witness.\n" << endl;
-
- cout << "Witness: " << endl;
- for(size_t i = 0; i < witness.size(); i++) {
- libzerocash::printVectorAsHex(witness.at(i));
- }
- cout << "\n" << endl;
-
- vector<bool> wit1(CSHA256::OUTPUT_SIZE * 8);
- vector<bool> wit2(CSHA256::OUTPUT_SIZE * 8);
- vector<bool> wit3(CSHA256::OUTPUT_SIZE * 8);
- vector<bool> inter_1(CSHA256::OUTPUT_SIZE * 8);
- vector<bool> inter_2(CSHA256::OUTPUT_SIZE * 8);
- std::vector<bool> zeros(CSHA256::OUTPUT_SIZE * 8, 0);
-
- wit1 = coinValues.at(2);
- libzerocash::hashVectors(coinValues.at(0), coinValues.at(1), wit2);
- libzerocash::hashVectors(coinValues.at(4), zeros, inter_1);
- inter_2 = zeros;
- libzerocash::hashVectors(inter_1, inter_2, wit3);
-
- BOOST_CHECK(witness.size() == 64);
- for (size_t i = 0; i < 61; i++) {
- BOOST_CHECK(witness.at(i) == zeros);
- }
- BOOST_CHECK(
- (witness.at(61) == wit3) &&
- (witness.at(62) == wit2) &&
- (witness.at(63) == wit1)
- );
-}
-
-BOOST_AUTO_TEST_CASE( SimpleTxTest ) {
- cout << "\nSIMPLE TRANSACTION TEST\n" << endl;
-
- libzerocash::timer_start("Param Generation");
- auto keypair = libzerocash::ZerocashParams::GenerateNewKeyPair(INCREMENTAL_MERKLE_TREE_DEPTH);
- libzerocash::ZerocashParams p(
- INCREMENTAL_MERKLE_TREE_DEPTH,
- &keypair
- );
- libzerocash::timer_stop("Param Generation");
-
- vector<libzerocash::Coin> coins;
- vector<libzerocash::Address> addrs;
-
- cout << "Creating Addresses and Coins...\n" << endl;
- for(size_t i = 0; i < 5; i++) {
- addrs.push_back(libzerocash::Address::CreateNewRandomAddress());
- coins.push_back(libzerocash::Coin(addrs.at(i).getPublicAddress(), i));
- }
- cout << "Successfully created address and coins.\n" << endl;
-
- cout << "Creating a Mint Transaction...\n" << endl;
- libzerocash::MintTransaction minttx(coins.at(0));
- cout << "Successfully created a Mint Transaction.\n" << endl;
-
- cout << "Verifying a Mint Transaction...\n" << endl;
- bool minttx_res = minttx.verify();
-
- vector<std::vector<bool>> coinValues(5);
- vector<bool> temp_comVal(ZC_CM_SIZE * 8);
- for(size_t i = 0; i < coinValues.size(); i++) {
- libzerocash::convertBytesVectorToVector(coins.at(i).getCoinCommitment().getCommitmentValue(), temp_comVal);
- coinValues.at(i) = temp_comVal;
- }
-
- cout << "Creating Merkle Tree...\n" << endl;
- libzerocash::IncrementalMerkleTree merkleTree(coinValues, INCREMENTAL_MERKLE_TREE_DEPTH);
- cout << "Successfully created Merkle Tree.\n" << endl;
-
- std::vector<bool> index;
-
- cout << "Creating Witness 1...\n" << endl;
- merkle_authentication_path witness_1(INCREMENTAL_MERKLE_TREE_DEPTH);
- libzerocash::convertIntToVector(1, index);
- if (merkleTree.getWitness(index, witness_1) == false) {
- BOOST_ERROR("Could not get witness");
- }
- cout << "Successfully created Witness 1.\n" << endl;
-
- cout << "Creating Witness 2...\n" << endl;
- merkle_authentication_path witness_2(INCREMENTAL_MERKLE_TREE_DEPTH);
- libzerocash::convertIntToVector(3, index);
- if (merkleTree.getWitness(index, witness_2) == false) {
- cout << "Could not get witness" << endl;
- }
- cout << "Successfully created Witness 2.\n" << endl;
-
- cout << "Creating coins to spend...\n" << endl;
- libzerocash::Address newAddress3 = libzerocash::Address::CreateNewRandomAddress();
- libzerocash::PublicAddress pubAddress3 = newAddress3.getPublicAddress();
-
- libzerocash::Address newAddress4 = libzerocash::Address::CreateNewRandomAddress();
- libzerocash::PublicAddress pubAddress4 = newAddress4.getPublicAddress();
-
- libzerocash::Coin c_1_new(pubAddress3, 2);
- libzerocash::Coin c_2_new(pubAddress4, 2);
- cout << "Successfully created coins to spend.\n" << endl;
-
- vector<bool> root_bv(ZC_ROOT_SIZE * 8);
- merkleTree.getRootValue(root_bv);
- vector<unsigned char> rt(ZC_ROOT_SIZE);
- libzerocash::convertVectorToBytesVector(root_bv, rt);
-
-
- vector<unsigned char> as(ZC_SIG_PK_SIZE, 'a');
-
- cout << "Creating a pour transaction...\n" << endl;
- libzerocash::PourTransaction pourtx(1, p,
- rt,
- coins.at(1), coins.at(3),
- addrs.at(1), addrs.at(3),
- 1, 3,
- witness_1, witness_2,
- pubAddress3, pubAddress4,
- 0,
- 0,
- as,
- c_1_new, c_2_new);
- cout << "Successfully created a pour transaction.\n" << endl;
-
- std::vector<unsigned char> pubkeyHash(ZC_SIG_PK_SIZE, 'a');
-
- cout << "Verifying a pour transaction...\n" << endl;
- bool pourtx_res = pourtx.verify(p, pubkeyHash, rt);
-
- BOOST_CHECK(minttx_res && pourtx_res);
-}
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of interfaces for the Zerocash Pour gadget.
-
- The Pour gadget implements the NP statement "Zerocash Pour" described in \[BCGGMTV14].
-
-
- References:
-
- \[BCGGMTV14]:
- "Zerocash: Decentralized Anonymous Payments from Bitcoin",
- Eli Ben-Sasson, Alessandro Chiesa, Christina Garman, Matthew Green, Ian Miers, Eran Tromer, Madars Virza,
- S&P 2014,
- <https://eprint.iacr.org/2014/349>
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef ZEROCASH_POUR_GADGET_HPP_
-#define ZEROCASH_POUR_GADGET_HPP_
-
-#include "zerocash_pour_params.hpp"
-#include "libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp"
-#include "libsnark/gadgetlib1/gadgets/merkle_tree/merkle_tree_check_read_gadget.hpp"
-
-namespace libzerocash {
-
-using namespace libsnark;
-
-/**
- * Gadget for the NP statement Zerocash Pour.
- *
- * More precisely, this gadgets checks the following NP statement.
- * (See Section 4.2 and Section 5.1 of the Zerocash paper for more details.)
- *
- * (A) old_coin_commitment_variables[i] appears on path old_coin_authentication_paths[i] to merkle_tree_root_variable
- *
- * (B) old_address_public_keys[i]
- * = PRF_{old_address_secret_key_variables[i]}^{addr}(z)
- * = H(old_address_secret_key_variables[i] || 00 || z)
- * where z = 0...0
- *
- * (C) old_coin_serial_number_variables[i]
- * = PRF_{old_address_secret_key_variables[i]}^{sn}(old_coin_serial_number_nonce_variables[0..254])
- * = H(old_address_secret_key_variables[i] || 01 || old_coin_serial_number_nonce_variables[0..254])
- *
- * Properties (D0) and (D1) jointly ensure that
- *
- * old_coin_value_commitment_nonces[i]
- * = COMM_{old_address_commitment_nonce_variables[i]}(old_address_public_key_variables[i] || old_coin_serial_number_nonce_variables[i])
- *
- * as follows:
- *
- * (D0) commitments_to_old_address_public_keys[i]
- * = H(old_address_public_key_variables[i] || old_coin_serial_number_nonce_variables[i])
- *
- * (D1) old_coin_value_commitment_nonces[i]
- * = H(old_address_commitment_nonce_variables[i] || commitments_to_old_address_public_keys[i] [0..128])
- *
- * Given this, (D2) computes old_coin_commitments:
- *
- * (D2) old_coin_commitment_variables[i]
- * = COMM_s(old_coin_value_variables[i] || old_coin_value_commitment_nonces[i])
- * = H(old_coin_value_commitment_nonces[i] || 0^{192} || old_coin_value_variables[i])
- *
- * Here we ignore commitment randomness s, because
- * k = old_coin_value_commitment_nonces[i]
- * is an output of a statistically-hiding commitment scheme.
- *
- * While (D0) and (D1) check that old coin commitments are well formed,
- * (E0) and (E1) check the same properties for new coins.
- *
- * (F) mac_of_signature_public_key_hash_variables[i]
- * = PRF_{old_address_secret_key_variables[i]}^{pk}(i || signature_public_key_hash_variable)
- * = H(old_address_secret_key_variables[i] || 10 || i || signature_public_key_hash_variable)
- *
- * Here signature_public_key_hash is truncated so that the entire argument fits inside SHA256 block.
- * Furthermore, the representation of i is MSB to LSB and is exactly log2(num_old_coins) bits long.
- */
-template<typename FieldT>
-class zerocash_pour_gadget : public gadget<FieldT> {
-public:
- size_t tree_depth;
-
- pb_variable_array<FieldT> input_as_field_elements; /* R1CS input */
- pb_variable_array<FieldT> input_as_bits; /* unpacked R1CS input */
- std::shared_ptr<multipacking_gadget<FieldT> > unpack_inputs;
-
- /* individual components of the unpacked R1CS input */
- std::shared_ptr<digest_variable<FieldT> > merkle_tree_root_variable;
- std::vector<std::shared_ptr<digest_variable<FieldT> > > old_coin_serial_number_variables;
- pb_variable_array<FieldT> old_coin_enforce_commitment;
- std::vector<std::shared_ptr<digest_variable<FieldT> > > new_coin_commitment_variables;
- pb_variable_array<FieldT> public_old_value_variable;
- pb_variable_array<FieldT> public_new_value_variable;
- std::shared_ptr<digest_variable<FieldT> > signature_public_key_hash_variable;
- std::vector<std::shared_ptr<digest_variable<FieldT> > > mac_of_signature_public_key_hash_variables;
-
- /* TODO */
- pb_variable<FieldT> zero;
-
- std::vector<pb_variable_array<FieldT> > new_address_public_key_variables;
- std::vector<pb_variable_array<FieldT> > old_address_secret_key_variables;
- std::vector<pb_variable_array<FieldT> > new_address_commitment_nonce_variables;
- std::vector<pb_variable_array<FieldT> > old_address_commitment_nonce_variables;
- std::vector<pb_variable_array<FieldT> > new_coin_serial_number_nonce_variables;
- std::vector<pb_variable_array<FieldT> > old_coin_serial_number_nonce_variables;
- std::vector<pb_variable_array<FieldT> > new_coin_value_variables;
- std::vector<pb_variable_array<FieldT> > old_coin_value_variables;
-
- std::vector<std::shared_ptr<block_variable<FieldT> > > prf_for_old_coin_serial_number_input_variables;
- std::vector<std::shared_ptr<sha256_compression_function_gadget<FieldT> > > prfs_for_old_coin_serial_numbers; // (C)
-
- std::vector<std::shared_ptr<digest_variable<FieldT> > > old_address_public_key_variables;
- std::vector<std::shared_ptr<block_variable<FieldT> > > prf_for_old_address_public_key_input_variables;
- std::vector<std::shared_ptr<sha256_compression_function_gadget<FieldT> > > prfs_for_old_address_public_keys; // (B)
-
- std::vector<std::shared_ptr<digest_variable<FieldT> > > commitments_to_old_address_public_keys;
- std::vector<std::shared_ptr<block_variable<FieldT> > > commit_to_old_address_public_key_input_variables;
- std::vector<std::shared_ptr<sha256_compression_function_gadget<FieldT> > > commit_to_old_address_public_keys; // (D0)
-
- std::vector<std::shared_ptr<digest_variable<FieldT> > > old_coin_value_commitment_nonces;
- std::vector<std::shared_ptr<block_variable<FieldT> > > commit_to_old_coin_value_commitment_nonce_input_variables;
- std::vector<std::shared_ptr<sha256_compression_function_gadget<FieldT> > > commit_to_old_coin_value_commitment_nonces; // (D1)
-
- std::vector<std::shared_ptr<digest_variable<FieldT> > > old_coin_commitment_variables;
- std::vector<std::shared_ptr<block_variable<FieldT> > > compute_old_coin_commitment_input_variables;
- std::vector<std::shared_ptr<sha256_compression_function_gadget<FieldT> > > compute_old_coin_commitments; // (D2)
-
- std::vector<std::shared_ptr<digest_variable<FieldT> > > commitments_to_new_address_public_keys;
- std::vector<std::shared_ptr<block_variable<FieldT> > > commit_to_new_address_public_key_input_variables;
- std::vector<std::shared_ptr<sha256_compression_function_gadget<FieldT> > > commit_to_new_address_public_keys; // (E0)
-
- std::vector<std::shared_ptr<digest_variable<FieldT> > > new_coin_value_commitment_nonces;
- std::vector<std::shared_ptr<block_variable<FieldT> > > commit_to_new_coin_value_commitment_nonce_input_variables;
- std::vector<std::shared_ptr<sha256_compression_function_gadget<FieldT> > > commit_to_new_coin_value_commitment_nonces; // (E1)
-
- std::vector<std::shared_ptr<block_variable<FieldT> > > compute_new_coin_commitment_input_variables;
- std::vector<std::shared_ptr<sha256_compression_function_gadget<FieldT> > > compute_new_coin_commitments; // (E2)
-
- std::vector<std::shared_ptr<block_variable<FieldT> > > prf_for_macs_of_signature_public_key_hash_input_variables;
- std::vector<std::shared_ptr<sha256_compression_function_gadget<FieldT> > > prfs_for_macs_of_signature_public_key_hash; // (F)
-
- std::vector<pb_variable_array<FieldT> > old_coin_merkle_tree_position_variables;
- std::vector<std::shared_ptr<merkle_authentication_path_variable<FieldT, sha256_two_to_one_hash_gadget<FieldT> > > > old_coin_authentication_path_variables;
- std::vector<std::shared_ptr<merkle_tree_check_read_gadget<FieldT, sha256_two_to_one_hash_gadget<FieldT> > > > old_coin_commitments_in_tree; // (A)
-
- size_t num_old_coins;
- size_t num_new_coins;
-
- zerocash_pour_gadget(protoboard<FieldT> &pb, const size_t num_old_coins, const size_t num_new_coins, const size_t tree_depth, const std::string &annotation_prefix);
- void generate_r1cs_constraints();
- void generate_r1cs_witness(const std::vector<merkle_authentication_path> &old_coin_authentication_paths,
- const std::vector<size_t> &old_coin_merkle_tree_positions,
- const bit_vector &merkle_tree_root,
- const std::vector<bit_vector> &new_address_public_keys,
- const std::vector<bit_vector> &old_address_secret_keys,
- const std::vector<bit_vector> &new_address_commitment_nonces,
- const std::vector<bit_vector> &old_address_commitment_nonces,
- const std::vector<bit_vector> &new_coin_serial_number_nonces,
- const std::vector<bit_vector> &old_coin_serial_number_nonces,
- const std::vector<bit_vector> &new_coin_values,
- const bit_vector &public_old_value,
- const bit_vector &public_new_value,
- const std::vector<bit_vector> &old_coin_values,
- const bit_vector &signature_public_key_hash);
-};
-
-template<typename FieldT>
-r1cs_primary_input<FieldT> zerocash_pour_input_map(const size_t num_old_coins,
- const size_t num_new_coins,
- const bit_vector &merkle_tree_root,
- const std::vector<bit_vector> &old_coin_serial_numbers,
- const std::vector<bit_vector> &new_coin_commitments,
- const bit_vector &public_old_value,
- const bit_vector &public_new_value,
- const bit_vector &signature_public_key_hash,
- const std::vector<bit_vector> &signature_public_key_hash_macs);
-
-} // libzerocash
-
-#include "zerocash_pour_gadget.tcc"
-
-#endif // ZEROCASH_POUR_GADGET_HPP_
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Implementation of interfaces for the Zerocash Pour gadget.
-
- See zerocash_pour_gadget.hpp .
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#include "algebra/fields/field_utils.hpp"
-
-namespace libzerocash {
-
-template<typename FieldT>
-zerocash_pour_gadget<FieldT>::zerocash_pour_gadget(protoboard<FieldT> &pb,
- const size_t num_old_coins,
- const size_t num_new_coins,
- const size_t tree_depth,
- const std::string &annotation_prefix) :
- gadget<FieldT>(pb, FMT(annotation_prefix, " zerocash_pour_gadget")),
- tree_depth(tree_depth),
- num_old_coins(num_old_coins),
- num_new_coins(num_new_coins)
-{
- /* allocate packed inputs */
- const size_t input_size_in_bits = sha256_digest_len + num_old_coins*sha256_digest_len + num_new_coins*sha256_digest_len + (coin_value_length * 2) + (num_old_coins + 1) * sha256_digest_len;
- const size_t input_size_in_field_elements = div_ceil(input_size_in_bits, FieldT::capacity());
- input_as_field_elements.allocate(pb, input_size_in_field_elements, FMT(annotation_prefix, " input_as_field_elements"));
- this->pb.set_input_sizes(input_size_in_field_elements);
-
- /* allocate inputs */
- merkle_tree_root_variable.reset(new digest_variable<FieldT>(pb, sha256_digest_len, FMT(annotation_prefix, " merkle_tree_root_variable")));
-
- old_coin_enforce_commitment.allocate(pb, num_old_coins, FMT(annotation_prefix, " old_coin_enforce_commitment"));
- old_coin_serial_number_variables.resize(num_old_coins);
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- old_coin_serial_number_variables[i].reset(new digest_variable<FieldT>(pb, sha256_digest_len, FMT(annotation_prefix, " old_coin_serial_number_variables_%zu", i)));
- }
-
- new_coin_commitment_variables.resize(num_new_coins);
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- new_coin_commitment_variables[i].reset(new digest_variable<FieldT>(pb, sha256_digest_len, FMT(annotation_prefix, " new_coin_commitment_variables_%zu", i)));
- }
-
- public_old_value_variable.allocate(pb, coin_value_length, FMT(annotation_prefix, " public_old_value_variable"));
- public_new_value_variable.allocate(pb, coin_value_length, FMT(annotation_prefix, " public_new_value_variable"));
- signature_public_key_hash_variable.reset(new digest_variable<FieldT>(pb, sha256_digest_len, FMT(annotation_prefix, " signature_public_key_hash")));
-
- mac_of_signature_public_key_hash_variables.resize(num_old_coins);
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- mac_of_signature_public_key_hash_variables[i].reset(new digest_variable<FieldT>(pb, sha256_digest_len, FMT(annotation_prefix, " mac_of_signature_public_key_hash_variables_%zu", i)));
- }
-
- /* do the multipacking */
- input_as_bits.insert(input_as_bits.end(), merkle_tree_root_variable->bits.begin(), merkle_tree_root_variable->bits.end());
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- input_as_bits.insert(input_as_bits.end(), old_coin_serial_number_variables[i]->bits.begin(), old_coin_serial_number_variables[i]->bits.end());
- }
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- input_as_bits.insert(input_as_bits.end(), new_coin_commitment_variables[i]->bits.begin(), new_coin_commitment_variables[i]->bits.end());
- }
- input_as_bits.insert(input_as_bits.end(), public_old_value_variable.begin(), public_old_value_variable.end());
- input_as_bits.insert(input_as_bits.end(), public_new_value_variable.begin(), public_new_value_variable.end());
- input_as_bits.insert(input_as_bits.end(), signature_public_key_hash_variable->bits.begin(), signature_public_key_hash_variable->bits.end());
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- input_as_bits.insert(input_as_bits.end(), mac_of_signature_public_key_hash_variables[i]->bits.begin(), mac_of_signature_public_key_hash_variables[i]->bits.end());
- }
- assert(input_as_bits.size() == input_size_in_bits);
- unpack_inputs.reset(new multipacking_gadget<FieldT>(this->pb, input_as_bits, input_as_field_elements, FieldT::capacity(), FMT(this->annotation_prefix, " unpack_inputs")));
-
- pb_linear_combination_array<FieldT> IV = SHA256_default_IV(pb);
- zero.allocate(this->pb, FMT(this->annotation_prefix, " zero")); /* TODO */
-
- /* allocate witness */
- new_address_public_key_variables.resize(num_new_coins);
- new_address_commitment_nonce_variables.resize(num_new_coins);
- new_coin_serial_number_nonce_variables.resize(num_new_coins);
- new_coin_value_variables.resize(num_new_coins);
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- new_address_public_key_variables[i].allocate(pb, address_public_key_length, FMT(annotation_prefix, " new_address_public_key_variables_%zu", i));
- new_address_commitment_nonce_variables[i].allocate(pb, address_commitment_nonce_length, FMT(annotation_prefix, " new_address_commitment_nonce_variables_%zu", i));
- new_coin_serial_number_nonce_variables[i].allocate(pb, serial_number_nonce_length, FMT(annotation_prefix, " new_coin_serial_number_nonce_variables_%zu", i));
- new_coin_value_variables[i].allocate(pb, coin_value_length, FMT(annotation_prefix, " new_coin_value_variables_%zu", i));
- }
-
- old_address_secret_key_variables.resize(num_old_coins);
- old_address_commitment_nonce_variables.resize(num_old_coins);
- old_coin_serial_number_nonce_variables.resize(num_old_coins);
- old_coin_value_variables.resize(num_old_coins);
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- old_address_secret_key_variables[i].allocate(pb, address_secret_key_length, FMT(annotation_prefix, " old_address_secret_key_variables_%zu", i));
- old_address_commitment_nonce_variables[i].allocate(pb, address_commitment_nonce_length, FMT(annotation_prefix, " old_address_commitment_nonce_variables_%zu", i));
- old_coin_serial_number_nonce_variables[i].allocate(pb, serial_number_nonce_length, FMT(annotation_prefix, " old_coin_serial_number_nonce_variables_%zu", i));
- old_coin_value_variables[i].allocate(pb, coin_value_length, FMT(annotation_prefix, " old_coin_value_variables_%zu", i));
- }
-
- /* do the actual hashing */
- pb_variable_array<FieldT> zero_one;
- zero_one.emplace_back(zero);
- zero_one.emplace_back(ONE);
-
- prf_for_old_coin_serial_number_input_variables.resize(num_old_coins);
- prfs_for_old_coin_serial_numbers.resize(num_old_coins);
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- /* (C) old_coin_serial_number_variables[i] = PRF_{old_address_secret_key_variables[i]}^{sn}
- (old_coin_serial_number_nonce_variables[0..254]) =
- H(old_address_secret_key_variables[i] || 01 || old_coin_serial_number_nonce_variables[0..254]) */
- prf_for_old_coin_serial_number_input_variables[i].reset(new block_variable<FieldT>(pb, {
- old_address_secret_key_variables[i],
- zero_one,
- pb_variable_array<FieldT>(old_coin_serial_number_nonce_variables[i].begin(),
- old_coin_serial_number_nonce_variables[i].begin() + truncated_serial_number_length) },
- FMT(annotation_prefix, " prf_for_old_coin_serial_number_input_variables_%zu", i)));
- prfs_for_old_coin_serial_numbers[i].reset(new sha256_compression_function_gadget<FieldT>(pb, IV, prf_for_old_coin_serial_number_input_variables[i]->bits, *old_coin_serial_number_variables[i], FMT(annotation_prefix, " prfs_for_old_coin_serial_numbers_%zu", i)));
- }
-
- old_address_public_key_variables.resize(num_old_coins);
- prf_for_old_address_public_key_input_variables.resize(num_old_coins);
- prfs_for_old_address_public_keys.resize(num_old_coins);
-
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- old_address_public_key_variables[i].reset(new digest_variable<FieldT>(pb, sha256_digest_len, FMT(annotation_prefix, " old_address_public_key_variables_%zu", i)));
-
- /* (B) old_address_public_keys[i] = PRF_{old_address_secret_key_variables[i]}^{addr}(z) =
- H(old_address_secret_key_variables[i] || 00 || z), where z = 0...0 */
- pb_variable_array<FieldT> addr_pk_pad(address_public_key_padding_length, zero);
- prf_for_old_address_public_key_input_variables[i].reset(new block_variable<FieldT>(pb,
- { old_address_secret_key_variables[i], addr_pk_pad },
- FMT(annotation_prefix, " prf_for_old_address_public_key_input_variables_%zu", i)));
- prfs_for_old_address_public_keys[i].reset(new sha256_compression_function_gadget<FieldT>(pb,
- IV,
- prf_for_old_address_public_key_input_variables[i]->bits,
- *old_address_public_key_variables[i],
- FMT(annotation_prefix, " prfs_for_old_address_public_keys_%zu", i)));
- }
-
- commitments_to_old_address_public_keys.resize(num_old_coins);
- commit_to_old_address_public_key_input_variables.resize(num_old_coins);
- commit_to_old_address_public_keys.resize(num_old_coins);
-
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- /* (D0) commitments_to_old_address_public_keys[i] = H(old_address_public_key_variables[i] || old_coin_serial_number_nonce_variables[i]) */
- commitments_to_old_address_public_keys[i].reset(new digest_variable<FieldT>(pb, sha256_digest_len, FMT(annotation_prefix, " commitments_to_old_address_public_keys_%zu", i)));
- commit_to_old_address_public_key_input_variables[i].reset(new block_variable<FieldT>(pb, { old_address_public_key_variables[i]->bits, old_coin_serial_number_nonce_variables[i] }, FMT(annotation_prefix, " commit_to_old_address_public_key_input_variables_%zu", i)));
- commit_to_old_address_public_keys[i].reset(new sha256_compression_function_gadget<FieldT>(pb, IV, commit_to_old_address_public_key_input_variables[i]->bits, *commitments_to_old_address_public_keys[i], FMT(annotation_prefix, " commit_to_old_address_public_keys_%zu", i)));
- }
-
- old_coin_value_commitment_nonces.resize(num_old_coins);
- commit_to_old_coin_value_commitment_nonce_input_variables.resize(num_old_coins);
- commit_to_old_coin_value_commitment_nonces.resize(num_old_coins);
-
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- /* (D1) old_coin_value_commitment_nonces[i] =
- H(old_address_commitment_nonce_variables[i] || commitments_to_old_address_public_keys[i] [0..128]) */
- old_coin_value_commitment_nonces[i].reset(new digest_variable<FieldT>(pb, sha256_digest_len, FMT(annotation_prefix, " old_coin_value_commitment_nonces_%zu", i)));
- commit_to_old_coin_value_commitment_nonce_input_variables[i].reset(new block_variable<FieldT>(pb, { old_address_commitment_nonce_variables[i], pb_variable_array<FieldT>(commitments_to_old_address_public_keys[i]->bits.begin(), commitments_to_old_address_public_keys[i]->bits.begin()+ truncated_coin_commitment_length) }, FMT(annotation_prefix, " commit_to_old_coin_value_commitment_nonce_input_variables_%zu", i)));
- commit_to_old_coin_value_commitment_nonces[i].reset(new sha256_compression_function_gadget<FieldT>(pb, IV, commit_to_old_coin_value_commitment_nonce_input_variables[i]->bits, *old_coin_value_commitment_nonces[i], FMT(annotation_prefix, " commit_to_old_coin_value_commitment_nonces_%zu", i)));
- }
-
- pb_variable_array<FieldT> coincomm_pad(coin_commitment_padding_length, zero);
- old_coin_commitment_variables.resize(num_old_coins);
- compute_old_coin_commitment_input_variables.resize(num_old_coins);
- compute_old_coin_commitments.resize(num_old_coins);
-
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- /* (D2) old_coin_commitment_variables[i] = COMM_s(old_coin_value_variables[i] || old_coin_value_commitment_nonces[i])
- H(old_coin_value_commitment_nonces[i] || 0^{192} || old_coin_value_variables[i])
-
- Here we ignore commitment randomness s, as k = old_coin_value_commitment_nonces[i] is an output of a
- statistically hiding commitment scheme. */
- old_coin_commitment_variables[i].reset(new digest_variable<FieldT>(pb, sha256_digest_len, FMT(annotation_prefix, " old_coin_commitment_variables_%zu", i)));
- compute_old_coin_commitment_input_variables[i].reset(new block_variable<FieldT>(pb, { old_coin_value_commitment_nonces[i]->bits, coincomm_pad, old_coin_value_variables[i] }, FMT(annotation_prefix, " compute_old_coin_commitment_input_variables_%zu", i)));
- compute_old_coin_commitments[i].reset(new sha256_compression_function_gadget<FieldT>(pb, IV, compute_old_coin_commitment_input_variables[i]->bits, *old_coin_commitment_variables[i], FMT(annotation_prefix, " compute_old_coin_commitment_%zu", i)));
- }
-
- commitments_to_new_address_public_keys.resize(num_new_coins);
- commit_to_new_address_public_key_input_variables.resize(num_new_coins);
- commit_to_new_address_public_keys.resize(num_new_coins);
-
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- /* (E0) commitments_to_new_address_public_keys[i] = H(new_address_public_key_variables[i] || new_coin_serial_number_nonce_variables[i]) */
- commitments_to_new_address_public_keys[i].reset(new digest_variable<FieldT>(pb, sha256_digest_len, FMT(annotation_prefix, " commitments_to_new_address_public_keys_%zu", i)));
- commit_to_new_address_public_key_input_variables[i].reset(new block_variable<FieldT>(pb, { new_address_public_key_variables[i], new_coin_serial_number_nonce_variables[i] }, FMT(annotation_prefix, " commit_to_new_address_public_key_input_variables_%zu", i)));
- commit_to_new_address_public_keys[i].reset(new sha256_compression_function_gadget<FieldT>(pb, IV, commit_to_new_address_public_key_input_variables[i]->bits, *commitments_to_new_address_public_keys[i], FMT(annotation_prefix, " commit_to_new_address_public_keys_%zu", i)));
- }
-
- new_coin_value_commitment_nonces.resize(num_new_coins);
- commit_to_new_coin_value_commitment_nonce_input_variables.resize(num_new_coins);
- commit_to_new_coin_value_commitment_nonces.resize(num_new_coins);
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- /* (E1) new_coin_value_commitment_nonces[i] =
- H(new_address_commitment_nonce_variables[i] || commitments_to_new_address_public_keys[i] [0..128]) */
- new_coin_value_commitment_nonces[i].reset(new digest_variable<FieldT>(pb, sha256_digest_len, FMT(annotation_prefix, " new_coin_value_commitment_nonces_%zu", i)));
- commit_to_new_coin_value_commitment_nonce_input_variables[i].reset(new block_variable<FieldT>(pb, { new_address_commitment_nonce_variables[i], pb_variable_array<FieldT>(commitments_to_new_address_public_keys[i]->bits.begin(), commitments_to_new_address_public_keys[i]->bits.begin()+ truncated_coin_commitment_length) }, FMT(annotation_prefix, " commit_to_new_coin_value_commitment_nonce_input_variables_%zu", i)));
- commit_to_new_coin_value_commitment_nonces[i].reset(new sha256_compression_function_gadget<FieldT>(pb, IV, commit_to_new_coin_value_commitment_nonce_input_variables[i]->bits, *new_coin_value_commitment_nonces[i], FMT(annotation_prefix, " commit_to_new_coin_value_commitment_nonces_%zu", i)));
- }
-
- compute_new_coin_commitment_input_variables.resize(num_new_coins);
- compute_new_coin_commitments.resize(num_new_coins);
-
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- /* (E2) new_coin_commitment_variables[i] = COMM_s(new_coin_value_variables[i] || new_coin_value_commitment_nonces[i])
- H(new_coin_value_commitment_nonces[i] || 0^{192} || new_coin_value_variables[i]) */
- compute_new_coin_commitment_input_variables[i].reset(new block_variable<FieldT>(pb, { new_coin_value_commitment_nonces[i]->bits, coincomm_pad, new_coin_value_variables[i] }, FMT(annotation_prefix, " compute_new_coin_commitment_input_variables_%zu", i)));
- compute_new_coin_commitments[i].reset(new sha256_compression_function_gadget<FieldT>(pb, IV, compute_new_coin_commitment_input_variables[i]->bits, *new_coin_commitment_variables[i], FMT(annotation_prefix, " compute_new_coin_commitment_%zu", i)));
- }
-
- /* compute signature public key macs */
- prf_for_macs_of_signature_public_key_hash_input_variables.resize(num_old_coins);
- prfs_for_macs_of_signature_public_key_hash.resize(num_old_coins);
- const size_t truncated_signature_public_key_hash_length = indexed_signature_public_key_hash_length - log2(num_old_coins);
-
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- /* (F) mac_of_signature_public_key_hash_variables[i] = PRF_{old_address_secret_key_variables[i]}^{pk}
- (i || signature_public_key_hash_variable) =
- H(old_address_secret_key_variables[i] || 10 || i || signature_public_key_hash_variable)
-
- Here signature_public_key_hash is truncated so that the entire argument fits inside SHA256 block.
- Furthermore, the representation of i is MSB to LSB and is exactly log2(num_old_coins) bits long. */
- pb_variable_array<FieldT> prf_padding;
- prf_padding.emplace_back(ONE);
- prf_padding.emplace_back(zero);
-
- for (size_t j = 0; j < log2(num_old_coins); ++j)
- {
- prf_padding.emplace_back((i >> (log2(num_old_coins) - j - 1)) & 1 ? ONE : zero);
- }
-
- prf_for_macs_of_signature_public_key_hash_input_variables[i].reset(new block_variable<FieldT>(pb, { old_address_secret_key_variables[i], prf_padding, pb_variable_array<FieldT>(signature_public_key_hash_variable->bits.begin(), signature_public_key_hash_variable->bits.begin()+truncated_signature_public_key_hash_length) }, FMT(annotation_prefix, " prf_for_macs_of_signature_public_key_hash_input_variables_%zu", i)));
- prfs_for_macs_of_signature_public_key_hash[i].reset(new sha256_compression_function_gadget<FieldT>(pb, IV, prf_for_macs_of_signature_public_key_hash_input_variables[i]->bits, *mac_of_signature_public_key_hash_variables[i], FMT(annotation_prefix, " prfs_for_macs_of_signature_public_key_hash_%zu", i)));
- }
-
- /* prove membership in the Merkle tree*/
- old_coin_merkle_tree_position_variables.resize(num_old_coins);
- old_coin_authentication_path_variables.resize(num_old_coins);
- old_coin_commitments_in_tree.resize(num_old_coins);
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- /* (A) old_coin_commitment_variables[i] appears on path old_coin_authentication_paths[i]
- to merkle_tree_root_variable */
- old_coin_merkle_tree_position_variables[i].allocate(pb, tree_depth, FMT(annotation_prefix, " old_coin_merkle_tree_position_variables_%zu", i));
- old_coin_authentication_path_variables[i].reset(new merkle_authentication_path_variable<FieldT, sha256_two_to_one_hash_gadget<FieldT> >(pb, tree_depth, FMT(annotation_prefix, " old_coin_authentication_path_variables_%zu", i)));
- old_coin_commitments_in_tree[i].reset(new merkle_tree_check_read_gadget<FieldT, sha256_two_to_one_hash_gadget<FieldT> >(
- pb, tree_depth, old_coin_merkle_tree_position_variables[i], *old_coin_commitment_variables[i], *merkle_tree_root_variable,
- *old_coin_authentication_path_variables[i], old_coin_enforce_commitment[i], FMT(annotation_prefix, " old_coin_commitments_in_tree_%zu", i)));
- }
-}
-
-template<typename FieldT>
-void zerocash_pour_gadget<FieldT>::generate_r1cs_constraints()
-{
- generate_r1cs_equals_const_constraint<FieldT>(this->pb, zero, FieldT::zero(), FMT(this->annotation_prefix, " zero"));
-
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- prfs_for_old_coin_serial_numbers[i]->generate_r1cs_constraints();
- prfs_for_old_address_public_keys[i]->generate_r1cs_constraints();
- commit_to_old_address_public_keys[i]->generate_r1cs_constraints();
- commit_to_old_coin_value_commitment_nonces[i]->generate_r1cs_constraints();
- compute_old_coin_commitments[i]->generate_r1cs_constraints();
- old_coin_commitments_in_tree[i]->generate_r1cs_constraints();
- prfs_for_macs_of_signature_public_key_hash[i]->generate_r1cs_constraints();
-
- for (size_t j = 0; j < tree_depth; ++j)
- {
- generate_boolean_r1cs_constraint<FieldT>(this->pb, old_coin_merkle_tree_position_variables[i][j], FMT(this->annotation_prefix, " old_coin_merkle_tree_position_variables_%zu_%zu", i, j));
- }
- }
-
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- commit_to_new_address_public_keys[i]->generate_r1cs_constraints();
- commit_to_new_coin_value_commitment_nonces[i]->generate_r1cs_constraints();
- compute_new_coin_commitments[i]->generate_r1cs_constraints();
- }
-
- unpack_inputs->generate_r1cs_constraints(true);
-
- /* ensure bitness of all values */
- for (size_t j = 0; j < coin_value_length; ++j)
- {
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- generate_boolean_r1cs_constraint<FieldT>(this->pb, old_coin_value_variables[i][j], FMT(this->annotation_prefix, " old_coin_value_variables_%zu_%zu", i, j));
- }
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- generate_boolean_r1cs_constraint<FieldT>(this->pb, new_coin_value_variables[i][j], FMT(this->annotation_prefix, " new_coin_value_variables_%zu_%zu", i, j));
- }
- }
-
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- generate_boolean_r1cs_constraint<FieldT>(this->pb, old_coin_enforce_commitment[i], FMT(this->annotation_prefix, " old_coin_enforce_commitment_%zu", i));
- this->pb.add_r1cs_constraint(r1cs_constraint<FieldT>(
- pb_packing_sum<FieldT>(pb_variable_array<FieldT>(old_coin_value_variables[i].rbegin(), old_coin_value_variables[i].rend())),
- 1 - old_coin_enforce_commitment[i],
- 0), FMT(this->annotation_prefix, " enforce_%zu", i));
- }
-
- /* check the balance equation */
- linear_combination<FieldT> old_packed_value;
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- old_packed_value = old_packed_value + pb_packing_sum<FieldT>(pb_variable_array<FieldT>(old_coin_value_variables[i].rbegin(), old_coin_value_variables[i].rend()));
- }
- old_packed_value = old_packed_value + pb_packing_sum<FieldT>(pb_variable_array<FieldT>(public_old_value_variable.rbegin(), public_old_value_variable.rend()));
-
- linear_combination<FieldT> new_packed_value;
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- new_packed_value = new_packed_value + pb_packing_sum<FieldT>(pb_variable_array<FieldT>(new_coin_value_variables[i].rbegin(), new_coin_value_variables[i].rend()));
- }
- new_packed_value = new_packed_value + pb_packing_sum<FieldT>(pb_variable_array<FieldT>(public_new_value_variable.rbegin(), public_new_value_variable.rend()));
-
- this->pb.add_r1cs_constraint(r1cs_constraint<FieldT>(1, old_packed_value, new_packed_value), FMT(this->annotation_prefix, " balance"));
-}
-
-template<typename FieldT>
-void zerocash_pour_gadget<FieldT>::generate_r1cs_witness(const std::vector<merkle_authentication_path> &old_coin_authentication_paths,
- const std::vector<size_t> &old_coin_merkle_tree_positions,
- const bit_vector &merkle_tree_root,
- const std::vector<bit_vector> &new_address_public_keys,
- const std::vector<bit_vector> &old_address_secret_keys,
- const std::vector<bit_vector> &new_address_commitment_nonces,
- const std::vector<bit_vector> &old_address_commitment_nonces,
- const std::vector<bit_vector> &new_coin_serial_number_nonces,
- const std::vector<bit_vector> &old_coin_serial_number_nonces,
- const std::vector<bit_vector> &new_coin_values,
- const bit_vector &public_old_value,
- const bit_vector &public_new_value,
- const std::vector<bit_vector> &old_coin_values,
- const bit_vector &signature_public_key_hash)
-{
- /* fill in the auxiliary variables */
- this->pb.val(zero) = FieldT::zero();
-
- /* fill in the witness */
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- new_address_public_key_variables[i].fill_with_bits(this->pb, new_address_public_keys[i]);
- new_address_commitment_nonce_variables[i].fill_with_bits(this->pb, new_address_commitment_nonces[i]);
- }
-
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- old_address_secret_key_variables[i].fill_with_bits(this->pb, old_address_secret_keys[i]);
- old_address_commitment_nonce_variables[i].fill_with_bits(this->pb, old_address_commitment_nonces[i]);
- }
-
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- new_coin_serial_number_nonce_variables[i].fill_with_bits(this->pb, new_coin_serial_number_nonces[i]);
- new_coin_value_variables[i].fill_with_bits(this->pb, new_coin_values[i]);
- }
-
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- this->pb.val(old_coin_enforce_commitment[i]) = FieldT::zero();
- old_coin_serial_number_nonce_variables[i].fill_with_bits(this->pb, old_coin_serial_number_nonces[i]);
- old_coin_value_variables[i].fill_with_bits(this->pb, old_coin_values[i]);
-
- for (size_t j = 0; j < coin_value_length; ++j)
- {
- if (old_coin_values[i][j]) {
- // If any bit in the value is nonzero, the value is nonzero.
- // Thus, the old coin must be committed in the tree.
- this->pb.val(old_coin_enforce_commitment[i]) = FieldT::one();
- break;
- }
- }
- }
-
- public_old_value_variable.fill_with_bits(this->pb, public_old_value);
- public_new_value_variable.fill_with_bits(this->pb, public_new_value);
- signature_public_key_hash_variable->generate_r1cs_witness(signature_public_key_hash);
-
- /* do the hashing */
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- prfs_for_old_coin_serial_numbers[i]->generate_r1cs_witness();
- prfs_for_old_address_public_keys[i]->generate_r1cs_witness();
- commit_to_old_address_public_keys[i]->generate_r1cs_witness();
- commit_to_old_coin_value_commitment_nonces[i]->generate_r1cs_witness();
- compute_old_coin_commitments[i]->generate_r1cs_witness();
- prfs_for_macs_of_signature_public_key_hash[i]->generate_r1cs_witness();
- }
-
- for (size_t i = 0; i < num_new_coins; ++i)
- {
- commit_to_new_address_public_keys[i]->generate_r1cs_witness();
- commit_to_new_coin_value_commitment_nonces[i]->generate_r1cs_witness();
- compute_new_coin_commitments[i]->generate_r1cs_witness();
- }
-
- /* prove the membership in the Merkle tree */
- for (size_t i = 0; i < num_old_coins; ++i)
- {
- /* (A) old_coin_commitment_variables[i] appears on path old_coin_authentication_paths[i]
- to merkle_tree_root_variable */
- old_coin_merkle_tree_position_variables[i].fill_with_bits_of_ulong(this->pb, old_coin_merkle_tree_positions[i]);
- old_coin_authentication_path_variables[i]->generate_r1cs_witness(old_coin_merkle_tree_positions[i], old_coin_authentication_paths[i]);
- old_coin_commitments_in_tree[i]->generate_r1cs_witness();
- }
-
- /* pack the input */
- unpack_inputs->generate_r1cs_witness_from_bits();
-
-#ifdef DEBUG
- printf("input_as_field_elements according to witness map:\n");
- for (size_t i = 0; i < input_as_field_elements.size(); ++i)
- {
- this->pb.val(input_as_field_elements[i]).print();
- }
-#endif
-}
-
-template<typename FieldT>
-r1cs_primary_input<FieldT> zerocash_pour_input_map(const size_t num_old_coins,
- const size_t num_new_coins,
- const bit_vector &merkle_tree_root,
- const std::vector<bit_vector> &old_coin_serial_numbers,
- const std::vector<bit_vector> &new_coin_commitments,
- const bit_vector &public_old_value,
- const bit_vector &public_new_value,
- const bit_vector &signature_public_key_hash,
- const std::vector<bit_vector> &signature_public_key_hash_macs)
-{
- enter_block("Call to zerocash_pour_input_map");
- assert(merkle_tree_root.size() == sha256_digest_len);
- assert(old_coin_serial_numbers.size() == num_old_coins);
- for (auto &old_coin_serial_number : old_coin_serial_numbers)
- {
- assert(old_coin_serial_number.size() == serial_number_length);
- }
- assert(new_coin_commitments.size() == num_new_coins);
- for (auto &new_coin_commitment : new_coin_commitments)
- {
- assert(new_coin_commitment.size() == coin_commitment_length);
- }
- assert(public_old_value.size() == coin_value_length);
- assert(public_new_value.size() == coin_value_length);
- assert(signature_public_key_hash.size() == sha256_digest_len);
- assert(signature_public_key_hash_macs.size() == num_old_coins);
- for (auto &signature_public_key_hash_mac : signature_public_key_hash_macs)
- {
- assert(signature_public_key_hash_mac.size() == sha256_digest_len);
- }
-
- bit_vector input_as_bits;
-
- input_as_bits.insert(input_as_bits.end(), merkle_tree_root.begin(), merkle_tree_root.end());
- for (auto &old_coin_serial_number : old_coin_serial_numbers)
- {
- input_as_bits.insert(input_as_bits.end(), old_coin_serial_number.begin(), old_coin_serial_number.end());
- }
- for (auto &new_coin_commitment : new_coin_commitments)
- {
- input_as_bits.insert(input_as_bits.end(), new_coin_commitment.begin(), new_coin_commitment.end());
- }
- input_as_bits.insert(input_as_bits.end(), public_old_value.begin(), public_old_value.end());
- input_as_bits.insert(input_as_bits.end(), public_new_value.begin(), public_new_value.end());
- input_as_bits.insert(input_as_bits.end(), signature_public_key_hash.begin(), signature_public_key_hash.end());
- for (auto &signature_public_key_hash_mac : signature_public_key_hash_macs)
- {
- input_as_bits.insert(input_as_bits.end(), signature_public_key_hash_mac.begin(), signature_public_key_hash_mac.end());
- }
- std::vector<FieldT> input_as_field_elements = pack_bit_vector_into_field_element_vector<FieldT>(input_as_bits);
-
-#ifdef DEBUG
- printf("input_as_field_elements from zerocash_pour_input_map:\n");
- for (size_t i = 0; i < input_as_field_elements.size(); ++i)
- {
- input_as_field_elements[i].print();
- }
-#endif
- leave_block("Call to zerocash_pour_input_map");
-
- return input_as_field_elements;
-}
-
-} // libzerocash
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of various parameters used by the Pour gadget and Pour ppzkSNARK.
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef ZEROCASH_POUR_PARAMS_HPP_
-#define ZEROCASH_POUR_PARAMS_HPP_
-
-namespace libzerocash {
-
-const size_t sha256_block_len = 512;
-const size_t sha256_digest_len = 256;
-const size_t address_public_key_length = sha256_digest_len;
-const size_t address_public_key_padding_length = 256;
-const size_t address_secret_key_length = 256;
-const size_t coin_commitment_length = sha256_digest_len;
-const size_t coin_commitment_padding_length = 192;
-const size_t truncated_coin_commitment_length = 128;
-const size_t truncated_serial_number_length = 254;
-const size_t serial_number_length = sha256_digest_len;
-const size_t address_commitment_nonce_length = 384;
-const size_t serial_number_nonce_length = 256;
-const size_t coin_value_length = 64;
-const size_t indexed_signature_public_key_hash_length = 254;
-
-} // libzerocash
-
-#endif // ZEROCASH_POUR_PARAMS_HPP_
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Declaration of interfaces for a ppzkSNARK for the NP statement "Pour".
-
- This includes:
- - class for proving key
- - class for verification key
- - class for key pair (proving key & verification key)
- - class for proof
- - generator algorithm
- - prover algorithm
- - verifier algorithm
-
- The ppzkSNARK is obtained by using an R1CS ppzkSNARK relative to an R1CS
- realization of the NP statement "Pour". The implementation follows, extends,
- and optimizes the approach described in \[BCGGMTV14].
-
-
- Acronyms:
-
- - R1CS = "Rank-1 Constraint Systems"
- - ppzkSNARK = "PreProcessing Zero-Knowledge Succinct Non-interactive ARgument of Knowledge"
-
- References:
-
- \[BCGGMTV14]:
- "Zerocash: Decentralized Anonymous Payments from Bitcoin",
- Eli Ben-Sasson, Alessandro Chiesa, Christina Garman, Matthew Green, Ian Miers, Eran Tromer, Madars Virza,
- S&P 2014,
- <https://eprint.iacr.org/2014/349>
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef ZEROCASH_POUR_PPZKSNARK_HPP_
-#define ZEROCASH_POUR_PPZKSNARK_HPP_
-
-#include "libsnark/common/data_structures/merkle_tree.hpp"
-#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp"
-#include <stdexcept>
-
-namespace libzerocash {
-
-/******************************** Proving key ********************************/
-
-/**
- * A proving key for the Pour ppzkSNARK.
- */
-template<typename ppzksnark_ppT>
-class zerocash_pour_proving_key;
-
-template<typename ppzksnark_ppT>
-std::ostream& operator<<(std::ostream &out, const zerocash_pour_proving_key<ppzksnark_ppT> &pk);
-
-template<typename ppzksnark_ppT>
-std::istream& operator>>(std::istream &in, zerocash_pour_proving_key<ppzksnark_ppT> &pk);
-
-template<typename ppzksnark_ppT>
-class zerocash_pour_proving_key {
-public:
- size_t num_old_coins;
- size_t num_new_coins;
- size_t tree_depth;
- r1cs_ppzksnark_proving_key<ppzksnark_ppT> r1cs_pk;
-
- zerocash_pour_proving_key() = default;
- zerocash_pour_proving_key(const zerocash_pour_proving_key<ppzksnark_ppT> &other) = default;
- zerocash_pour_proving_key(zerocash_pour_proving_key<ppzksnark_ppT> &&other) = default;
- zerocash_pour_proving_key(const size_t num_old_coins,
- const size_t num_new_coins,
- const size_t tree_depth,
- const r1cs_ppzksnark_proving_key<ppzksnark_ppT> &r1cs_pk) :
- num_old_coins(num_old_coins), num_new_coins(num_new_coins),
- tree_depth(tree_depth), r1cs_pk(r1cs_pk) {}
- zerocash_pour_proving_key(const size_t num_old_coins,
- const size_t num_new_coins,
- const size_t tree_depth,
- r1cs_ppzksnark_proving_key<ppzksnark_ppT> &&r1cs_pk) :
- num_old_coins(num_old_coins), num_new_coins(num_new_coins),
- tree_depth(tree_depth), r1cs_pk(std::move(r1cs_pk)) {}
- zerocash_pour_proving_key<ppzksnark_ppT>& operator=(const zerocash_pour_proving_key<ppzksnark_ppT> &other) = default;
-
- bool operator==(const zerocash_pour_proving_key<ppzksnark_ppT> &other) const;
- friend std::ostream& operator<< <ppzksnark_ppT>(std::ostream &out, const zerocash_pour_proving_key<ppzksnark_ppT> &pk);
- friend std::istream& operator>> <ppzksnark_ppT>(std::istream &in, zerocash_pour_proving_key<ppzksnark_ppT> &pk);
-};
-
-/******************************* Verification key ****************************/
-
-/**
- * A verification key for the Pour ppzkSNARK.
- */
-template<typename ppzksnark_ppT>
-class zerocash_pour_verification_key;
-
-template<typename ppzksnark_ppT>
-std::ostream& operator<<(std::ostream &out, const zerocash_pour_verification_key<ppzksnark_ppT> &pk);
-
-template<typename ppzksnark_ppT>
-std::istream& operator>>(std::istream &in, zerocash_pour_verification_key<ppzksnark_ppT> &pk);
-
-template<typename ppzksnark_ppT>
-class zerocash_pour_verification_key {
-public:
- size_t num_old_coins;
- size_t num_new_coins;
- r1cs_ppzksnark_verification_key<ppzksnark_ppT> r1cs_vk;
-
- zerocash_pour_verification_key() = default;
- zerocash_pour_verification_key(const zerocash_pour_verification_key<ppzksnark_ppT> &other) = default;
- zerocash_pour_verification_key(zerocash_pour_verification_key<ppzksnark_ppT> &&other) = default;
- zerocash_pour_verification_key(const size_t num_old_coins,
- const size_t num_new_coins,
- const r1cs_ppzksnark_verification_key<ppzksnark_ppT> &r1cs_vk) :
- num_old_coins(num_old_coins), num_new_coins(num_new_coins),
- r1cs_vk(r1cs_vk) {}
- zerocash_pour_verification_key(const size_t num_old_coins,
- const size_t num_new_coins,
- r1cs_ppzksnark_verification_key<ppzksnark_ppT> &&r1cs_vk) :
- num_old_coins(num_old_coins), num_new_coins(num_new_coins),
- r1cs_vk(std::move(r1cs_vk)) {}
- zerocash_pour_verification_key<ppzksnark_ppT>& operator=(const zerocash_pour_verification_key<ppzksnark_ppT> &other) = default;
-
- bool operator==(const zerocash_pour_verification_key<ppzksnark_ppT> &other) const;
- friend std::ostream& operator<< <ppzksnark_ppT>(std::ostream &out, const zerocash_pour_verification_key<ppzksnark_ppT> &pk);
- friend std::istream& operator>> <ppzksnark_ppT>(std::istream &in, zerocash_pour_verification_key<ppzksnark_ppT> &pk);
-};
-
-/********************************** Key pair *********************************/
-
-/**
- * A key pair for the Pour ppzkSNARK, which consists of a proving key and a verification key.
- */
-template<typename ppzksnark_ppT>
-class zerocash_pour_keypair;
-
-template<typename ppzksnark_ppT>
-std::ostream& operator<<(std::ostream &out, const zerocash_pour_keypair<ppzksnark_ppT> &pk);
-
-template<typename ppzksnark_ppT>
-std::istream& operator>>(std::istream &in, zerocash_pour_keypair<ppzksnark_ppT> &pk);
-
-template<typename ppzksnark_ppT>
-class zerocash_pour_keypair {
-public:
- zerocash_pour_proving_key<ppzksnark_ppT> pk;
- zerocash_pour_verification_key<ppzksnark_ppT> vk;
-
- zerocash_pour_keypair() = default;
- zerocash_pour_keypair(const zerocash_pour_keypair<ppzksnark_ppT> &other) = default;
- zerocash_pour_keypair(zerocash_pour_keypair<ppzksnark_ppT> &&other) = default;
- zerocash_pour_keypair(const zerocash_pour_proving_key<ppzksnark_ppT> &pk,
- const zerocash_pour_verification_key<ppzksnark_ppT> &vk) :
- pk(pk), vk(vk) {}
- zerocash_pour_keypair(zerocash_pour_proving_key<ppzksnark_ppT> &&pk,
- zerocash_pour_verification_key<ppzksnark_ppT> &&vk) :
- pk(std::move(pk)),
- vk(std::move(vk)) {}
- zerocash_pour_keypair<ppzksnark_ppT>& operator=(const zerocash_pour_keypair<ppzksnark_ppT> &other) = default;
-
- bool operator==(const zerocash_pour_keypair<ppzksnark_ppT> &other) const;
- friend std::ostream& operator<< <ppzksnark_ppT>(std::ostream &out, const zerocash_pour_keypair<ppzksnark_ppT> &pk);
- friend std::istream& operator>> <ppzksnark_ppT>(std::istream &in, zerocash_pour_keypair<ppzksnark_ppT> &pk);
-};
-
-/*********************************** Proof ***********************************/
-
-/**
- * A proof for the Pour ppzkSNARK.
- */
-template<typename ppzksnark_ppT>
-using zerocash_pour_proof = r1cs_ppzksnark_proof<ppzksnark_ppT>;
-
-
-/***************************** Main algorithms *******************************/
-
-/**
- * A generator algorithm for the Pour ppzkSNARK.
- *
- * Given a tree depth d, this algorithm produces proving and verification keys
- * for Pour relative to a Merkle tree of depth d.
- */
-template<typename ppzksnark_ppT>
-zerocash_pour_keypair<ppzksnark_ppT> zerocash_pour_ppzksnark_generator(const size_t num_old_coins,
- const size_t num_new_coins,
- const size_t tree_depth);
-
-/**
- * A prover algorithm for the Pour ppzkSNARK.
- *
- * TODO: add description
- */
-template<typename ppzksnark_ppT>
-zerocash_pour_proof<ppzksnark_ppT> zerocash_pour_ppzksnark_prover(const zerocash_pour_proving_key<ppzksnark_ppT> &pk,
- const std::vector<merkle_authentication_path> &old_coin_authentication_paths,
- const std::vector<size_t> &old_coin_merkle_tree_positions,
- const bit_vector &merkle_tree_root,
- const std::vector<bit_vector> &new_address_public_keys,
- const std::vector<bit_vector> &old_address_secret_keys,
- const std::vector<bit_vector> &new_address_commitment_nonces,
- const std::vector<bit_vector> &old_address_commitment_nonces,
- const std::vector<bit_vector> &new_coin_serial_number_nonces,
- const std::vector<bit_vector> &old_coin_serial_number_nonces,
- const std::vector<bit_vector> &new_coin_values,
- const bit_vector &public_old_value,
- const bit_vector &public_new_value,
- const std::vector<bit_vector> &old_coin_values,
- const bit_vector &signature_public_key_hash);
-
-/**
- * A verifier algorithm for the Pour ppzkSNARK.
- */
-template<typename ppzksnark_ppT>
-bool zerocash_pour_ppzksnark_verifier(const zerocash_pour_verification_key<ppzksnark_ppT> &vk,
- const bit_vector &merkle_tree_root,
- const std::vector<bit_vector> &old_coin_serial_numbers,
- const std::vector<bit_vector> &new_coin_commitments,
- const bit_vector &public_old_value,
- const bit_vector &public_new_value,
- const bit_vector &signature_public_key_hash,
- const std::vector<bit_vector> &signature_public_key_hash_macs,
- const zerocash_pour_proof<ppzksnark_ppT> &proof);
-
-} // libzerocash
-
-#include "zerocash_pour_ppzksnark.tcc"
-
-#endif // ZEROCASH_POUR_PPZKSNARK_HPP_
+++ /dev/null
-/** @file
- *****************************************************************************
-
- Implementation of interfaces for a ppzkSNARK for the NP statement "Pour".
-
- See zerocash_pour_ppzksnark.hpp .
-
- *****************************************************************************
- * @author This file is part of libzerocash, developed by the Zerocash
- * project and contributors (see AUTHORS).
- * @copyright MIT license (see LICENSE file)
- *****************************************************************************/
-
-#ifndef ZEROCASH_POUR_PPZKSNARK_TCC_
-#define ZEROCASH_POUR_PPZKSNARK_TCC_
-
-#include "zerocash_pour_gadget.hpp"
-#include "common/profiling.hpp"
-
-namespace libzerocash {
-
-template<typename ppzksnark_ppT>
-bool zerocash_pour_proving_key<ppzksnark_ppT>::operator==(const zerocash_pour_proving_key<ppzksnark_ppT> &other) const
-{
- return (this->num_old_coins == other.num_old_coins &&
- this->num_new_coins == other.num_new_coins &&
- this->tree_depth == other.tree_depth &&
- this->r1cs_pk == other.r1cs_pk);
-}
-
-template<typename ppzksnark_ppT>
-std::ostream& operator<<(std::ostream &out, const zerocash_pour_proving_key<ppzksnark_ppT> &pk)
-{
- out << pk.num_old_coins << "\n";
- out << pk.num_new_coins << "\n";
- out << pk.tree_depth << "\n";
- out << pk.r1cs_pk;
-
- return out;
-}
-
-template<typename ppzksnark_ppT>
-std::istream& operator>>(std::istream &in, zerocash_pour_proving_key<ppzksnark_ppT> &pk)
-{
- in >> pk.num_old_coins;
- consume_newline(in);
- in >> pk.num_new_coins;
- consume_newline(in);
- in >> pk.tree_depth;
- consume_newline(in);
- in >> pk.r1cs_pk;
-
- return in;
-}
-
-template<typename ppzksnark_ppT>
-bool zerocash_pour_verification_key<ppzksnark_ppT>::operator==(const zerocash_pour_verification_key<ppzksnark_ppT> &other) const
-{
- return (this->num_old_coins == other.num_old_coins &&
- this->num_new_coins == other.num_new_coins &&
- this->r1cs_vk == other.r1cs_vk);
-}
-
-template<typename ppzksnark_ppT>
-std::ostream& operator<<(std::ostream &out, const zerocash_pour_verification_key<ppzksnark_ppT> &vk)
-{
- out << vk.num_old_coins << "\n";
- out << vk.num_new_coins << "\n";
- out << vk.r1cs_vk;
-
- return out;
-}
-
-template<typename ppzksnark_ppT>
-std::istream& operator>>(std::istream &in, zerocash_pour_verification_key<ppzksnark_ppT> &vk)
-{
- in >> vk.num_old_coins;
- consume_newline(in);
- in >> vk.num_new_coins;
- consume_newline(in);
- in >> vk.r1cs_vk;
-
- return in;
-}
-
-template<typename ppzksnark_ppT>
-bool zerocash_pour_keypair<ppzksnark_ppT>::operator==(const zerocash_pour_keypair<ppzksnark_ppT> &other) const
-{
- return (this->pk == other.pk &&
- this->vk == other.vk);
-}
-
-template<typename ppzksnark_ppT>
-std::ostream& operator<<(std::ostream &out, const zerocash_pour_keypair<ppzksnark_ppT> &kp)
-{
- out << kp.pk;
- out << kp.vk;
-
- return out;
-}
-
-template<typename ppzksnark_ppT>
-std::istream& operator>>(std::istream &in, zerocash_pour_keypair<ppzksnark_ppT> &kp)
-{
- in >> kp.pk;
- in >> kp.vk;
-
- return in;
-}
-
-template<typename ppzksnark_ppT>
-zerocash_pour_keypair<ppzksnark_ppT> zerocash_pour_ppzksnark_generator(const size_t num_old_coins,
- const size_t num_new_coins,
- const size_t tree_depth)
-{
- typedef Fr<ppzksnark_ppT> FieldT;
- enter_block("Call to zerocash_pour_ppzksnark_generator");
-
- protoboard<FieldT> pb;
- zerocash_pour_gadget<FieldT> g(pb, num_old_coins, num_new_coins, tree_depth, "zerocash_pour");
- g.generate_r1cs_constraints();
- const r1cs_constraint_system<FieldT> constraint_system = pb.get_constraint_system();
- r1cs_ppzksnark_keypair<ppzksnark_ppT> ppzksnark_keypair = r1cs_ppzksnark_generator<ppzksnark_ppT>(constraint_system);
- leave_block("Call to zerocash_pour_ppzksnark_generator");
-
- zerocash_pour_proving_key<ppzksnark_ppT> zerocash_pour_pk(num_old_coins, num_new_coins, tree_depth, std::move(ppzksnark_keypair.pk));
- zerocash_pour_verification_key<ppzksnark_ppT> zerocash_pour_vk(num_old_coins, num_new_coins, std::move(ppzksnark_keypair.vk));
- return zerocash_pour_keypair<ppzksnark_ppT>(std::move(zerocash_pour_pk), std::move(zerocash_pour_vk));
-}
-
-template<typename ppzksnark_ppT>
-zerocash_pour_proof<ppzksnark_ppT> zerocash_pour_ppzksnark_prover(const zerocash_pour_proving_key<ppzksnark_ppT> &pk,
- const std::vector<merkle_authentication_path> &old_coin_authentication_paths,
- const std::vector<size_t> &old_coin_merkle_tree_positions,
- const bit_vector &merkle_tree_root,
- const std::vector<bit_vector> &new_address_public_keys,
- const std::vector<bit_vector> &old_address_secret_keys,
- const std::vector<bit_vector> &new_address_commitment_nonces,
- const std::vector<bit_vector> &old_address_commitment_nonces,
- const std::vector<bit_vector> &new_coin_serial_number_nonces,
- const std::vector<bit_vector> &old_coin_serial_number_nonces,
- const std::vector<bit_vector> &new_coin_values,
- const bit_vector &public_old_value,
- const bit_vector &public_new_value,
- const std::vector<bit_vector> &old_coin_values,
- const bit_vector &signature_public_key_hash)
-{
- typedef Fr<ppzksnark_ppT> FieldT;
-
- enter_block("Call to zerocash_pour_ppzksnark_prover");
-
- protoboard<FieldT> pb;
- zerocash_pour_gadget<FieldT > g(pb, pk.num_old_coins, pk.num_new_coins, pk.tree_depth, "zerocash_pour");
- g.generate_r1cs_constraints();
- g.generate_r1cs_witness(old_coin_authentication_paths,
- old_coin_merkle_tree_positions,
- merkle_tree_root,
- new_address_public_keys,
- old_address_secret_keys,
- new_address_commitment_nonces,
- old_address_commitment_nonces,
- new_coin_serial_number_nonces,
- old_coin_serial_number_nonces,
- new_coin_values,
- public_old_value,
- public_new_value,
- old_coin_values,
- signature_public_key_hash);
- if (!pb.is_satisfied()) {
- leave_block("Call to zerocash_pour_ppzksnark_prover");
- throw std::invalid_argument("Constraints not satisfied by inputs");
- }
-
- zerocash_pour_proof<ppzksnark_ppT> proof = r1cs_ppzksnark_prover<ppzksnark_ppT>(pk.r1cs_pk, pb.primary_input(), pb.auxiliary_input());
-
- leave_block("Call to zerocash_pour_ppzksnark_prover");
-
- return proof;
-}
-
-template<typename ppzksnark_ppT>
-bool zerocash_pour_ppzksnark_verifier(const zerocash_pour_verification_key<ppzksnark_ppT> &vk,
- const bit_vector &merkle_tree_root,
- const std::vector<bit_vector> &old_coin_serial_numbers,
- const std::vector<bit_vector> &new_coin_commitments,
- const bit_vector &public_old_value,
- const bit_vector &public_new_value,
- const bit_vector &signature_public_key_hash,
- const std::vector<bit_vector> &signature_public_key_hash_macs,
- const zerocash_pour_proof<ppzksnark_ppT> &proof)
-{
- typedef Fr<ppzksnark_ppT> FieldT;
-
- enter_block("Call to zerocash_pour_ppzksnark_verifier");
- const r1cs_primary_input<FieldT> input = zerocash_pour_input_map<FieldT>(vk.num_old_coins,
- vk.num_new_coins,
- merkle_tree_root,
- old_coin_serial_numbers,
- new_coin_commitments,
- public_old_value,
- public_new_value,
- signature_public_key_hash,
- signature_public_key_hash_macs);
- const bool ans = r1cs_ppzksnark_verifier_strong_IC<ppzksnark_ppT>(vk.r1cs_vk, input, proof);
- leave_block("Call to zerocash_pour_ppzksnark_verifier");
-
- return ans;
-}
-
-} // libzerocash
-
-#endif // ZEROCASH_POUR_PPZKSNARK_TCC_