Skip to content

Commit

Permalink
Merge pull request #145 from gogoex/set-mem-proof-generator-deriver
Browse files Browse the repository at this point in the history
Use the same G and H generators in range proof and set membership proof. Allow TokenId and blsct::Message as a seed for range proof
  • Loading branch information
aguycalled authored Feb 28, 2024
2 parents 9a3786d + 8ba32e9 commit 08b1849
Show file tree
Hide file tree
Showing 30 changed files with 525 additions and 204 deletions.
4 changes: 2 additions & 2 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -865,9 +865,9 @@ libbitcoin_common_a_SOURCES = \
blsct/public_keys.cpp \
blsct/range_proof/bulletproofs/amount_recovery_request.cpp \
blsct/range_proof/bulletproofs/amount_recovery_result.cpp \
blsct/range_proof/bulletproofs/range_proof.cpp \
blsct/range_proof/bulletproofs/range_proof_logic.cpp \
blsct/range_proof/bulletproofs/range_proof_with_transcript.cpp \
blsct/range_proof/bulletproofs/range_proof.cpp \
blsct/range_proof/bulletproofs_plus/amount_recovery_request.cpp \
blsct/range_proof/bulletproofs_plus/amount_recovery_result.cpp \
blsct/range_proof/bulletproofs_plus/range_proof.cpp \
Expand Down Expand Up @@ -1167,9 +1167,9 @@ libnavcoinkernel_la_SOURCES = \
blsct/public_keys.cpp \
blsct/range_proof/bulletproofs/amount_recovery_request.cpp \
blsct/range_proof/bulletproofs/amount_recovery_result.cpp \
blsct/range_proof/bulletproofs/range_proof.cpp \
blsct/range_proof/bulletproofs/range_proof_logic.cpp \
blsct/range_proof/bulletproofs/range_proof_with_transcript.cpp \
blsct/range_proof/bulletproofs/range_proof.cpp \
blsct/range_proof/bulletproofs_plus/amount_recovery_request.cpp \
blsct/range_proof/bulletproofs_plus/amount_recovery_result.cpp \
blsct/range_proof/bulletproofs_plus/range_proof.cpp \
Expand Down
35 changes: 27 additions & 8 deletions src/blsct/building_block/generator_deriver.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
#include <blsct/building_block/generator_deriver.h>
#include <blsct/arith/mcl/mcl.h>
#include <blsct/common.h>
#include <stdexcept>
#include <util/strencodings.h>
#include <hash.h>
#include <optional>
#include <variant>

template <typename Point>
Point GeneratorDeriver<Point>::Derive(
const Point& p,
const size_t index,
const std::optional<TokenId>& token_id
const std::optional<Seed>& opt_seed
) const {
std::vector<uint8_t> serialized_p = p.GetVch();

Expand All @@ -17,13 +20,29 @@ Point GeneratorDeriver<Point>::Derive(
os << n;
return os.str();
};
std::string hash_preimage =
HexStr(serialized_p) +
salt_str +
num_to_str(index) +
(token_id.has_value() ? token_id.value().ToString() : "") +
(token_id.has_value() ? "nft" + num_to_str(token_id.value().subid) : "");
std::string hash_preimage;

if (std::holds_alternative<TokenId>(opt_seed.value())) {
auto token_id = std::get<TokenId>(opt_seed.value());
hash_preimage =
HexStr(serialized_p) +
salt_str +
num_to_str(index) +
token_id.ToString() +
"nft" + num_to_str(token_id.subid)
;
} else if (std::holds_alternative<blsct::Message>(opt_seed.value())) {
auto message = std::get<Bytes>(opt_seed.value());
hash_preimage =
HexStr(serialized_p) +
salt_str +
num_to_str(index) +
"DERIVATION_FROM_MESSAGE" +
HexStr(message)
;
} else {
throw new std::runtime_error("Unexpected seed type");
}
HashWriter ss{};
ss << hash_preimage;
auto hash = ss.GetHash();
Expand All @@ -40,5 +59,5 @@ template
typename Mcl::Point GeneratorDeriver<typename Mcl::Point>::Derive(
const Mcl::Point& p,
const size_t index,
const std::optional<TokenId>& token_id
const std::optional<Seed>& seed
) const;
11 changes: 9 additions & 2 deletions src/blsct/building_block/generator_deriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,27 @@
#include <ctokens/tokenid.h>
#include <optional>
#include <string>
#include <variant>
#include <vector>

using Bytes = std::vector<uint8_t>;

template <typename Point>
class GeneratorDeriver {
public:
using Seed = std::variant<TokenId, Bytes>;

GeneratorDeriver(const std::string& salt_str): salt_str{salt_str} {}

Point Derive(
const Point& p,
const size_t index,
const std::optional<TokenId>& token_id = std::nullopt
const std::optional<Seed>& opt_token_id = TokenId()
) const;

private:
const std::string salt_str;
};

#endif // NAVCOIN_BLSCT_GENERATOR_DERIVER_H
#endif // NAVCOIN_BLSCT_GENERATOR_DERIVER_H

1 change: 0 additions & 1 deletion src/blsct/building_block/imp_inner_prod_arg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <blsct/building_block/imp_inner_prod_arg.h>
#include <blsct/building_block/lazy_points.h>
#include <blsct/common.h>
#include <blsct/range_proof/bulletproofs/range_proof.h>
#include <blsct/range_proof/setup.h>

template <typename T>
Expand Down
1 change: 0 additions & 1 deletion src/blsct/building_block/imp_inner_prod_arg.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

#include <blsct/arith/mcl/mcl.h>
#include <blsct/arith/elements.h>
#include <blsct/range_proof/bulletproofs/range_proof.h>
#include <hash.h>
#include <vector>
#include <optional>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#include <blsct/arith/mcl/mcl.h>
#include <blsct/range_proof/bulletproofs/amount_recovery_request.h>
#include <blsct/range_proof/bulletproofs/range_proof_with_transcript.h>
#include <blsct/range_proof/bulletproofs/range_proof.h>

#include <stdexcept>
#include <variant>

namespace bulletproofs {

Expand All @@ -15,15 +19,16 @@ AmountRecoveryRequest<T> AmountRecoveryRequest<T>::of(RangeProof<T>& proof, type

AmountRecoveryRequest<T> req{
1,
proof.token_id,
proof.seed,
proof_with_transcript.x,
proof_with_transcript.z,
proof.Vs,
proof.Ls,
proof.Rs,
proof.mu,
proof.tau_x,
nonce};
nonce
};
return req;
}
template AmountRecoveryRequest<Mcl> AmountRecoveryRequest<Mcl>::of(RangeProof<Mcl>&, Mcl::Point&);
Expand Down
9 changes: 6 additions & 3 deletions src/blsct/range_proof/bulletproofs/amount_recovery_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#define NAVCOIN_BLSCT_ARITH_RANGE_PROOF_BULLETPROOFS_AMOUNT_RECOVERY_REQUEST_H

#include <blsct/arith/elements.h>
#include <blsct/building_block/generator_deriver.h>
#include <blsct/range_proof/bulletproofs/range_proof.h>
#include <ctokens/tokenid.h>

namespace bulletproofs {

Expand All @@ -19,7 +19,7 @@ struct AmountRecoveryRequest
using Points = Elements<Point>;

size_t id;
TokenId token_id;
typename GeneratorDeriver<T>::Seed seed;
Scalar x;
Scalar z;
Points Vs;
Expand All @@ -29,7 +29,10 @@ struct AmountRecoveryRequest
Scalar tau_x;
Point nonce;

static AmountRecoveryRequest<T> of(RangeProof<T>& proof, Point& nonce);
static AmountRecoveryRequest<T> of(
RangeProof<T>& proof,
Point& nonce
);
};

} // namespace bulletproofs
Expand Down
19 changes: 16 additions & 3 deletions src/blsct/range_proof/bulletproofs/range_proof.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,28 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <blsct/range_proof/bulletproofs/range_proof.h>
#include <blsct/arith/mcl/mcl.h>
#include <blsct/common.h>
#include <variant>

namespace bulletproofs {

template <typename T>
bool RangeProof<T>::operator==(const RangeProof<T>& other) const
{
return range_proof::ProofBase<T>::operator==(other) &&
token_id == other.token_id &&
using P = range_proof::ProofBase<T>;
auto this_parent = static_cast<const P&>(*this);
auto other_parent = static_cast<const P&>(other);

bool seed_matches = false;
if (std::holds_alternative<TokenId>(seed) && std::holds_alternative<TokenId>(other.seed)) {
seed_matches = std::get<TokenId>(seed) == std::get<TokenId>(other.seed);
} else if (std::holds_alternative<blsct::Message>(seed) && std::holds_alternative<blsct::Message>(other.seed)) {
seed_matches = std::get<blsct::Message>(seed) == std::get<blsct::Message>(other.seed);
}

return
this_parent == other_parent &&
seed_matches &&
A == other.A &&
S == other.S &&
T1 == other.T1 &&
Expand Down
23 changes: 20 additions & 3 deletions src/blsct/range_proof/bulletproofs/range_proof.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@
#include <blsct/arith/mcl/mcl.h>
#include <blsct/arith/mcl/mcl_g1point.h>
#include <blsct/arith/mcl/mcl_scalar.h>
#include <blsct/building_block/generator_deriver.h>
#include <blsct/range_proof/proof_base.h>

#include <ctokens/tokenid.h>
#include <span.h>
#include <streams.h>

#include <variant>
#include <stdexcept>

namespace bulletproofs {

template <typename T>
Expand All @@ -22,8 +27,6 @@ struct RangeProof: public range_proof::ProofBase<T> {
using Scalar = typename T::Scalar;
using Points = Elements<Point>;

TokenId token_id;

// intermediate values used to derive random values later
Point A;
Point S;
Expand All @@ -37,14 +40,23 @@ struct RangeProof: public range_proof::ProofBase<T> {
Scalar b; // result of inner product argument
Scalar t_hat; // inner product of l and r

// seed to derive generators
typename GeneratorDeriver<T>::Seed seed;

bool operator==(const RangeProof<T>& other) const;
bool operator!=(const RangeProof<T>& other) const;

template <typename Stream>
void Serialize(Stream& s) const
{
range_proof::ProofBase<T>::Serialize(s);
::Serialize(s, token_id);

if (std::holds_alternative<TokenId>(seed)) {
auto token_id = std::get<TokenId>(seed);
::Serialize(s, token_id);
} else {
throw new std::runtime_error("Only TokenId seed can be serialized");
}
::Serialize(s, A);
::Serialize(s, S);
::Serialize(s, T1);
Expand All @@ -60,7 +72,12 @@ struct RangeProof: public range_proof::ProofBase<T> {
void Unserialize(Stream& s)
{
range_proof::ProofBase<T>::Unserialize(s);

// expect to unserialize RangeProof w/ TokenId only
TokenId token_id;
::Unserialize(s, token_id);
seed = token_id;

::Unserialize(s, A);
::Unserialize(s, S);
::Unserialize(s, T1);
Expand Down
17 changes: 11 additions & 6 deletions src/blsct/range_proof/bulletproofs/range_proof_logic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@
#include <blsct/building_block/lazy_points.h>
#include <blsct/building_block/g_h_gi_hi_zero_verifier.h>
#include <blsct/common.h>
#include <blsct/range_proof/bulletproofs/range_proof.h>
#include <blsct/range_proof/bulletproofs/range_proof_logic.h>
#include <blsct/range_proof/common.h>
#include <blsct/range_proof/msg_amt_cipher.h>
#include <stdexcept>
#include <tinyformat.h>
#include <optional>
#include <variant>

namespace bulletproofs {

Expand All @@ -23,7 +26,7 @@ RangeProof<T> RangeProofLogic<T>::Prove(
Elements<typename T::Scalar>& vs,
typename T::Point& nonce,
const std::vector<uint8_t>& message,
const TokenId& token_id
const Seed& seed
) const {
using Scalar = typename T::Scalar;
using Scalars = Elements<Scalar>;
Expand All @@ -39,7 +42,7 @@ RangeProof<T> RangeProofLogic<T>::Prove(

////////////// Proving steps
RangeProof<T> proof;
proof.token_id = token_id;
proof.seed = seed;

// generate gammas
Scalars gammas;
Expand All @@ -54,7 +57,7 @@ RangeProof<T> RangeProofLogic<T>::Prove(
}

// Get Generators<P> for the token_id
range_proof::Generators<T> gens = m_common.Gf().GetInstance(token_id);
range_proof::Generators<T> gens = m_common.Gf().GetInstance(seed);
auto Gi = gens.GetGiSubset(concat_input_values_in_bits);
auto Hi = gens.GetHiSubset(concat_input_values_in_bits);
auto H = gens.H;
Expand Down Expand Up @@ -210,13 +213,14 @@ RangeProof<T> RangeProofLogic<T>::Prove(
proof.a = res.value().a;
proof.b = res.value().b;
}

return proof;
}
template RangeProof<Mcl> RangeProofLogic<Mcl>::Prove(
Elements<Mcl::Scalar>&,
Mcl::Point&,
const std::vector<uint8_t>&,
const TokenId&
const Seed&
) const;

template <typename T>
Expand All @@ -230,7 +234,7 @@ bool RangeProofLogic<T>::VerifyProofs(
for (const RangeProofWithTranscript<T>& p : proof_transcripts) {
if (p.proof.Ls.Size() != p.proof.Rs.Size()) return false;

const range_proof::Generators<T> gens = m_common.Gf().GetInstance(p.proof.token_id);
const range_proof::Generators<T> gens = m_common.Gf().GetInstance(p.proof.seed);
G_H_Gi_Hi_ZeroVerifier<T> verifier(max_mn);

auto num_rounds = range_proof::Common<T>::GetNumRoundsExclLast(p.proof.Vs.Size());
Expand Down Expand Up @@ -343,6 +347,7 @@ bool RangeProofLogic<T>::Verify(
size_t max_num_rounds = 0;

for (const RangeProof<T>& proof : proofs) {

// update max # of rounds and sum of all V bits
max_num_rounds = std::max(max_num_rounds, proof.Ls.Size());

Expand Down Expand Up @@ -374,7 +379,7 @@ AmountRecoveryResult<T> RangeProofLogic<T>::RecoverAmounts(

for (size_t i = 0; i < reqs.size(); ++i) {
auto req = reqs[i];
const range_proof::Generators<T> gens = m_common.Gf().GetInstance(req.token_id);
const range_proof::Generators<T> gens = m_common.Gf().GetInstance(req.seed);
Point G = gens.G;
Point H = gens.H;

Expand Down
Loading

0 comments on commit 08b1849

Please sign in to comment.