diff options
Diffstat (limited to 'src/ringct')
-rw-r--r-- | src/ringct/bulletproofs.cc | 13 | ||||
-rw-r--r-- | src/ringct/rctOps.cpp | 17 | ||||
-rw-r--r-- | src/ringct/rctOps.h | 3 |
3 files changed, 33 insertions, 0 deletions
diff --git a/src/ringct/bulletproofs.cc b/src/ringct/bulletproofs.cc index bc7e15f35..7ec87378b 100644 --- a/src/ringct/bulletproofs.cc +++ b/src/ringct/bulletproofs.cc @@ -922,6 +922,19 @@ bool bulletproof_VERIFY(const std::vector<const Bulletproof*> &proofs) for (const Bulletproof *p: proofs) { const Bulletproof &proof = *p; + + // check subgroup + for (const rct::key &k: proof.V) + CHECK_AND_ASSERT_MES(rct::isInMainSubgroup(k), false, "Input point not in subgroup"); + for (const rct::key &k: proof.L) + CHECK_AND_ASSERT_MES(rct::isInMainSubgroup(k), false, "Input point not in subgroup"); + for (const rct::key &k: proof.R) + CHECK_AND_ASSERT_MES(rct::isInMainSubgroup(k), false, "Input point not in subgroup"); + CHECK_AND_ASSERT_MES(rct::isInMainSubgroup(proof.A), false, "Input point not in subgroup"); + CHECK_AND_ASSERT_MES(rct::isInMainSubgroup(proof.S), false, "Input point not in subgroup"); + CHECK_AND_ASSERT_MES(rct::isInMainSubgroup(proof.T1), false, "Input point not in subgroup"); + CHECK_AND_ASSERT_MES(rct::isInMainSubgroup(proof.T2), false, "Input point not in subgroup"); + CHECK_AND_ASSERT_MES(proof.V.size() >= 1, false, "V does not have at least one element"); CHECK_AND_ASSERT_MES(proof.L.size() == proof.R.size(), false, "Mismatched L and R sizes"); CHECK_AND_ASSERT_MES(proof.L.size() > 0, false, "Empty proof"); diff --git a/src/ringct/rctOps.cpp b/src/ringct/rctOps.cpp index fe0ad8747..df027f4b6 100644 --- a/src/ringct/rctOps.cpp +++ b/src/ringct/rctOps.cpp @@ -60,6 +60,17 @@ namespace rct { //Various key generation functions + bool toPointCheckOrder(ge_p3 *P, const unsigned char *data) + { + if (ge_frombytes_vartime(P, data)) + return false; + ge_p2 R; + ge_scalarmult(&R, curveOrder().bytes, P); + key tmp; + ge_tobytes(tmp.bytes, &R); + return tmp == identity(); + } + //generates a random scalar which can be used as a secret key or mask void skGen(key &sk) { random32_unbiased(sk.bytes); @@ -200,6 +211,12 @@ namespace rct { return aP; } + //Computes aL where L is the curve order + bool isInMainSubgroup(const key & a) { + ge_p3 p3; + return toPointCheckOrder(&p3, a.bytes); + } + //Curve addition / subtractions //for curve points: AB = A + B diff --git a/src/ringct/rctOps.h b/src/ringct/rctOps.h index f8889af5c..f0320f333 100644 --- a/src/ringct/rctOps.h +++ b/src/ringct/rctOps.h @@ -83,6 +83,7 @@ namespace rct { keyM keyMInit(size_t rows, size_t cols); //Various key generation functions + bool toPointCheckOrder(ge_p3 *P, const unsigned char *data); //generates a random scalar which can be used as a secret key or mask key skGen(); @@ -119,6 +120,8 @@ namespace rct { key scalarmultKey(const key &P, const key &a); //Computes aH where H= toPoint(cn_fast_hash(G)), G the basepoint key scalarmultH(const key & a); + // checks a is in the main subgroup (ie, not a small one) + bool isInMainSubgroup(const key & a); //Curve addition / subtractions |