Skip to content

Commit

Permalink
Asset::Proof: implicitly including Beam past HF6
Browse files Browse the repository at this point in the history
  • Loading branch information
valdok committed Dec 27, 2023
1 parent bf802eb commit 74a9f7c
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 52 deletions.
124 changes: 91 additions & 33 deletions core/block_crypt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3395,26 +3395,46 @@ namespace beam
return pid == m_Owner;
}

const ECC::Point::Compact& Asset::Proof::get_H()
const ECC::Point::Compact& Asset::Base::get_H()
{
return ECC::Context::get().m_Ipp.H_.m_Fast.m_pPt[0];
}

bool Asset::Proof::CmList::get_At(ECC::Point::Storage& pt_s, uint32_t iIdx)
void Asset::Base::get_GeneratorSafe(ECC::Point::Storage& pt_s) const
{
Asset::ID id = m_Begin + iIdx;
if (id)
Base(id).get_Generator(pt_s);
if (m_ID)
get_Generator(pt_s);
else
{
secp256k1_ge ge;
get_H().Assign(ge);
pt_s.FromNnz(ge);
}

return true;
}

struct Asset::Proof::CmList
:public Sigma::CmList
{
Asset::ID m_Aid0;
bool m_IsPastHF6;

CmList(const Rules& r, Height hScheme)
{
m_IsPastHF6 = (hScheme >= r.pForks[6].m_Height);
}

bool get_At(ECC::Point::Storage& pt_s, uint32_t iIdx) override
{
Asset::ID aid = (m_IsPastHF6 && !iIdx) ? 0 : (m_Aid0 + iIdx);
Base(aid).get_GeneratorSafe(pt_s);
return true;
}

void SelectWindow(Asset::ID, Asset::ID aidMax, const Rules&, const ECC::Scalar::Native& skGen);

static Asset::ID SelectWindowInternal(Asset::ID aid, Asset::ID aidMax, uint32_t N, uint32_t rnd);
};

void Asset::Proof::Create(Height hScheme, ECC::Point::Native& genBlinded, ECC::Scalar::Native& skInOut, Amount val, Asset::ID aid, const ECC::Hash::Value* phvSeed)
{
ECC::Point::Native gen;
Expand Down Expand Up @@ -3455,18 +3475,19 @@ namespace beam
if (aid)
genBlinded = gen;
else
get_H().Assign(genBlinded, true); // not always specified explicitly for aid==0
Base::get_H().Assign(genBlinded, true); // not always specified explicitly for aid==0

genBlinded += ECC::Context::get().G * skGen;
m_hGen = genBlinded;

uint32_t nPos = SetBegin(aid, skGen);
const Rules& r = Rules::get();
CmList lst(r, hScheme);

CmList lst;
lst.m_Begin = m_Begin;
lst.SelectWindow(aid, 0, r, skGen);
m_Begin = lst.m_Aid0;

Sigma::Prover prover(lst, Rules::get().CA.m_ProofCfg, *this);
prover.m_Witness.m_L = nPos;
Sigma::Prover prover(lst, r.CA.m_ProofCfg, *this);
prover.m_Witness.m_L = aid ? (aid - lst.m_Aid0) : 0; // should be correct, with both schemes
prover.m_Witness.m_R = -skGen;

ECC::Hash::Value hvSeed;
Expand All @@ -3488,32 +3509,68 @@ namespace beam
skInOut += k;
}

uint32_t Asset::Proof::SetBegin(Asset::ID aid, const ECC::Scalar::Native& skGen)
void Asset::Proof::CmList::SelectWindow(Asset::ID aid, Asset::ID aidMax, const Rules& r, const ECC::Scalar::Native& skGen)
{
// Randomize m_Begin
const Rules& r = Rules::get();
// Randomize m_Aid0
m_Aid0 = 0;

uint32_t N = r.CA.m_ProofCfg.get_N();
assert(N);
if (N <= 1)
return; // should not happen

if (aid > N / 2)
{
ECC::Hash::Value hv;
ECC::Hash::Processor() << skGen >> hv;
if (aidMax < aid)
aidMax = aid + N / 2; // guess

uint32_t nPos;
hv.ExportWord<0>(nPos);
nPos %= N; // the position of this element in the list
if (aidMax < N)
return;

if (aid > nPos)
ECC::Hash::Value hv;
ECC::Hash::Processor() << skGen >> hv; // pseudo-random

uint32_t nPos;
hv.ExportWord<0>(nPos);

if (m_IsPastHF6)
{
if (!aid)
{
// TODO: don't exceed the max current asset count, for this we must query it
m_Begin = aid - nPos;
return nPos;
// choose a pseudo-random aid within [1, aidMax]
hv.ExportWord<1>(aid);
aid = 1u + (aid % aidMax);
}

nPos = 1u + (nPos % (N - 1)); // our element position within [1, N)

}
else
nPos %= N; // our element position within [0, N)


if (aid + (N - 1) - nPos > aidMax)
m_Aid0 = aidMax - (N - 1); // last element of window shouldn't exceed aidMax
else
{
if (aid > nPos)
m_Aid0 = aid - nPos;
}
}

Asset::ID Asset::Proof::CmList::SelectWindowInternal(Asset::ID aid, Asset::ID aidMax, uint32_t N, uint32_t rnd)
{
assert(aid <= aidMax);
assert(N);
assert(aidMax > (N - 1));

m_Begin = 0;
return aid;
rnd %= N; // index of our element within the window

if (aid < rnd)
return 0;

Asset::ID ret = aid - rnd;
if (ret + (N - 1) <= aidMax)
return ret;

return aidMax - (N - 1);
}

bool Asset::Proof::IsValidPrepare(ECC::Point::Native& hGen, ECC::InnerProduct::BatchContext& bc, ECC::Scalar::Native* pKs) const
Expand Down Expand Up @@ -3542,16 +3599,17 @@ namespace beam
ECC::InnerProduct::BatchContextEx<1> bc;
std::vector<ECC::Scalar::Native> vKs;

const Sigma::Cfg& cfg = Rules::get().CA.m_ProofCfg;
const Rules& r = Rules::get();
const Sigma::Cfg& cfg = r.CA.m_ProofCfg;
uint32_t N = cfg.get_N();
assert(N);
vKs.resize(N);

if (!IsValidPrepare(hGen, bc, &vKs.front()))
return false;

CmList lst;
lst.m_Begin = m_Begin;
CmList lst(r, hScheme);
lst.m_Aid0 = m_Begin;

lst.Calculate(bc.m_Sum, 0, N, &vKs.front());

Expand Down
13 changes: 4 additions & 9 deletions core/block_crypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ namespace beam
void get_Generator(ECC::Point::Native&) const;
void get_Generator(ECC::Point::Storage&) const;
void get_Generator(ECC::Point::Native&, ECC::Point::Storage&) const;

void get_GeneratorSafe(ECC::Point::Storage&) const; // works for aid=0
static const ECC::Point::Compact& get_H();
};

struct Metadata
Expand Down Expand Up @@ -251,13 +254,6 @@ namespace beam

static void Expose(ECC::Oracle&, Height hScheme, const Ptr&);

struct CmList
:public Sigma::CmList
{
Asset::ID m_Begin;
virtual bool get_At(ECC::Point::Storage&, uint32_t iIdx) override;
};

void Clone(Ptr&) const;

struct BatchContext
Expand All @@ -281,8 +277,7 @@ namespace beam
};

private:
uint32_t SetBegin(Asset::ID, const ECC::Scalar::Native& skGen);
static const ECC::Point::Compact& get_H();
struct CmList;
};
};

Expand Down
19 changes: 14 additions & 5 deletions core/unittest/ecc_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2189,15 +2189,14 @@ void TestLelantusKeys()
}
}

void TestAssetProof()
void TestAssetProof2()
{
Scalar::Native sk;
SetRandom(sk);

Amount val = 400;

Point::Native genBlinded;

beam::Asset::Proof proof;
proof.Create(g_hFork, genBlinded, sk, val, 100500);
verify_test(proof.IsValid(g_hFork, genBlinded));
Expand All @@ -2209,6 +2208,17 @@ void TestAssetProof()
verify_test(proof.IsValid(g_hFork, genBlinded));
}

void TestAssetProof()
{
// before HF6
beam::Rules::get().pForks[6].m_Height = beam::MaxHeight;
TestAssetProof2();

// after HF6
beam::Rules::get().pForks[6].m_Height = g_hFork;
TestAssetProof2();
}

void TestAssetEmission()
{
const beam::Height hScheme = g_hFork;
Expand Down Expand Up @@ -3115,9 +3125,8 @@ int main()
ECC::PseudoRandomGenerator::Scope scopePrg(&prg);

beam::Rules::get().CA.Enabled = true;
beam::Rules::get().pForks[1].m_Height = g_hFork;
beam::Rules::get().pForks[2].m_Height = g_hFork;
beam::Rules::get().pForks[3].m_Height = g_hFork;
for (uint32_t i = 0; i < _countof(beam::Rules::get().pForks); i++)
beam::Rules::get().pForks[i].m_Height = g_hFork;
ECC::TestAll();
ECC::RunBenchmark();

Expand Down
29 changes: 24 additions & 5 deletions node/processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1226,7 +1226,17 @@ struct NodeProcessor::MultiAssetContext

private:

Asset::Proof::CmList m_Lst;
struct List
:public Sigma::CmList
{
Asset::ID m_Begin;
bool get_At(ECC::Point::Storage& pt_s, uint32_t iIdx) override
{
Asset::Base(m_Begin + iIdx).get_GeneratorSafe(pt_s);
return true;
}

} m_Lst;

virtual Sigma::CmList& get_List() override
{
Expand All @@ -1247,17 +1257,26 @@ bool NodeProcessor::MultiAssetContext::BatchCtx::IsValid(Height hScheme, ECC::Po
assert(ECC::InnerProduct::BatchContext::s_pInstance);
ECC::InnerProduct::BatchContext& bc = *ECC::InnerProduct::BatchContext::s_pInstance;

const Sigma::Cfg& cfg = Rules::get().CA.m_ProofCfg;
const Rules& r = Rules::get();
const Sigma::Cfg& cfg = r.CA.m_ProofCfg;
uint32_t N = cfg.get_N();
assert(N);
if (!N)
return false; // ?!

m_vKs.resize(N); // will allocate if empty
memset0(&m_vKs.front(), sizeof(ECC::Scalar::Native) * N);

if (!p.IsValid(hGen, bc, &m_vKs.front()))
if (!p.IsValidPrepare(hGen, bc, &m_vKs.front()))
return false;

m_Ctx.Add(p.m_Begin, N, &m_vKs.front());
if (hScheme >= r.pForks[6].m_Height)
{
m_Ctx.Add(0, 1, &m_vKs.front());
m_Ctx.Add(p.m_Begin + 1u, N - 1, &m_vKs.front());
}
else
m_Ctx.Add(p.m_Begin, N, &m_vKs.front());

return true;
}

Expand Down

0 comments on commit 74a9f7c

Please sign in to comment.