Skip to content

Commit

Permalink
Merge branch 'libspats-refactor' of ../../spats/firo into libspats-re…
Browse files Browse the repository at this point in the history
…factor
  • Loading branch information
levonpetrosyan93 committed Sep 5, 2024
2 parents 27d6059 + e96ce9d commit d6f6c0e
Show file tree
Hide file tree
Showing 22 changed files with 202 additions and 79 deletions.
5 changes: 4 additions & 1 deletion src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,10 @@ BITCOIN_TESTS = \
libspats/test/coin_test.cpp \
libspats/test/type_test.cpp \
libspats/test/base_asset_test.cpp \
libspats/test/spend_transaction_test.cpp
libspats/test/mint_transaction_test.cpp \
libspats/test/spend_transaction_test.cpp \
libspats/test/balance_test.cpp


if ENABLE_WALLET
BITCOIN_TESTS += \
Expand Down
21 changes: 20 additions & 1 deletion src/libspats/balance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,26 @@ bool Balance::verify(const GroupElement& C, const BalanceProof& proof)
const Scalar c = challenge(C, proof.A);
const GroupElement check2 = proof.A + C * c;

return (check2 + check1.inverse()).isInfinity();
std::vector<GroupElement> points;
std::vector<Scalar> scalars;
points.reserve(5);
scalars.reserve(5);

// tw * E + tx * F + tz * H = A + c * C
scalars.emplace_back(proof.tw);
points.emplace_back(E);
scalars.emplace_back(proof.tx);
points.emplace_back(F);
scalars.emplace_back(proof.tz);
points.emplace_back(H);
scalars.emplace_back(Scalar(uint64_t(1)).negate());
points.emplace_back(proof.A);
scalars.emplace_back(c.negate());
points.emplace_back(C);

MultiExponent result(points, scalars);
return result.get_multiple().isInfinity();
// return (check2 + check1.inverse()).isInfinity();
}

} // namespace spats
1 change: 1 addition & 0 deletions src/libspats/balance.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define FIRO_LIBSPATS_BALANCE_H

#include "balance_proof.h"
#include <secp256k1/include/MultiExponent.h>

namespace spats {

Expand Down
2 changes: 1 addition & 1 deletion src/libspats/balance_proof.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace spats{
class BalanceProof{
public:
inline std::size_t memoryRequired() const {
return Scalar::memoryRequired() + GroupElement::memoryRequired();
return 3*Scalar::memoryRequired() + GroupElement::memoryRequired();
}

ADD_SERIALIZE_METHODS;
Expand Down
14 changes: 11 additions & 3 deletions src/libspats/base_asset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ void BaseAsset::prove(const std::vector<Scalar>& y, const std::vector<Scalar>& z
const std::size_t n = y.size();

// Check statement validity
if (y.size() != z.size() && y.size() != C.size()) {
throw std::invalid_argument("Bad BaseAsset statement!1");
if (y.size() != z.size() || y.size() != C.size()) {
throw std::invalid_argument("Bad base asset statement!1");
}


for (std::size_t i = 0; i < n; i++) {
if (G * y[i] + H * z[i] != C[i]) {
throw std::invalid_argument("Bad BaseAsset statement!2");
throw std::invalid_argument("Bad base asset statement!2");
}
}

Expand All @@ -58,6 +58,10 @@ void BaseAsset::prove(const std::vector<Scalar>& y, const std::vector<Scalar>& z
proof.ty = ry;
proof.tz = rz;
for (std::size_t i = 0; i < n; i++) {
// c_power must be nonzero
if (c_power.isZero()) {
throw std::invalid_argument("Unexpected challenge!");
}
proof.ty += y[i].negate() * c_power;
proof.tz += z[i].negate() * c_power;
c_power *= c;
Expand Down Expand Up @@ -89,6 +93,10 @@ bool BaseAsset::verify(const std::vector<GroupElement>& C, const BaseAssetProof&
const Scalar c = challenge(C, proof.A);
Scalar c_power(c);
for (std::size_t i = 0; i < n; i++) {
// c_power must be nonzero
if (c_power.isZero()) {
throw std::invalid_argument("Unexpected challenge!");
}
points.emplace_back(C[i]);
scalars.emplace_back(c_power);
c_power *= c;
Expand Down
2 changes: 1 addition & 1 deletion src/libspats/base_asset_proof.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace spats {
class BaseAssetProof{
public:
inline std::size_t memoryRequired() const {
return Scalar::memoryRequired() + GroupElement::memoryRequired();
return 2*Scalar::memoryRequired() + GroupElement::memoryRequired();
}

ADD_SERIALIZE_METHODS;
Expand Down
2 changes: 1 addition & 1 deletion src/libspats/bpplus_proof.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class BPPlusProof{
}

inline std::size_t memoryRequired() const {
return 3*GroupElement::memoryRequired() + 3*Scalar::memoryRequired() + L.size()*GroupElement::memoryRequired() + R.size()*GroupElement::memoryRequired();
return 3*GroupElement::memoryRequired() + 5*Scalar::memoryRequired() + L.size()*GroupElement::memoryRequired() + R.size()*GroupElement::memoryRequired();
}

ADD_SERIALIZE_METHODS;
Expand Down
6 changes: 3 additions & 3 deletions src/libspats/coin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ Coin::Coin(
const Params* params,
const char type,
const Scalar& k,
const uint64_t& a,
const uint64_t& iota,
const Scalar& a,
const Scalar& iota,
const Address& address,
const uint64_t& v,
const std::string& memo,
Expand Down Expand Up @@ -47,7 +47,7 @@ Coin::Coin(
this->S = this->params->get_F() * SpatsUtils::hash_ser(k, serial_context) + address.get_Q2();

// // Construct the value commitment
this->C = this->params->get_E() * Scalar(a) + this->params->get_F() * Scalar(iota) + this->params->get_G() * Scalar(v) + this->params->get_H() * SpatsUtils::hash_val(k);
this->C = this->params->get_E() * a + this->params->get_F() * iota + this->params->get_G() * Scalar(v) + this->params->get_H() * SpatsUtils::hash_val(k);

// Check the memo validity, and pad if needed
if (memo.size() > this->params->get_memo_bytes()) {
Expand Down
15 changes: 7 additions & 8 deletions src/libspats/coin.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ const char COIN_TYPE_SPEND = 1;
struct IdentifiedCoinData {
uint64_t i; // diversifier
std::vector<unsigned char> d; // encrypted diversifier
uint64_t a; // asset type
uint64_t iota; // identifier
Scalar a; // asset type
Scalar iota; // identifier
uint64_t v; // value
Scalar k; // nonce
std::string memo; // memo
Expand Down Expand Up @@ -54,8 +54,8 @@ struct SpendCoinRecipientData {
uint64_t v; // value
std::vector<unsigned char> d; // encrypted diversifier
Scalar k; // nonce
uint64_t a; // asset type
uint64_t iota; // identifier
Scalar a; // asset type
Scalar iota; // identifier
std::string memo; // memo

ADD_SERIALIZE_METHODS;
Expand All @@ -81,8 +81,8 @@ class Coin
const Params* params,
const char type,
const Scalar& k,
const uint64_t& a,
const uint64_t& iota,
const Scalar& a,
const Scalar& iota,
const Address& address,
const uint64_t& v,
const std::string& memo,
Expand Down Expand Up @@ -114,8 +114,7 @@ class Coin
GroupElement S, K, C; // serial commitment, recovery key, value commitment
AEADEncryptedData r_; // encrypted recipient data
uint64_t v; // value
uint64_t a; // asset type
uint64_t iota; // identifier
Scalar a, iota; // asset type, identifier
std::vector<unsigned char> serial_context; // context to which the serial commitment should be bound (not serialized, but inferred)

// Serialization depends on the coin type
Expand Down
8 changes: 4 additions & 4 deletions src/libspats/mint_transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ MintTransaction::MintTransaction(
if (generate) {
MintedCoinData output = outputs[j];

if (output.iota != 0 && output.v != 1) {
if (Scalar(output.iota) != Scalar(uint64_t(0)) && output.v != 1) {
throw std::invalid_argument("mint: identifier not equal to 0 and value not equal to 1");
}
if (output.a == 0 && output.iota != 0) {
if (Scalar(output.a) == Scalar(uint64_t(0)) && Scalar(output.iota) != Scalar(uint64_t(0))) {
throw std::invalid_argument("mint: asset type equal to 0 and identifier not equal to 0");
}

Expand All @@ -49,7 +49,7 @@ MintTransaction::MintTransaction(
serial_context));

// Prepare the value proof
value_statement.emplace_back(this->coins[j].C + this->params->get_E().inverse() * Scalar(this->coins[j].a) + this->params->get_F().inverse() * Scalar(this->coins[j].iota) + this->params->get_G().inverse() * Scalar(this->coins[j].v));
value_statement.emplace_back(this->coins[j].C + this->params->get_E().inverse() * this->coins[j].a + this->params->get_F().inverse() * this->coins[j].iota + this->params->get_G().inverse() * Scalar(this->coins[j].v));

value_witness.emplace_back(SpatsUtils::hash_val(k));
} else {
Expand Down Expand Up @@ -77,7 +77,7 @@ bool MintTransaction::verify()
std::vector<GroupElement> value_statement;

for (std::size_t j = 0; j < this->coins.size(); j++) {
value_statement.emplace_back(this->coins[j].C + this->params->get_E().inverse() * Scalar(this->coins[j].a) + this->params->get_F().inverse() * Scalar(this->coins[j].iota) + this->params->get_G().inverse() * Scalar(this->coins[j].v));
value_statement.emplace_back(this->coins[j].C + this->params->get_E().inverse() * this->coins[j].a + this->params->get_F().inverse() * this->coins[j].iota + this->params->get_G().inverse() * Scalar(this->coins[j].v));
}

return schnorr.verify(value_statement, this->value_proof);
Expand Down
39 changes: 20 additions & 19 deletions src/libspats/mint_transaction.h
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
#ifndef FIRO_SPATS_MINT_TRANSACTION_H
#define FIRO_SPATS_MINT_TRANSACTION_H
#include "keys.h"
#include "coin.h"
#include "keys.h"
#include "schnorr.h"
#include "util.h"

namespace spats {
namespace spats
{

using namespace secp_primitives;

struct MintedCoinData {
Address address;
uint64_t v;
uint64_t a;
uint64_t iota;
std::string memo;
Address address;
uint64_t v;
Scalar a;
Scalar iota;
std::string memo;
};

class MintTransaction {
class MintTransaction
{
public:
MintTransaction(const Params* params);
MintTransaction(
const Params* params,
const std::vector<MintedCoinData>& outputs,
const std::vector<unsigned char>& serial_context,
bool generate = true
);
bool verify();
MintTransaction(
const Params* params,
const std::vector<MintedCoinData>& outputs,
const std::vector<unsigned char>& serial_context,
bool generate = true);
bool verify();

// returns the vector of serialized coins, with first one it puts also the chnorr proof;
std::vector<CDataStream> getMintedCoinsSerialized();
Expand All @@ -37,11 +38,11 @@ class MintTransaction {
void getCoins(std::vector<Coin>& coins_);

private:
const Params* params;
std::vector<Coin> coins;
SchnorrProof value_proof;
const Params* params;
std::vector<Coin> coins;
SchnorrProof value_proof;
};

}
} // namespace spats

#endif
2 changes: 0 additions & 2 deletions src/libspats/params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,6 @@ Params::Params(
this->G_range.resize(64*max_M_range);
this->H_range.resize(64*max_M_range);
for (std::size_t i = 0; i < 64*max_M_range; i++) {
this->E_range[i] = SpatsUtils::hash_generator(LABEL_GENERATOR_E_RANGE + " " + std::to_string(i));
this->F_range[i] = SpatsUtils::hash_generator(LABEL_GENERATOR_F_RANGE + " " + std::to_string(i));
this->G_range[i] = SpatsUtils::hash_generator(LABEL_GENERATOR_G_RANGE + " " + std::to_string(i));
this->H_range[i] = SpatsUtils::hash_generator(LABEL_GENERATOR_H_RANGE + " " + std::to_string(i));
}
Expand Down
8 changes: 8 additions & 0 deletions src/libspats/schnorr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ void Schnorr::prove(const std::vector<Scalar>& y, const std::vector<GroupElement

proof.t = r;
for (std::size_t i = 0; i < n; i++) {
// c_power must be nonzero
if (c_power.isZero()) {
throw std::invalid_argument("Unexpected challenge!");
}
proof.t += y[i].negate() * c_power;
c_power *= c;
}
Expand Down Expand Up @@ -79,6 +83,10 @@ bool Schnorr::verify(const std::vector<GroupElement>& Y, const SchnorrProof& pro
const Scalar c = challenge(Y, proof.A);
Scalar c_power(c);
for (std::size_t i = 0; i < n; i++) {
// c_power must be nonzero
if (c_power.isZero()) {
throw std::invalid_argument("Unexpected challenge!");
}
points.emplace_back(Y[i]);
scalars.emplace_back(c_power);
c_power *= c;
Expand Down
Loading

0 comments on commit d6f6c0e

Please sign in to comment.