mirror of
https://git.wownero.com/wownero/wownero.git
synced 2024-08-15 01:03:23 +00:00
Merge pull request #1413
648ea6be
blockchain: bring the v4 fork height one block forward (luigi1111)46a0dcc1
ringct: luigi1111's changes to fix and speedup Borromean sigs (luigi1111)76958fc7
ringct: switch to Borromean signatures (Shen Noether)
This commit is contained in:
commit
22e16e88e3
9 changed files with 116 additions and 164 deletions
|
@ -91,8 +91,8 @@ static const struct {
|
||||||
// version 3 starts from block 1141317, which is on or around the 24th of September, 2016. Fork time finalised on 2016-03-21.
|
// version 3 starts from block 1141317, which is on or around the 24th of September, 2016. Fork time finalised on 2016-03-21.
|
||||||
{ 3, 1141317, 0, 1458558528 },
|
{ 3, 1141317, 0, 1458558528 },
|
||||||
|
|
||||||
// version 4 starts from block 1220517, which is on or around the 5th of January, 2017. Fork time finalised on 2016-09-18.
|
// version 4 starts from block 1220516, which is on or around the 5th of January, 2017. Fork time finalised on 2016-09-18.
|
||||||
{ 4, 1220517, 0, 1483574400 },
|
{ 4, 1220516, 0, 1483574400 },
|
||||||
|
|
||||||
// version 5 starts from block 1406997, which is on or around the 20th of September, 2017. Fork time finalised on 2016-09-18.
|
// version 5 starts from block 1406997, which is on or around the 20th of September, 2017. Fork time finalised on 2016-09-18.
|
||||||
{ 5, 1406997, 0, 1505865600 },
|
{ 5, 1406997, 0, 1505865600 },
|
||||||
|
@ -113,7 +113,7 @@ static const struct {
|
||||||
|
|
||||||
// versions 3-5 were passed in rapid succession from September 18th, 2016
|
// versions 3-5 were passed in rapid succession from September 18th, 2016
|
||||||
{ 3, 800500, 0, 1472415034 },
|
{ 3, 800500, 0, 1472415034 },
|
||||||
{ 4, 801220, 0, 1472415035 },
|
{ 4, 801219, 0, 1472415035 },
|
||||||
{ 5, 802660, 0, 1472415036 },
|
{ 5, 802660, 0, 1472415036 },
|
||||||
};
|
};
|
||||||
static const uint64_t testnet_hard_fork_version_1_till = 624633;
|
static const uint64_t testnet_hard_fork_version_1_till = 624633;
|
||||||
|
|
|
@ -207,11 +207,11 @@ namespace boost
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
inline void serialize(Archive &a, rct::asnlSig &x, const boost::serialization::version_type ver)
|
inline void serialize(Archive &a, rct::boroSig &x, const boost::serialization::version_type ver)
|
||||||
{
|
{
|
||||||
a & x.L1;
|
a & x.s0;
|
||||||
a & x.s2;
|
a & x.s1;
|
||||||
a & x.s;
|
a & x.ee;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
|
|
|
@ -267,7 +267,7 @@ namespace rct {
|
||||||
ge_p3_tobytes(AB.bytes, &A2);
|
ge_p3_tobytes(AB.bytes, &A2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//checks if A, B are equal as curve points
|
//checks if A, B are equal in terms of bytes (may say no if one is a non-reduced scalar)
|
||||||
//without doing curve operations
|
//without doing curve operations
|
||||||
bool equalKeys(const key & a, const key & b) {
|
bool equalKeys(const key & a, const key & b) {
|
||||||
bool rv = true;
|
bool rv = true;
|
||||||
|
@ -359,6 +359,19 @@ namespace rct {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key cn_fast_hash(const key64 keys) {
|
||||||
|
key rv;
|
||||||
|
cn_fast_hash(rv, &keys[0], 64 * sizeof(keys[0]));
|
||||||
|
//dp(rv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
key hash_to_scalar(const key64 keys) {
|
||||||
|
key rv = cn_fast_hash(keys);
|
||||||
|
sc_reduce32(rv.bytes);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
key hashToPointSimple(const key & hh) {
|
key hashToPointSimple(const key & hh) {
|
||||||
key pointk;
|
key pointk;
|
||||||
ge_p1p1 point2;
|
ge_p1p1 point2;
|
||||||
|
|
|
@ -158,6 +158,9 @@ namespace rct {
|
||||||
//for mg sigs
|
//for mg sigs
|
||||||
key cn_fast_hash(const keyV &keys);
|
key cn_fast_hash(const keyV &keys);
|
||||||
key hash_to_scalar(const keyV &keys);
|
key hash_to_scalar(const keyV &keys);
|
||||||
|
//for ANSL
|
||||||
|
key cn_fast_hash(const key64 keys);
|
||||||
|
key hash_to_scalar(const key64 keys);
|
||||||
|
|
||||||
//returns hashToPoint as described in https://github.com/ShenNoether/ge_fromfe_writeup
|
//returns hashToPoint as described in https://github.com/ShenNoether/ge_fromfe_writeup
|
||||||
key hashToPointSimple(const key &in);
|
key hashToPointSimple(const key &in);
|
||||||
|
|
|
@ -40,92 +40,64 @@ using namespace crypto;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
namespace rct {
|
namespace rct {
|
||||||
//Schnorr Non-linkable
|
namespace {
|
||||||
//Gen Gives a signature (L1, s1, s2) proving that the sender knows "x" such that xG = one of P1 or P2
|
struct verRangeWrapper_ {
|
||||||
//Ver Verifies that signer knows an "x" such that xG = one of P1 or P2
|
void operator()(const key & C, const rangeSig & as, bool &result) const {
|
||||||
//These are called in the below ASNL sig generation
|
result = verRange(C, as);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
constexpr const verRangeWrapper_ verRangeWrapper{};
|
||||||
|
|
||||||
void GenSchnorrNonLinkable(key & L1, key & s1, key & s2, const key & x, const key & P1, const key & P2, unsigned int index) {
|
struct verRctMGSimpleWrapper_ {
|
||||||
key c1, c2, L2;
|
void operator()(const key &message, const mgSig &mg, const ctkeyV & pubs, const key & C, bool &result) const {
|
||||||
key a = skGen();
|
result = verRctMGSimple(message, mg, pubs, C);
|
||||||
if (index == 0) {
|
|
||||||
scalarmultBase(L1, a);
|
|
||||||
hash_to_scalar(c2, L1);
|
|
||||||
skGen(s2);
|
|
||||||
addKeys2(L2, s2, c2, P2);
|
|
||||||
hash_to_scalar(c1, L2);
|
|
||||||
//s1 = a - x * c1
|
|
||||||
sc_mulsub(s1.bytes, x.bytes, c1.bytes, a.bytes);
|
|
||||||
}
|
|
||||||
else if (index == 1) {
|
|
||||||
scalarmultBase(L2, a);
|
|
||||||
hash_to_scalar(c1, L2);
|
|
||||||
skGen(s1);
|
|
||||||
addKeys2(L1, s1, c1, P1);
|
|
||||||
hash_to_scalar(c2, L1);
|
|
||||||
sc_mulsub(s2.bytes, x.bytes, c2.bytes, a.bytes);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw std::runtime_error("GenSchnorrNonLinkable: invalid index (should be 0 or 1)");
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
constexpr const verRctMGSimpleWrapper_ verRctMGSimpleWrapper{};
|
||||||
}
|
}
|
||||||
|
|
||||||
//Schnorr Non-linkable
|
//Borromean (c.f. gmax/andytoshi's paper)
|
||||||
//Gen Gives a signature (L1, s1, s2) proving that the sender knows "x" such that xG = one of P1 or P2
|
boroSig genBorromean(const key64 x, const key64 P1, const key64 P2, const bits indices) {
|
||||||
//Ver Verifies that signer knows an "x" such that xG = one of P1 or P2
|
key64 L[2], alpha;
|
||||||
//These are called in the below ASNL sig generation
|
key c;
|
||||||
bool VerSchnorrNonLinkable(const key & P1, const key & P2, const key & L1, const key & s1, const key & s2) {
|
int naught = 0, prime = 0, ii = 0, jj=0;
|
||||||
key c2, L2, c1, L1p;
|
boroSig bb;
|
||||||
hash_to_scalar(c2, L1);
|
for (ii = 0 ; ii < 64 ; ii++) {
|
||||||
addKeys2(L2, s2, c2, P2);
|
naught = indices[ii]; prime = (indices[ii] + 1) % 2;
|
||||||
hash_to_scalar(c1, L2);
|
skGen(alpha[ii]);
|
||||||
addKeys2(L1p, s1, c1, P1);
|
scalarmultBase(L[naught][ii], alpha[ii]);
|
||||||
|
if (naught == 0) {
|
||||||
return equalKeys(L1, L1p);
|
skGen(bb.s1[ii]);
|
||||||
|
c = hash_to_scalar(L[naught][ii]);
|
||||||
|
addKeys2(L[prime][ii], bb.s1[ii], c, P2[ii]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bb.ee = hash_to_scalar(L[1]); //or L[1]..
|
||||||
|
key LL, cc;
|
||||||
|
for (jj = 0 ; jj < 64 ; jj++) {
|
||||||
|
if (!indices[jj]) {
|
||||||
|
sc_mulsub(bb.s0[jj].bytes, x[jj].bytes, bb.ee.bytes, alpha[jj].bytes);
|
||||||
|
} else {
|
||||||
|
skGen(bb.s0[jj]);
|
||||||
|
addKeys2(LL, bb.s0[jj], bb.ee, P1[jj]); //different L0
|
||||||
|
cc = hash_to_scalar(LL);
|
||||||
|
sc_mulsub(bb.s1[jj].bytes, x[jj].bytes, cc.bytes, alpha[jj].bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Aggregate Schnorr Non-linkable Ring Signature (ASNL)
|
//see above.
|
||||||
// c.f. http://eprint.iacr.org/2015/1098 section 5.
|
bool verifyBorromean(const boroSig &bb, const key64 P1, const key64 P2) {
|
||||||
// These are used in range proofs (alternatively Borromean could be used)
|
key64 Lv1; key chash, LL;
|
||||||
// Gen gives a signature which proves the signer knows, for each i,
|
int ii = 0;
|
||||||
// an x[i] such that x[i]G = one of P1[i] or P2[i]
|
for (ii = 0 ; ii < 64 ; ii++) {
|
||||||
// Ver Verifies the signer knows a key for one of P1[i], P2[i] at each i
|
addKeys2(LL, bb.s0[ii], bb.ee, P1[ii]);
|
||||||
asnlSig GenASNL(key64 x, key64 P1, key64 P2, bits indices) {
|
chash = hash_to_scalar(LL);
|
||||||
DP("Generating Aggregate Schnorr Non-linkable Ring Signature\n");
|
addKeys2(Lv1[ii], bb.s1[ii], chash, P2[ii]);
|
||||||
key64 s1;
|
|
||||||
int j = 0;
|
|
||||||
asnlSig rv;
|
|
||||||
rv.s = zero();
|
|
||||||
for (j = 0; j < ATOMS; j++) {
|
|
||||||
GenSchnorrNonLinkable(rv.L1[j], s1[j], rv.s2[j], x[j], P1[j], P2[j], indices[j]);
|
|
||||||
sc_add(rv.s.bytes, rv.s.bytes, s1[j].bytes);
|
|
||||||
}
|
}
|
||||||
return rv;
|
key eeComputed = hash_to_scalar(Lv1); //hash function fine
|
||||||
}
|
return equalKeys(eeComputed, bb.ee);
|
||||||
|
|
||||||
//Aggregate Schnorr Non-linkable Ring Signature (ASNL)
|
|
||||||
// c.f. http://eprint.iacr.org/2015/1098 section 5.
|
|
||||||
// These are used in range proofs (alternatively Borromean could be used)
|
|
||||||
// Gen gives a signature which proves the signer knows, for each i,
|
|
||||||
// an x[i] such that x[i]G = one of P1[i] or P2[i]
|
|
||||||
// Ver Verifies the signer knows a key for one of P1[i], P2[i] at each i
|
|
||||||
bool VerASNL(const key64 P1, const key64 P2, const asnlSig &as) {
|
|
||||||
PERF_TIMER(VerASNL);
|
|
||||||
DP("Verifying Aggregate Schnorr Non-linkable Ring Signature\n");
|
|
||||||
key LHS = identity();
|
|
||||||
key RHS = scalarmultBase(as.s);
|
|
||||||
key c2, L2, c1;
|
|
||||||
int j = 0;
|
|
||||||
for (j = 0; j < ATOMS; j++) {
|
|
||||||
hash_to_scalar(c2, as.L1[j]);
|
|
||||||
addKeys2(L2, as.s2[j], c2, P2[j]);
|
|
||||||
addKeys(LHS, LHS, as.L1[j]);
|
|
||||||
hash_to_scalar(c1, L2);
|
|
||||||
addKeys(RHS, RHS, scalarmultKey(P1[j], c1));
|
|
||||||
}
|
|
||||||
key cc;
|
|
||||||
sc_sub(cc.bytes, LHS.bytes, RHS.bytes);
|
|
||||||
return sc_isnonzero(cc.bytes) == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures)
|
//Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures)
|
||||||
|
@ -323,7 +295,7 @@ namespace rct {
|
||||||
sc_add(mask.bytes, mask.bytes, ai[i].bytes);
|
sc_add(mask.bytes, mask.bytes, ai[i].bytes);
|
||||||
addKeys(C, C, sig.Ci[i]);
|
addKeys(C, C, sig.Ci[i]);
|
||||||
}
|
}
|
||||||
sig.asig = GenASNL(ai, sig.Ci, CiH, b);
|
sig.asig = genBorromean(ai, sig.Ci, CiH, b);
|
||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +317,7 @@ namespace rct {
|
||||||
}
|
}
|
||||||
if (!equalKeys(C, Ctmp))
|
if (!equalKeys(C, Ctmp))
|
||||||
return false;
|
return false;
|
||||||
if (!VerASNL(as.Ci, CiH, as.asig))
|
if (!verifyBorromean(as.asig, as.Ci, CiH))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -371,10 +343,10 @@ namespace rct {
|
||||||
for (auto r: rv.p.rangeSigs)
|
for (auto r: rv.p.rangeSigs)
|
||||||
{
|
{
|
||||||
for (size_t n = 0; n < 64; ++n)
|
for (size_t n = 0; n < 64; ++n)
|
||||||
kv.push_back(r.asig.L1[n]);
|
kv.push_back(r.asig.s0[n]);
|
||||||
for (size_t n = 0; n < 64; ++n)
|
for (size_t n = 0; n < 64; ++n)
|
||||||
kv.push_back(r.asig.s2[n]);
|
kv.push_back(r.asig.s1[n]);
|
||||||
kv.push_back(r.asig.s);
|
kv.push_back(r.asig.ee);
|
||||||
for (size_t n = 0; n < 64; ++n)
|
for (size_t n = 0; n < 64; ++n)
|
||||||
kv.push_back(r.Ci[n]);
|
kv.push_back(r.Ci[n]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,21 +66,8 @@ using namespace crypto;
|
||||||
|
|
||||||
namespace rct {
|
namespace rct {
|
||||||
|
|
||||||
//Schnorr Non-linkable
|
boroSig genBorromean(const key64 x, const key64 P1, const key64 P2, const bits indices);
|
||||||
//Gen Gives a signature (L1, s1, s2) proving that the sender knows "x" such that xG = one of P1 or P2
|
bool verifyBorromean(const boroSig &bb, const key64 P1, const key64 P2);
|
||||||
//Ver Verifies that signer knows an "x" such that xG = one of P1 or P2
|
|
||||||
//These are called in the below ASNL sig generation
|
|
||||||
void GenSchnorrNonLinkable(key & L1, key & s1, key & s2, const key & x, const key & P1, const key & P2, unsigned int index);
|
|
||||||
bool VerSchnorrNonLinkable(const key & P1, const key & P2, const key & L1, const key & s1, const key & s2);
|
|
||||||
|
|
||||||
//Aggregate Schnorr Non-linkable Ring Signature (ASNL)
|
|
||||||
// c.f. http://eprint.iacr.org/2015/1098 section 5.
|
|
||||||
// These are used in range proofs (alternatively Borromean could be used)
|
|
||||||
// Gen gives a signature which proves the signer knows, for each i,
|
|
||||||
// an x[i] such that x[i]G = one of P1[i] or P2[i]
|
|
||||||
// Ver Verifies the signer knows a key for one of P1[i], P2[i] at each i
|
|
||||||
asnlSig GenASNL(key64 x, key64 P1, key64 P2, bits indices);
|
|
||||||
bool VerASNL(const key64 P1, const key64 P2, const asnlSig &as);
|
|
||||||
|
|
||||||
//Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures)
|
//Multilayered Spontaneous Anonymous Group Signatures (MLSAG signatures)
|
||||||
//These are aka MG signatutes in earlier drafts of the ring ct paper
|
//These are aka MG signatutes in earlier drafts of the ring ct paper
|
||||||
|
|
|
@ -125,12 +125,10 @@ namespace rct {
|
||||||
typedef unsigned int bits[ATOMS];
|
typedef unsigned int bits[ATOMS];
|
||||||
typedef key key64[64];
|
typedef key key64[64];
|
||||||
|
|
||||||
//just contains the necessary keys to represent asnlSigs
|
struct boroSig {
|
||||||
//c.f. http://eprint.iacr.org/2015/1098
|
key64 s0;
|
||||||
struct asnlSig {
|
key64 s1;
|
||||||
key64 L1;
|
key ee;
|
||||||
key64 s2;
|
|
||||||
key s;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Container for precomp
|
//Container for precomp
|
||||||
|
@ -151,14 +149,14 @@ namespace rct {
|
||||||
// FIELD(II) - not serialized, it can be reconstructed
|
// FIELD(II) - not serialized, it can be reconstructed
|
||||||
END_SERIALIZE()
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
//contains the data for an asnl sig
|
//contains the data for an Borromean sig
|
||||||
// also contains the "Ci" values such that
|
// also contains the "Ci" values such that
|
||||||
// \sum Ci = C
|
// \sum Ci = C
|
||||||
// and the signature proves that each Ci is either
|
// and the signature proves that each Ci is either
|
||||||
// a Pedersen commitment to 0 or to 2^i
|
// a Pedersen commitment to 0 or to 2^i
|
||||||
//thus proving that C is in the range of [0, 2^64]
|
//thus proving that C is in the range of [0, 2^64]
|
||||||
struct rangeSig {
|
struct rangeSig {
|
||||||
asnlSig asig;
|
boroSig asig;
|
||||||
key64 Ci;
|
key64 Ci;
|
||||||
|
|
||||||
BEGIN_SERIALIZE_OBJECT()
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
@ -452,7 +450,7 @@ inline std::ostream &operator <<(std::ostream &o, const rct::key &v) { return pr
|
||||||
BLOB_SERIALIZER(rct::key);
|
BLOB_SERIALIZER(rct::key);
|
||||||
BLOB_SERIALIZER(rct::key64);
|
BLOB_SERIALIZER(rct::key64);
|
||||||
BLOB_SERIALIZER(rct::ctkey);
|
BLOB_SERIALIZER(rct::ctkey);
|
||||||
BLOB_SERIALIZER(rct::asnlSig);
|
BLOB_SERIALIZER(rct::boroSig);
|
||||||
|
|
||||||
VARIANT_TAG(debug_archive, rct::key, "rct::key");
|
VARIANT_TAG(debug_archive, rct::key, "rct::key");
|
||||||
VARIANT_TAG(debug_archive, rct::key64, "rct::key64");
|
VARIANT_TAG(debug_archive, rct::key64, "rct::key64");
|
||||||
|
@ -464,7 +462,7 @@ VARIANT_TAG(debug_archive, rct::ctkeyM, "rct::ctkeyM");
|
||||||
VARIANT_TAG(debug_archive, rct::ecdhTuple, "rct::ecdhTuple");
|
VARIANT_TAG(debug_archive, rct::ecdhTuple, "rct::ecdhTuple");
|
||||||
VARIANT_TAG(debug_archive, rct::mgSig, "rct::mgSig");
|
VARIANT_TAG(debug_archive, rct::mgSig, "rct::mgSig");
|
||||||
VARIANT_TAG(debug_archive, rct::rangeSig, "rct::rangeSig");
|
VARIANT_TAG(debug_archive, rct::rangeSig, "rct::rangeSig");
|
||||||
VARIANT_TAG(debug_archive, rct::asnlSig, "rct::asnlSig");
|
VARIANT_TAG(debug_archive, rct::boroSig, "rct::boroSig");
|
||||||
VARIANT_TAG(debug_archive, rct::rctSig, "rct::rctSig");
|
VARIANT_TAG(debug_archive, rct::rctSig, "rct::rctSig");
|
||||||
|
|
||||||
VARIANT_TAG(binary_archive, rct::key, 0x90);
|
VARIANT_TAG(binary_archive, rct::key, 0x90);
|
||||||
|
@ -477,7 +475,7 @@ VARIANT_TAG(binary_archive, rct::ctkeyM, 0x96);
|
||||||
VARIANT_TAG(binary_archive, rct::ecdhTuple, 0x97);
|
VARIANT_TAG(binary_archive, rct::ecdhTuple, 0x97);
|
||||||
VARIANT_TAG(binary_archive, rct::mgSig, 0x98);
|
VARIANT_TAG(binary_archive, rct::mgSig, 0x98);
|
||||||
VARIANT_TAG(binary_archive, rct::rangeSig, 0x99);
|
VARIANT_TAG(binary_archive, rct::rangeSig, 0x99);
|
||||||
VARIANT_TAG(binary_archive, rct::asnlSig, 0x9a);
|
VARIANT_TAG(binary_archive, rct::boroSig, 0x9a);
|
||||||
VARIANT_TAG(binary_archive, rct::rctSig, 0x9b);
|
VARIANT_TAG(binary_archive, rct::rctSig, 0x9b);
|
||||||
|
|
||||||
VARIANT_TAG(json_archive, rct::key, "rct_key");
|
VARIANT_TAG(json_archive, rct::key, "rct_key");
|
||||||
|
@ -490,7 +488,7 @@ VARIANT_TAG(json_archive, rct::ctkeyM, "rct_ctkeyM");
|
||||||
VARIANT_TAG(json_archive, rct::ecdhTuple, "rct_ecdhTuple");
|
VARIANT_TAG(json_archive, rct::ecdhTuple, "rct_ecdhTuple");
|
||||||
VARIANT_TAG(json_archive, rct::mgSig, "rct_mgSig");
|
VARIANT_TAG(json_archive, rct::mgSig, "rct_mgSig");
|
||||||
VARIANT_TAG(json_archive, rct::rangeSig, "rct_rangeSig");
|
VARIANT_TAG(json_archive, rct::rangeSig, "rct_rangeSig");
|
||||||
VARIANT_TAG(json_archive, rct::asnlSig, "rct_asnlSig");
|
VARIANT_TAG(json_archive, rct::boroSig, "rct_boroSig");
|
||||||
VARIANT_TAG(json_archive, rct::rctSig, "rct_rctSig");
|
VARIANT_TAG(json_archive, rct::rctSig, "rct_rctSig");
|
||||||
|
|
||||||
#endif /* RCTTYPES_H */
|
#endif /* RCTTYPES_H */
|
||||||
|
|
|
@ -40,29 +40,12 @@
|
||||||
using namespace crypto;
|
using namespace crypto;
|
||||||
using namespace rct;
|
using namespace rct;
|
||||||
|
|
||||||
TEST(ringct, SNL)
|
TEST(ringct, Borromean)
|
||||||
{
|
|
||||||
key x, P1;
|
|
||||||
skpkGen(x, P1);
|
|
||||||
|
|
||||||
key P2 = pkGen();
|
|
||||||
key P3 = pkGen();
|
|
||||||
|
|
||||||
key L1, s1, s2;
|
|
||||||
GenSchnorrNonLinkable(L1, s1, s2, x, P1, P2, 0);
|
|
||||||
|
|
||||||
// a valid one
|
|
||||||
// an invalid one
|
|
||||||
ASSERT_TRUE(VerSchnorrNonLinkable(P1, P2, L1, s1, s2));
|
|
||||||
ASSERT_FALSE(VerSchnorrNonLinkable(P1, P3, L1, s1, s2));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(ringct, ASNL)
|
|
||||||
{
|
{
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
//Tests for ASNL
|
//Tests for Borromean signatures
|
||||||
//#ASNL true one, false one, C != sum Ci, and one out of the range..
|
//#boro true one, false one, C != sum Ci, and one out of the range..
|
||||||
int N = 64;
|
int N = 64;
|
||||||
key64 xv;
|
key64 xv;
|
||||||
key64 P1v;
|
key64 P1v;
|
||||||
|
@ -74,34 +57,30 @@ TEST(ringct, ASNL)
|
||||||
|
|
||||||
xv[j] = skGen();
|
xv[j] = skGen();
|
||||||
if ( (int)indi[j] == 0 ) {
|
if ( (int)indi[j] == 0 ) {
|
||||||
P1v[j] = scalarmultBase(xv[j]);
|
scalarmultBase(P1v[j], xv[j]);
|
||||||
P2v[j] = pkGen();
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
addKeys1(P1v[j], xv[j], H2[j]);
|
||||||
P2v[j] = scalarmultBase(xv[j]);
|
|
||||||
P1v[j] = pkGen();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
subKeys(P2v[j], P1v[j], H2[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#true one
|
//#true one
|
||||||
asnlSig L1s2s = GenASNL(xv, P1v, P2v, indi);
|
boroSig bb = genBorromean(xv, P1v, P2v, indi);
|
||||||
ASSERT_TRUE(VerASNL(P1v, P2v, L1s2s));
|
ASSERT_TRUE(verifyBorromean(bb, P1v, P2v));
|
||||||
|
|
||||||
//#false one
|
//#false one
|
||||||
indi[3] = (indi[3] + 1) % 2;
|
indi[3] = (indi[3] + 1) % 2;
|
||||||
L1s2s = GenASNL(xv, P1v, P2v, indi);
|
bb = genBorromean(xv, P1v, P2v, indi);
|
||||||
ASSERT_FALSE(VerASNL(P1v, P2v, L1s2s));
|
ASSERT_FALSE(verifyBorromean(bb, P1v, P2v));
|
||||||
|
|
||||||
//#true one again
|
//#true one again
|
||||||
indi[3] = (indi[3] + 1) % 2;
|
indi[3] = (indi[3] + 1) % 2;
|
||||||
L1s2s = GenASNL(xv, P1v, P2v, indi);
|
bb = genBorromean(xv, P1v, P2v, indi);
|
||||||
ASSERT_TRUE(VerASNL(P1v, P2v, L1s2s));
|
ASSERT_TRUE(verifyBorromean(bb, P1v, P2v));
|
||||||
|
|
||||||
//#false one
|
//#false one
|
||||||
L1s2s = GenASNL(xv, P2v, P1v, indi);
|
bb = genBorromean(xv, P2v, P1v, indi);
|
||||||
ASSERT_FALSE(VerASNL(P1v, P2v, L1s2s));
|
ASSERT_FALSE(verifyBorromean(bb, P1v, P2v));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ringct, MG_sigs)
|
TEST(ringct, MG_sigs)
|
||||||
|
|
|
@ -457,7 +457,7 @@ TEST(Serialization, serializes_ringct_types)
|
||||||
rct::ctkeyV ctkeyv0, ctkeyv1;
|
rct::ctkeyV ctkeyv0, ctkeyv1;
|
||||||
rct::ctkeyM ctkeym0, ctkeym1;
|
rct::ctkeyM ctkeym0, ctkeym1;
|
||||||
rct::ecdhTuple ecdh0, ecdh1;
|
rct::ecdhTuple ecdh0, ecdh1;
|
||||||
rct::asnlSig asnl0, asnl1;
|
rct::boroSig boro0, boro1;
|
||||||
rct::mgSig mg0, mg1;
|
rct::mgSig mg0, mg1;
|
||||||
rct::rangeSig rg0, rg1;
|
rct::rangeSig rg0, rg1;
|
||||||
rct::rctSig s0, s1;
|
rct::rctSig s0, s1;
|
||||||
|
@ -541,13 +541,13 @@ TEST(Serialization, serializes_ringct_types)
|
||||||
|
|
||||||
for (size_t n = 0; n < 64; ++n)
|
for (size_t n = 0; n < 64; ++n)
|
||||||
{
|
{
|
||||||
asnl0.L1[n] = rct::skGen();
|
boro0.s0[n] = rct::skGen();
|
||||||
asnl0.s2[n] = rct::skGen();
|
boro0.s1[n] = rct::skGen();
|
||||||
}
|
}
|
||||||
asnl0.s = rct::skGen();
|
boro0.ee = rct::skGen();
|
||||||
ASSERT_TRUE(serialization::dump_binary(asnl0, blob));
|
ASSERT_TRUE(serialization::dump_binary(boro0, blob));
|
||||||
ASSERT_TRUE(serialization::parse_binary(blob, asnl1));
|
ASSERT_TRUE(serialization::parse_binary(blob, boro1));
|
||||||
ASSERT_TRUE(!memcmp(&asnl0, &asnl1, sizeof(asnl0)));
|
ASSERT_TRUE(!memcmp(&boro0, &boro1, sizeof(boro0)));
|
||||||
|
|
||||||
// create a full rct signature to use its innards
|
// create a full rct signature to use its innards
|
||||||
rct::ctkeyV sc, pc;
|
rct::ctkeyV sc, pc;
|
||||||
|
|
Loading…
Reference in a new issue