aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ringct/rctSigs.cpp264
-rw-r--r--src/ringct/rctSigs.h7
-rw-r--r--tests/performance_tests/main.cpp2
-rw-r--r--tests/unit_tests/ringct.cpp166
4 files changed, 221 insertions, 218 deletions
diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp
index 074812156..2e56dad58 100644
--- a/src/ringct/rctSigs.cpp
+++ b/src/ringct/rctSigs.cpp
@@ -168,12 +168,17 @@ namespace rct {
// Generate a CLSAG signature
// See paper by Goodell et al. (https://eprint.iacr.org/2019/654)
- clsag CLSAG_Gen(const key &message, const keyV & P, const key & p, const keyV & C, const key & z, const unsigned int l, const multisig_kLRki *kLRki, key *mscout, key *mspout) {
+ //
+ // The keys are set as follows:
+ // P[l] == p*G
+ // C[l] == z*G
+ // C[i] == C_nonzero[i] - C_offset (for hashing purposes) for all i
+ clsag CLSAG_Gen(const key &message, const keyV & P, const key & p, const keyV & C, const key & z, const keyV & C_nonzero, const key & C_offset, const unsigned int l, const multisig_kLRki *kLRki, key *mscout, key *mspout) {
clsag sig;
size_t n = P.size(); // ring size
CHECK_AND_ASSERT_THROW_MES(n == C.size(), "Signing and commitment key vector sizes must match!");
+ CHECK_AND_ASSERT_THROW_MES(n == C_nonzero.size(), "Signing and commitment key vector sizes must match!");
CHECK_AND_ASSERT_THROW_MES(l < n, "Signing index out of range!");
- CHECK_AND_ASSERT_THROW_MES(scalarmultBase(z) == C[l], "C does not match z!");
CHECK_AND_ASSERT_THROW_MES((kLRki && mscout) || (!kLRki && !mscout), "Only one of kLRki/mscout is present");
CHECK_AND_ASSERT_THROW_MES((mscout && mspout) || !kLRki, "Multisig pointers are not all present");
@@ -212,8 +217,8 @@ namespace rct {
scalarmultKey(aH,H,a);
// Aggregation hashes
- keyV mu_P_to_hash(2*n+3); // domain, I, D, P, C
- keyV mu_C_to_hash(2*n+3); // domain, I, D, P, C
+ keyV mu_P_to_hash(2*n+4); // domain, I, D, P, C, C_offset
+ keyV mu_C_to_hash(2*n+4); // domain, I, D, P, C, C_offset
sc_0(mu_P_to_hash[0].bytes);
memcpy(mu_P_to_hash[0].bytes,config::HASH_KEY_CLSAG_AGG_0,sizeof(config::HASH_KEY_CLSAG_AGG_0)-1);
sc_0(mu_C_to_hash[0].bytes);
@@ -223,40 +228,43 @@ namespace rct {
mu_C_to_hash[i] = P[i-1];
}
for (size_t i = n+1; i < 2*n+1; ++i) {
- mu_P_to_hash[i] = C[i-n-1];
- mu_C_to_hash[i] = C[i-n-1];
+ mu_P_to_hash[i] = C_nonzero[i-n-1];
+ mu_C_to_hash[i] = C_nonzero[i-n-1];
}
mu_P_to_hash[2*n+1] = sig.I;
mu_P_to_hash[2*n+2] = sig.D;
+ mu_P_to_hash[2*n+3] = C_offset;
mu_C_to_hash[2*n+1] = sig.I;
mu_C_to_hash[2*n+2] = sig.D;
+ mu_C_to_hash[2*n+3] = C_offset;
key mu_P, mu_C;
mu_P = hash_to_scalar(mu_P_to_hash);
mu_C = hash_to_scalar(mu_C_to_hash);
// Initial commitment
- keyV c_to_hash(2*n+4); // domain, P, C, message, aG, aH
+ keyV c_to_hash(2*n+5); // domain, P, C, C_offset, message, aG, aH
key c;
sc_0(c_to_hash[0].bytes);
memcpy(c_to_hash[0].bytes,config::HASH_KEY_CLSAG_ROUND,sizeof(config::HASH_KEY_CLSAG_ROUND)-1);
for (size_t i = 1; i < n+1; ++i)
{
c_to_hash[i] = P[i-1];
- c_to_hash[i+n] = C[i-1];
+ c_to_hash[i+n] = C_nonzero[i-1];
}
- c_to_hash[2*n+1] = message;
+ c_to_hash[2*n+1] = C_offset;
+ c_to_hash[2*n+2] = message;
// Multisig data is present
if (kLRki)
{
a = kLRki->k;
- c_to_hash[2*n+2] = kLRki->L;
- c_to_hash[2*n+3] = kLRki->R;
+ c_to_hash[2*n+3] = kLRki->L;
+ c_to_hash[2*n+4] = kLRki->R;
}
else
{
- c_to_hash[2*n+2] = aG;
- c_to_hash[2*n+3] = aH;
+ c_to_hash[2*n+3] = aG;
+ c_to_hash[2*n+4] = aH;
}
c = hash_to_scalar(c_to_hash);
@@ -295,8 +303,8 @@ namespace rct {
ge_dsm_precomp(H_precomp.k, &Hi_p3);
addKeys_aAbBcC(R,sig.s[i],H_precomp.k,c_p,I_precomp.k,c_c,D_precomp.k);
- c_to_hash[2*n+2] = L;
- c_to_hash[2*n+3] = R;
+ c_to_hash[2*n+3] = L;
+ c_to_hash[2*n+4] = R;
c_new = hash_to_scalar(c_to_hash);
copy(c,c_new);
@@ -320,99 +328,8 @@ namespace rct {
return sig;
}
- clsag CLSAG_Gen(const key &message, const keyV & P, const key & p, const keyV & C, const key & z, const unsigned int l) {
- return CLSAG_Gen(message, P, p, C, z, l, NULL, NULL, NULL);
- }
-
- // Verify a CLSAG signature
- // See paper by Goodell et al. (https://eprint.iacr.org/2019/654)
- bool CLSAG_Ver(const key &message, const keyV & P, const keyV & C, const clsag & sig)
- {
- size_t n = P.size(); // ring size
- CHECK_AND_ASSERT_MES(n == C.size(), false, "Signing and commitment key vector sizes must match!");
- CHECK_AND_ASSERT_MES(n == sig.s.size(), false, "Signature scalar vector is the wrong size!");
- for (size_t i = 0; i < n; ++i)
- CHECK_AND_ASSERT_MES(sc_check(sig.s[i].bytes) == 0, false, "Bad signature scalar!");
- CHECK_AND_ASSERT_MES(sc_check(sig.c1.bytes) == 0, false, "Bad signature commitment!");
-
- key c = copy(sig.c1);
- key D_8 = scalarmult8(sig.D);
- geDsmp I_precomp;
- geDsmp D_precomp;
- precomp(I_precomp.k,sig.I);
- precomp(D_precomp.k,D_8);
-
- // Aggregation hashes
- keyV mu_P_to_hash(2*n+3); // domain, I, D, P, C
- keyV mu_C_to_hash(2*n+3); // domain, I, D, P, C
- sc_0(mu_P_to_hash[0].bytes);
- memcpy(mu_P_to_hash[0].bytes,config::HASH_KEY_CLSAG_AGG_0,sizeof(config::HASH_KEY_CLSAG_AGG_0)-1);
- sc_0(mu_C_to_hash[0].bytes);
- memcpy(mu_C_to_hash[0].bytes,config::HASH_KEY_CLSAG_AGG_1,sizeof(config::HASH_KEY_CLSAG_AGG_1)-1);
- for (size_t i = 1; i < n+1; ++i) {
- mu_P_to_hash[i] = P[i-1];
- mu_C_to_hash[i] = P[i-1];
- }
- for (size_t i = n+1; i < 2*n+1; ++i) {
- mu_P_to_hash[i] = C[i-n-1];
- mu_C_to_hash[i] = C[i-n-1];
- }
- mu_P_to_hash[2*n+1] = sig.I;
- mu_P_to_hash[2*n+2] = sig.D;
- mu_C_to_hash[2*n+1] = sig.I;
- mu_C_to_hash[2*n+2] = sig.D;
- key mu_P, mu_C;
- mu_P = hash_to_scalar(mu_P_to_hash);
- mu_C = hash_to_scalar(mu_C_to_hash);
-
- keyV c_to_hash(2*n+4); // domain, P, C, message, L, R
- sc_0(c_to_hash[0].bytes);
- memcpy(c_to_hash[0].bytes,config::HASH_KEY_CLSAG_ROUND,sizeof(config::HASH_KEY_CLSAG_ROUND)-1);
- for (size_t i = 1; i < n+1; ++i)
- {
- c_to_hash[i] = P[i-1];
- c_to_hash[i+n] = C[i-1];
- }
- c_to_hash[2*n+1] = message;
- key c_p; // = c[i]*mu_P
- key c_c; // = c[i]*mu_C
- key c_new;
- key L;
- key R;
- geDsmp P_precomp;
- geDsmp C_precomp;
- geDsmp H_precomp;
- size_t i = 0;
- ge_p3 hash8_p3;
- geDsmp hash_precomp;
-
- while (i < n) {
- sc_0(c_new.bytes);
- sc_mul(c_p.bytes,mu_P.bytes,c.bytes);
- sc_mul(c_c.bytes,mu_C.bytes,c.bytes);
-
- // Precompute points
- precomp(P_precomp.k,P[i]);
- precomp(C_precomp.k,C[i]);
-
- // Compute L
- addKeys_aGbBcC(L,sig.s[i],c_p,P_precomp.k,c_c,C_precomp.k);
-
- // Compute R
- hash_to_p3(hash8_p3,P[i]);
- ge_dsm_precomp(hash_precomp.k, &hash8_p3);
- addKeys_aAbBcC(R,sig.s[i],hash_precomp.k,c_p,I_precomp.k,c_c,D_precomp.k);
-
- c_to_hash[2*n+2] = L;
- c_to_hash[2*n+3] = R;
- c_new = hash_to_scalar(c_to_hash);
- CHECK_AND_ASSERT_MES(!(c_new == rct::zero()), false, "Bad signature hash");
- copy(c,c_new);
-
- i = i + 1;
- }
- sc_sub(c_new.bytes,c.bytes,sig.c1.bytes);
- return sc_isnonzero(c_new.bytes) == 0;
+ clsag CLSAG_Gen(const key &message, const keyV & P, const key & p, const keyV & C, const key & z, const keyV & C_nonzero, const key & C_offset, const unsigned int l) {
+ return CLSAG_Gen(message, P, p, C, z, C_nonzero, C_offset, l, NULL, NULL, NULL);
}
// MLSAG signatures
@@ -816,12 +733,14 @@ namespace rct {
size_t i;
keyM M(cols, tmp);
- keyV P, C;
+ keyV P, C, C_nonzero;
P.reserve(pubs.size());
C.reserve(pubs.size());
+ C_nonzero.reserve(pubs.size());
for (const ctkey &k: pubs)
{
P.push_back(k.dest);
+ C_nonzero.push_back(k.mask);
rct::key tmp;
subKeys(tmp, k.mask, Cout);
C.push_back(tmp);
@@ -829,7 +748,7 @@ namespace rct {
sk[0] = copy(inSk.dest);
sc_sub(sk[1].bytes, inSk.mask.bytes, a.bytes);
- clsag result = CLSAG_Gen(message, P, sk[0], C, sk[1], index, kLRki, mscout, mspout);
+ clsag result = CLSAG_Gen(message, P, sk[0], C, sk[1], C_nonzero, Cout, index, kLRki, mscout, mspout);
memwipe(sk.data(), sk.size() * sizeof(key));
return result;
}
@@ -913,29 +832,116 @@ namespace rct {
catch (...) { return false; }
}
- bool verRctCLSAGSimple(const key &message, const clsag &clsag, const ctkeyV & pubs, const key & C) {
+ bool verRctCLSAGSimple(const key &message, const clsag &sig, const ctkeyV & pubs, const key & C_offset) {
try
{
PERF_TIMER(verRctCLSAGSimple);
- //setup vars
- const size_t cols = pubs.size();
- CHECK_AND_ASSERT_MES(cols >= 1, false, "Empty pubs");
- keyV Pi(cols), Ci(cols);
- ge_p3 Cp3;
- CHECK_AND_ASSERT_MES_L1(ge_frombytes_vartime(&Cp3, C.bytes) == 0, false, "point conv failed");
- ge_cached Ccached;
- ge_p3_to_cached(&Ccached, &Cp3);
- ge_p1p1 p1;
- //create the matrix to mg sig
- for (size_t i = 0; i < cols; i++) {
- Pi[i] = pubs[i].dest;
- ge_p3 p3;
- CHECK_AND_ASSERT_MES_L1(ge_frombytes_vartime(&p3, pubs[i].mask.bytes) == 0, false, "point conv failed");
- ge_sub(&p1, &p3, &Ccached);
- ge_p1p1_to_p3(&p3, &p1);
- ge_p3_tobytes(Ci[i].bytes, &p3);
+ const size_t n = pubs.size();
+
+ // Check data
+ CHECK_AND_ASSERT_MES(n >= 1, false, "Empty pubs");
+ CHECK_AND_ASSERT_MES(n == sig.s.size(), false, "Signature scalar vector is the wrong size!");
+ for (size_t i = 0; i < n; ++i)
+ CHECK_AND_ASSERT_MES(sc_check(sig.s[i].bytes) == 0, false, "Bad signature scalar!");
+ CHECK_AND_ASSERT_MES(sc_check(sig.c1.bytes) == 0, false, "Bad signature commitment!");
+ CHECK_AND_ASSERT_MES(!(sig.I == rct::identity()), false, "Bad key image!");
+
+ // Cache commitment offset for efficient subtraction later
+ ge_p3 C_offset_p3;
+ CHECK_AND_ASSERT_MES(ge_frombytes_vartime(&C_offset_p3, C_offset.bytes) == 0, false, "point conv failed");
+ ge_cached C_offset_cached;
+ ge_p3_to_cached(&C_offset_cached, &C_offset_p3);
+
+ // Prepare key images
+ key c = copy(sig.c1);
+ key D_8 = scalarmult8(sig.D);
+ CHECK_AND_ASSERT_MES(!(D_8 == rct::identity()), false, "Bad auxiliary key image!");
+ geDsmp I_precomp;
+ geDsmp D_precomp;
+ precomp(I_precomp.k,sig.I);
+ precomp(D_precomp.k,D_8);
+
+ // Aggregation hashes
+ keyV mu_P_to_hash(2*n+4); // domain, I, D, P, C, C_offset
+ keyV mu_C_to_hash(2*n+4); // domain, I, D, P, C, C_offset
+ sc_0(mu_P_to_hash[0].bytes);
+ memcpy(mu_P_to_hash[0].bytes,config::HASH_KEY_CLSAG_AGG_0,sizeof(config::HASH_KEY_CLSAG_AGG_0)-1);
+ sc_0(mu_C_to_hash[0].bytes);
+ memcpy(mu_C_to_hash[0].bytes,config::HASH_KEY_CLSAG_AGG_1,sizeof(config::HASH_KEY_CLSAG_AGG_1)-1);
+ for (size_t i = 1; i < n+1; ++i) {
+ mu_P_to_hash[i] = pubs[i-1].dest;
+ mu_C_to_hash[i] = pubs[i-1].dest;
+ }
+ for (size_t i = n+1; i < 2*n+1; ++i) {
+ mu_P_to_hash[i] = pubs[i-n-1].mask;
+ mu_C_to_hash[i] = pubs[i-n-1].mask;
+ }
+ mu_P_to_hash[2*n+1] = sig.I;
+ mu_P_to_hash[2*n+2] = sig.D;
+ mu_P_to_hash[2*n+3] = C_offset;
+ mu_C_to_hash[2*n+1] = sig.I;
+ mu_C_to_hash[2*n+2] = sig.D;
+ mu_C_to_hash[2*n+3] = C_offset;
+ key mu_P, mu_C;
+ mu_P = hash_to_scalar(mu_P_to_hash);
+ mu_C = hash_to_scalar(mu_C_to_hash);
+
+ // Set up round hash
+ keyV c_to_hash(2*n+5); // domain, P, C, C_offset, message, L, R
+ sc_0(c_to_hash[0].bytes);
+ memcpy(c_to_hash[0].bytes,config::HASH_KEY_CLSAG_ROUND,sizeof(config::HASH_KEY_CLSAG_ROUND)-1);
+ for (size_t i = 1; i < n+1; ++i)
+ {
+ c_to_hash[i] = pubs[i-1].dest;
+ c_to_hash[i+n] = pubs[i-1].mask;
+ }
+ c_to_hash[2*n+1] = C_offset;
+ c_to_hash[2*n+2] = message;
+ key c_p; // = c[i]*mu_P
+ key c_c; // = c[i]*mu_C
+ key c_new;
+ key L;
+ key R;
+ geDsmp P_precomp;
+ geDsmp C_precomp;
+ geDsmp H_precomp;
+ size_t i = 0;
+ ge_p3 hash8_p3;
+ geDsmp hash_precomp;
+ ge_p3 temp_p3;
+ ge_p1p1 temp_p1;
+
+ while (i < n) {
+ sc_0(c_new.bytes);
+ sc_mul(c_p.bytes,mu_P.bytes,c.bytes);
+ sc_mul(c_c.bytes,mu_C.bytes,c.bytes);
+
+ // Precompute points for L/R
+ precomp(P_precomp.k,pubs[i].dest);
+
+ CHECK_AND_ASSERT_MES(ge_frombytes_vartime(&temp_p3, pubs[i].mask.bytes) == 0, false, "point conv failed");
+ ge_sub(&temp_p1,&temp_p3,&C_offset_cached);
+ ge_p1p1_to_p3(&temp_p3,&temp_p1);
+ ge_dsm_precomp(C_precomp.k,&temp_p3);
+
+ // Compute L
+ addKeys_aGbBcC(L,sig.s[i],c_p,P_precomp.k,c_c,C_precomp.k);
+
+ // Compute R
+ hash_to_p3(hash8_p3,pubs[i].dest);
+ ge_dsm_precomp(hash_precomp.k, &hash8_p3);
+ addKeys_aAbBcC(R,sig.s[i],hash_precomp.k,c_p,I_precomp.k,c_c,D_precomp.k);
+
+ c_to_hash[2*n+3] = L;
+ c_to_hash[2*n+4] = R;
+ c_new = hash_to_scalar(c_to_hash);
+ CHECK_AND_ASSERT_MES(!(c_new == rct::zero()), false, "Bad signature hash");
+ copy(c,c_new);
+
+ i = i + 1;
}
- return CLSAG_Ver(message, Pi, Ci, clsag);
+ sc_sub(c_new.bytes,c.bytes,sig.c1.bytes);
+ return sc_isnonzero(c_new.bytes) == 0;
}
catch (...) { return false; }
}
diff --git a/src/ringct/rctSigs.h b/src/ringct/rctSigs.h
index ed82f6bc5..199ad9aef 100644
--- a/src/ringct/rctSigs.h
+++ b/src/ringct/rctSigs.h
@@ -77,9 +77,10 @@ namespace rct {
mgSig MLSAG_Gen(const key &message, const keyM & pk, const keyV & xx, const multisig_kLRki *kLRki, key *mscout, const unsigned int index, size_t dsRows, hw::device &hwdev);
bool MLSAG_Ver(const key &message, const keyM &pk, const mgSig &sig, size_t dsRows);
- clsag CLSAG_Gen(const key &message, const keyV & P, const key & p, const keyV & C, const key & z, const unsigned int l, const multisig_kLRki *kLRki, key *mscout, key *mspout);
- clsag CLSAG_Gen(const key &message, const keyV & P, const key & p, const keyV & C, const key & z, const unsigned int l);
- bool CLSAG_Ver(const key &message, const keyV & P, const keyV & C, const clsag & sig);
+ clsag CLSAG_Gen(const key &message, const keyV & P, const key & p, const keyV & C, const keyV & C_nonzero, const key & C_offset, const key & z, const unsigned int l, const multisig_kLRki *kLRki, key *mscout, key *mspout);
+ clsag CLSAG_Gen(const key &message, const keyV & P, const key & p, const keyV & C, const keyV & C_nonzero, const key & C_offset, const key & z, const unsigned int l);
+ clsag proveRctCLSAGSimple(const key &, const ctkeyV &, const ctkey &, const key &, const key &, const multisig_kLRki *, key *, key *, unsigned int, hw::device &);
+ bool verRctCLSAGSimple(const key &, const clsag &, const ctkeyV &, const key &);
//proveRange and verRange
//proveRange gives C, and mask such that \sumCi = C
diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp
index b0cec464c..fde14b229 100644
--- a/tests/performance_tests/main.cpp
+++ b/tests/performance_tests/main.cpp
@@ -61,7 +61,6 @@
#include "crypto_ops.h"
#include "multiexp.h"
#include "sig_mlsag.h"
-#include "sig_clsag.h"
namespace po = boost::program_options;
@@ -216,7 +215,6 @@ int main(int argc, char** argv)
TEST_PERFORMANCE1(filter, p, test_cn_fast_hash, 16384);
TEST_PERFORMANCE2(filter, p, test_sig_mlsag, 11, true); // MLSAG verification
- TEST_PERFORMANCE3(filter, p, test_sig_clsag, 11, true, 0); // CLSAG verification
TEST_PERFORMANCE2(filter, p, test_ringct_mlsag, 11, false);
TEST_PERFORMANCE2(filter, p, test_ringct_mlsag, 11, true);
diff --git a/tests/unit_tests/ringct.cpp b/tests/unit_tests/ringct.cpp
index 75fe9ecfb..2388d647b 100644
--- a/tests/unit_tests/ringct.cpp
+++ b/tests/unit_tests/ringct.cpp
@@ -140,165 +140,163 @@ TEST(ringct, MG_sigs)
TEST(ringct, CLSAG)
{
- const size_t ring_size = 11;
+ const size_t N = 11;
const size_t idx = 5;
- keyV P, C;
- key p, z;
+ ctkeyV pubs;
+ key p, t, t2, u;
const key message = identity();
- key backup;
+ ctkey backup;
clsag clsag;
- for (size_t i = 0; i < ring_size; ++i)
+ for (size_t i = 0; i < N; ++i)
{
- key Sk, Pk;
- skpkGen(Sk, Pk);
- P.push_back(Pk);
- skpkGen(Sk, Pk);
- C.push_back(Pk);
+ key sk;
+ ctkey tmp;
+
+ skpkGen(sk, tmp.dest);
+ skpkGen(sk, tmp.mask);
+
+ pubs.push_back(tmp);
}
- skpkGen(p, P[idx]);
- skpkGen(z, C[idx]);
- // bad p at creation
- clsag = CLSAG_Gen(zero(), P, p, C, z, idx); //, hw::get_device("default"));
- ASSERT_FALSE(CLSAG_Ver(message, P, C, clsag));
+ // Set P[idx]
+ skpkGen(p, pubs[idx].dest);
+
+ // Set C[idx]
+ t = skGen();
+ u = skGen();
+ addKeys2(pubs[idx].mask,t,u,H);
+
+ // Set commitment offset
+ key Cout;
+ t2 = skGen();
+ addKeys2(Cout,t2,u,H);
+
+ // Prepare generation inputs
+ ctkey insk;
+ insk.dest = p;
+ insk.mask = t;
+
+ // bad message
+ clsag = rct::proveRctCLSAGSimple(zero(),pubs,insk,t2,Cout,NULL,NULL,NULL,idx,hw::get_device("default"));
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
// bad index at creation
try
{
- clsag = CLSAG_Gen(message, P, p, C, z, (idx + 1) % ring_size); //, hw::get_device("default"));
- ASSERT_FALSE(CLSAG_Ver(message, P, C, clsag));
+ clsag = rct::proveRctCLSAGSimple(message,pubs,insk,t2,Cout,NULL,NULL,NULL,(idx + 1) % N,hw::get_device("default"));
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
}
catch (...) { /* either exception, or failure to verify above */ }
// bad z at creation
try
{
- clsag = CLSAG_Gen(message, P, p, C, skGen(), idx); //, hw::get_device("default"));
- ASSERT_FALSE(CLSAG_Ver(message, P, C, clsag));
+ ctkey insk2;
+ insk2.dest = insk.dest;
+ insk2.mask = skGen();
+ clsag = rct::proveRctCLSAGSimple(message,pubs,insk2,t2,Cout,NULL,NULL,NULL,idx,hw::get_device("default"));
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
}
catch (...) { /* either exception, or failure to verify above */ }
// bad C at creation
- backup = C[idx];
- C[idx] = scalarmultBase(skGen());
+ backup = pubs[idx];
+ pubs[idx].mask = scalarmultBase(skGen());
try
{
- clsag = CLSAG_Gen(message, P, p, C, z, idx); //, hw::get_device("default"));
- ASSERT_FALSE(CLSAG_Ver(message, P, C, clsag));
+ clsag = rct::proveRctCLSAGSimple(message,pubs,insk,t2,Cout,NULL,NULL,NULL,idx,hw::get_device("default"));
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
}
catch (...) { /* either exception, or failure to verify above */ }
- C[idx] = backup;
+ pubs[idx] = backup;
// bad p at creation
try
{
- clsag = CLSAG_Gen(message, P, skGen(), C, z, idx); //, hw::get_device("default"));
- ASSERT_FALSE(CLSAG_Ver(message, P, C, clsag));
+ ctkey insk2;
+ insk2.dest = skGen();
+ insk2.mask = insk.mask;
+ clsag = rct::proveRctCLSAGSimple(message,pubs,insk2,t2,Cout,NULL,NULL,NULL,idx,hw::get_device("default"));
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
}
catch (...) { /* either exception, or failure to verify above */ }
// bad P at creation
- backup = P[idx];
- P[idx] = scalarmultBase(skGen());
+ backup = pubs[idx];
+ pubs[idx].dest = scalarmultBase(skGen());
try
{
- clsag = CLSAG_Gen(message, P, p, C, z, idx); //, hw::get_device("default"));
- ASSERT_FALSE(CLSAG_Ver(message, P, C, clsag));
+ clsag = rct::proveRctCLSAGSimple(message,pubs,insk,t2,Cout,NULL,NULL,NULL,idx,hw::get_device("default"));
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
}
catch (...) { /* either exception, or failure to verify above */ }
- P[idx] = backup;
-
- // good
- clsag = CLSAG_Gen(message, P, p, C, z, idx); //, hw::get_device("default"));
- ASSERT_TRUE(CLSAG_Ver(message, P, C, clsag));
-
- // bad message at verification
- ASSERT_FALSE(CLSAG_Ver(zero(), P, C, clsag));
-
- // bad real P at verification
- backup = P[idx];
- P[idx] = scalarmultBase(skGen());
- ASSERT_FALSE(CLSAG_Ver(zero(), P, C, clsag));
- P[idx] = backup;
-
- // bad fake P at verification
- backup = P[(idx + 1) % ring_size];
- P[(idx + 1) % ring_size] = scalarmultBase(skGen());
- ASSERT_FALSE(CLSAG_Ver(zero(), P, C, clsag));
- P[(idx + 1) % ring_size] = backup;
-
- // bad real C at verification
- backup = C[idx];
- C[idx] = scalarmultBase(skGen());
- ASSERT_FALSE(CLSAG_Ver(zero(), P, C, clsag));
- C[idx] = backup;
-
- // bad fake C at verification
- backup = C[(idx + 1) % ring_size];
- C[(idx + 1) % ring_size] = scalarmultBase(skGen());
- ASSERT_FALSE(CLSAG_Ver(zero(), P, C, clsag));
- C[(idx + 1) % ring_size] = backup;
+ pubs[idx] = backup;
+
+ // Test correct signature
+ clsag = rct::proveRctCLSAGSimple(message,pubs,insk,t2,Cout,NULL,NULL,NULL,idx,hw::get_device("default"));
+ ASSERT_TRUE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
// empty s
auto sbackup = clsag.s;
clsag.s.clear();
- ASSERT_FALSE(CLSAG_Ver(identity(), P, C, clsag));
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
clsag.s = sbackup;
// too few s elements
- backup = clsag.s.back();
+ key backup_key;
+ backup_key = clsag.s.back();
clsag.s.pop_back();
- ASSERT_FALSE(CLSAG_Ver(identity(), P, C, clsag));
- clsag.s.push_back(backup);
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
+ clsag.s.push_back(backup_key);
// too many s elements
clsag.s.push_back(skGen());
- ASSERT_FALSE(CLSAG_Ver(identity(), P, C, clsag));
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
clsag.s.pop_back();
// bad s in clsag at verification
for (auto &s: clsag.s)
{
- backup = s;
+ backup_key = s;
s = skGen();
- ASSERT_FALSE(CLSAG_Ver(identity(), P, C, clsag));
- s = backup;
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
+ s = backup_key;
}
// bad c1 in clsag at verification
- backup = clsag.c1;
+ backup_key = clsag.c1;
clsag.c1 = skGen();
- ASSERT_FALSE(CLSAG_Ver(identity(), P, C, clsag));
- clsag.c1 = backup;
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
+ clsag.c1 = backup_key;
// bad I in clsag at verification
- backup = clsag.I;
+ backup_key = clsag.I;
clsag.I = scalarmultBase(skGen());
- ASSERT_FALSE(CLSAG_Ver(identity(), P, C, clsag));
- clsag.I = backup;
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
+ clsag.I = backup_key;
// bad D in clsag at verification
- backup = clsag.D;
+ backup_key = clsag.D;
clsag.D = scalarmultBase(skGen());
- ASSERT_FALSE(CLSAG_Ver(identity(), P, C, clsag));
- clsag.D = backup;
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
+ clsag.D = backup_key;
// D not in main subgroup in clsag at verification
- backup = clsag.D;
+ backup_key = clsag.D;
rct::key x;
ASSERT_TRUE(epee::string_tools::hex_to_pod("c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa", x));
clsag.D = rct::addKeys(clsag.D, x);
- ASSERT_FALSE(CLSAG_Ver(identity(), P, C, clsag));
- clsag.D = backup;
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
+ clsag.D = backup_key;
// swapped I and D in clsag at verification
std::swap(clsag.I, clsag.D);
- ASSERT_FALSE(CLSAG_Ver(identity(), P, C, clsag));
+ ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
std::swap(clsag.I, clsag.D);
// check it's still good, in case we failed to restore
- ASSERT_TRUE(CLSAG_Ver(message, P, C, clsag));
+ ASSERT_TRUE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout));
}
TEST(ringct, range_proofs)