From 1adc1b0f8ddc3a8034599be188390a7327d4f4a4 Mon Sep 17 00:00:00 2001 From: Some Random Crypto Guy Date: Thu, 29 May 2025 19:07:12 +0100 Subject: [PATCH] added full set of CLSAG tests for T-CLSAG --- src/ringct/rctSigs.cpp | 2 +- src/ringct/rctSigs.h | 2 +- tests/unit_tests/ringct.cpp | 147 +++++++++++++++++++++++++++++++++++- 3 files changed, 147 insertions(+), 4 deletions(-) diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index 0b264fb..e1eee41 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -977,7 +977,7 @@ namespace rct { return result; } - clsagCarrot proveRctCLSAGSSimpleCarrot(const key &message, const ctkeyV &pubs, const key &x, const key &y, const key &mask, const key &a, const key &Cout, unsigned int index, hw::device &hwdev) { + clsagCarrot proveRctCLSAGSimpleCarrot(const key &message, const ctkeyV &pubs, const key &x, const key &y, const key &mask, const key &a, const key &Cout, unsigned int index, hw::device &hwdev) { //setup vars size_t rows = 1; size_t cols = pubs.size(); diff --git a/src/ringct/rctSigs.h b/src/ringct/rctSigs.h index c3d6186..f755ce0 100644 --- a/src/ringct/rctSigs.h +++ b/src/ringct/rctSigs.h @@ -86,7 +86,7 @@ namespace rct { bool verRctCLSAGSimple(const key &, const clsag &, const ctkeyV &, const key &); clsagCarrot CLSAG_Gen_Carrot(const key &message, const keyV & P, const key & x, const key & y, const keyV & C, const key & z, const keyV & C_nonzero, const key & C_offset, const unsigned int l, hw::device &hwdev); - clsagCarrot proveRctCLSAGSSimpleCarrot(const key &message, const ctkeyV &pubs, const key &x, const key &y, const key &mask, const key &a, const key &Cout, unsigned int index, hw::device &hwdev); + clsagCarrot proveRctCLSAGSimpleCarrot(const key &message, const ctkeyV &pubs, const key &x, const key &y, const key &mask, const key &a, const key &Cout, unsigned int index, hw::device &hwdev); bool verRctCLSAGSimpleCarrot(const key &message, const clsagCarrot &sig, const ctkeyV & pubs, const key & C_offset); zk_proof PRProof_Gen(const rct::key &difference); diff --git a/tests/unit_tests/ringct.cpp b/tests/unit_tests/ringct.cpp index 01daf51..96b8524 100644 --- a/tests/unit_tests/ringct.cpp +++ b/tests/unit_tests/ringct.cpp @@ -309,6 +309,7 @@ TEST(ringct, CLSAG_CARROT) const key message = identity(); ctkey backup; clsagCarrot clsag; + key backup_key; for (size_t i = 0; i < N; ++i) { @@ -336,9 +337,151 @@ TEST(ringct, CLSAG_CARROT) t2 = skGen(); addKeys2(Cout,t2,u,H); + // bad message + clsag = rct::proveRctCLSAGSimpleCarrot(zero(), pubs, x, y, t, t2, Cout, idx, hw::get_device("default")); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + + // bad index at creation + try + { + clsag = rct::proveRctCLSAGSimpleCarrot(message, pubs, x, y, t, t2, Cout, (idx + 1) % N, hw::get_device("default")); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + } + catch (...) { /* either exception, or failure to verify above */ } + + // bad C at creation + backup = pubs[idx]; + pubs[idx].mask = scalarmultBase(skGen()); + try + { + clsag = rct::proveRctCLSAGSimpleCarrot(message, pubs, x, y, t, t2, Cout, idx, hw::get_device("default")); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + } + catch (...) { /* either exception, or failure to verify above */ } + pubs[idx] = backup; + + // bad x at creation + backup_key = x; + skGen(x); + try + { + clsag = rct::proveRctCLSAGSimpleCarrot(message, pubs, x, y, t, t2, Cout, idx, hw::get_device("default")); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + } + catch (...) { /* either exception, or failure to verify above */ } + x = backup_key; + + // bad y at creation + backup_key = y; + skGen(y); + try + { + clsag = rct::proveRctCLSAGSimpleCarrot(message, pubs, x, y, t, t2, Cout, idx, hw::get_device("default")); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + } + catch (...) { /* either exception, or failure to verify above */ } + y = backup_key; + + // bad P at creation + backup = pubs[idx]; + pubs[idx].dest = scalarmultBase(skGen()); + try + { + clsag = rct::proveRctCLSAGSimpleCarrot(message, pubs, x, y, t, t2, Cout, idx, hw::get_device("default")); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + } + catch (...) { /* either exception, or failure to verify above */ } + pubs[idx] = backup; + // generate the signature - clsag = rct::proveRctCLSAGSSimpleCarrot(message, pubs, x, y, t, t2, Cout, idx, hw::get_device("default")); - ASSERT_TRUE(rct::verRctCLSAGSimpleCarrot(message, clsag, pubs, Cout)); + clsag = rct::proveRctCLSAGSimpleCarrot(message, pubs, x, y, t, t2, Cout, idx, hw::get_device("default")); + ASSERT_TRUE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + + // empty sx + auto sbackup = clsag.sx; + clsag.sx.clear(); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + clsag.sx = sbackup; + + // too few sx elements + backup_key = clsag.sx.back(); + clsag.sx.pop_back(); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + clsag.sx.push_back(backup_key); + + // too many sx elements + clsag.sx.push_back(skGen()); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + clsag.sx.pop_back(); + + // bad sx in clsag at verification + for (auto &sx: clsag.sx) + { + backup_key = sx; + sx = skGen(); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + sx = backup_key; + } + + // empty sy + sbackup = clsag.sy; + clsag.sy.clear(); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + clsag.sy = sbackup; + + // too few sy elements + backup_key = clsag.sy.back(); + clsag.sy.pop_back(); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + clsag.sy.push_back(backup_key); + + // too many sy elements + clsag.sy.push_back(skGen()); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + clsag.sy.pop_back(); + + // bad sy in clsag at verification + for (auto &sy: clsag.sy) + { + backup_key = sy; + sy = skGen(); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + sy = backup_key; + } + + // bad c1 in clsag at verification + backup_key = clsag.c1; + clsag.c1 = skGen(); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + clsag.c1 = backup_key; + + // bad I in clsag at verification + backup_key = clsag.I; + clsag.I = scalarmultBase(skGen()); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + clsag.I = backup_key; + + // bad D in clsag at verification + backup_key = clsag.D; + clsag.D = scalarmultBase(skGen()); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + clsag.D = backup_key; + + // D not in main subgroup in clsag at verification + backup_key = clsag.D; + rct::key foo; + ASSERT_TRUE(epee::string_tools::hex_to_pod("c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa", foo)); + clsag.D = rct::addKeys(clsag.D, foo); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + clsag.D = backup_key; + + // swapped I and D in clsag at verification + std::swap(clsag.I, clsag.D); + ASSERT_FALSE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); + std::swap(clsag.I, clsag.D); + + // check it's still good, in case we failed to restore + ASSERT_TRUE(rct::verRctCLSAGSimpleCarrot(message,clsag,pubs,Cout)); } TEST(ringct, range_proofs)