From 0d3203ba2e2cc9896ee55c944794c150de732c38 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Tue, 27 Jun 2023 18:09:53 -0500 Subject: [PATCH] added optional return values (instead of throwing exceptions) and enabled checks in 'pairing' and 'map' functions --- libraries/chain/webassembly/crypto.cpp | 64 +++++++++++++++--------- libraries/libfc/libraries/bls12-381 | 2 +- libraries/libfc/test/crypto/test_bls.cpp | 4 +- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/libraries/chain/webassembly/crypto.cpp b/libraries/chain/webassembly/crypto.cpp index 937e2fe298..baff2374e9 100644 --- a/libraries/chain/webassembly/crypto.cpp +++ b/libraries/chain/webassembly/crypto.cpp @@ -255,9 +255,11 @@ namespace eosio { namespace chain { namespace webassembly { { if(op1.size() != 144 || op2.size() != 144 || result.size() != 144) return return_code::failure; - bls12_381::g1 a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op1.data()), 144}, false, true); - bls12_381::g1 b = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op2.data()), 144}, false, true); - bls12_381::g1 c = a.add(b); + std::optional a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op1.data()), 144}, false, true); + std::optional b = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op2.data()), 144}, false, true); + if(!a.has_value() || !b.has_value()) + return return_code::failure; + bls12_381::g1 c = a.value().add(b.value()); c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); return return_code::success; } @@ -266,9 +268,11 @@ namespace eosio { namespace chain { namespace webassembly { { if(op1.size() != 288 || op2.size() != 288 || result.size() != 288) return return_code::failure; - bls12_381::g2 a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op1.data()), 288}, false, true); - bls12_381::g2 b = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op2.data()), 288}, false, true); - bls12_381::g2 c = a.add(b); + std::optional a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op1.data()), 288}, false, true); + std::optional b = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op2.data()), 288}, false, true); + if(!a.has_value() || !b.has_value()) + return return_code::failure; + bls12_381::g2 c = a.value().add(b.value()); c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); return return_code::success; } @@ -277,9 +281,11 @@ namespace eosio { namespace chain { namespace webassembly { { if(point.size() != 144 || scalar.size() != 32 || result.size() != 144) return return_code::failure; - bls12_381::g1 a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(point.data()), 144}, false, true); + std::optional a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(point.data()), 144}, false, true); + if(!a.has_value()) + return return_code::failure; std::array b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalar.data()), 32}); - bls12_381::g1 c = a.mulScalar(b); + bls12_381::g1 c = a.value().mulScalar(b); c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); return return_code::success; } @@ -288,9 +294,11 @@ namespace eosio { namespace chain { namespace webassembly { { if(point.size() != 288 || scalar.size() != 32 || result.size() != 288) return return_code::failure; - bls12_381::g2 a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(point.data()), 288}, false, true); + std::optional a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(point.data()), 288}, false, true); + if(!a.has_value()) + return return_code::failure; std::array b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalar.data()), 32}); - bls12_381::g2 c = a.mulScalar(b); + bls12_381::g2 c = a.value().mulScalar(b); c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); return return_code::success; } @@ -305,14 +313,16 @@ namespace eosio { namespace chain { namespace webassembly { sv.reserve(n); for(uint32_t i = 0; i < n; i++) { - bls12_381::g1 p = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(points.data() + i*144), 144}, false, true); + std::optional p = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(points.data() + i*144), 144}, false, true); + if(!p.has_value()) + return return_code::failure; std::array s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalars.data() + i*32), 32}); - pv.push_back(p); + pv.push_back(p.value()); sv.push_back(s); if(i%10 == 0) context.trx_context.checktime(); } - bls12_381::g1 r = bls12_381::g1::multiExp(pv, sv); + bls12_381::g1 r = bls12_381::g1::multiExp(pv, sv).value(); // accessing value is safe r.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); return return_code::success; } @@ -327,14 +337,16 @@ namespace eosio { namespace chain { namespace webassembly { sv.reserve(n); for(uint32_t i = 0; i < n; i++) { - bls12_381::g2 p = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(points.data() + i*288), 288}, false, true); + std::optional p = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(points.data() + i*288), 288}, false, true); + if(!p.has_value()) + return return_code::failure; std::array s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalars.data() + i*32), 32}); - pv.push_back(p); + pv.push_back(p.value()); sv.push_back(s); if(i%6 == 0) context.trx_context.checktime(); } - bls12_381::g2 r = bls12_381::g2::multiExp(pv, sv, [this](){ context.trx_context.checktime(); }); + bls12_381::g2 r = bls12_381::g2::multiExp(pv, sv, [this](){ context.trx_context.checktime(); }).value(); // accessing value is safe r.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); return return_code::success; } @@ -347,9 +359,11 @@ namespace eosio { namespace chain { namespace webassembly { v.reserve(n); for(uint32_t i = 0; i < n; i++) { - bls12_381::g1 p_g1 = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(g1_points.data() + i*144), 144}, false, true); - bls12_381::g2 p_g2 = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(g2_points.data() + i*288), 288}, false, true); - bls12_381::pairing::add_pair(v, p_g1, p_g2); + std::optional p_g1 = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(g1_points.data() + i*144), 144}, true, true); + std::optional p_g2 = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(g2_points.data() + i*288), 288}, true, true); + if(!p_g1.has_value() || !p_g2.has_value()) + return return_code::failure; + bls12_381::pairing::add_pair(v, p_g1.value(), p_g2.value()); if(i%4 == 0) context.trx_context.checktime(); } @@ -362,8 +376,10 @@ namespace eosio { namespace chain { namespace webassembly { { if(e.size() != 48 || result.size() != 144) return return_code::failure; - bls12_381::fp a = bls12_381::fp::fromBytesLE({reinterpret_cast(e.data()), 48}, false, true); - bls12_381::g1 c = bls12_381::g1::mapToCurve(a); + std::optional a = bls12_381::fp::fromBytesLE({reinterpret_cast(e.data()), 48}, true, true); + if(!a.has_value()) + return return_code::failure; + bls12_381::g1 c = bls12_381::g1::mapToCurve(a.value()); c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); return return_code::success; } @@ -372,8 +388,10 @@ namespace eosio { namespace chain { namespace webassembly { { if(e.size() != 96 || result.size() != 288) return return_code::failure; - bls12_381::fp2 a = bls12_381::fp2::fromBytesLE({reinterpret_cast(e.data()), 96}, false, true); - bls12_381::g2 c = bls12_381::g2::mapToCurve(a); + std::optional a = bls12_381::fp2::fromBytesLE({reinterpret_cast(e.data()), 96}, true, true); + if(!a.has_value()) + return return_code::failure; + bls12_381::g2 c = bls12_381::g2::mapToCurve(a.value()); c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); return return_code::success; } diff --git a/libraries/libfc/libraries/bls12-381 b/libraries/libfc/libraries/bls12-381 index e43561f9bd..17c3dc17d8 160000 --- a/libraries/libfc/libraries/bls12-381 +++ b/libraries/libfc/libraries/bls12-381 @@ -1 +1 @@ -Subproject commit e43561f9bd036123be81c73372e05016048c8618 +Subproject commit 17c3dc17d87f051fe2689ea923ee8628487e1d31 diff --git a/libraries/libfc/test/crypto/test_bls.cpp b/libraries/libfc/test/crypto/test_bls.cpp index 3e8853a171..a67a9d9395 100644 --- a/libraries/libfc/test/crypto/test_bls.cpp +++ b/libraries/libfc/test/crypto/test_bls.cpp @@ -38,8 +38,8 @@ BOOST_AUTO_TEST_CASE(bls_serialization_test) try { cout << pk_string << std::endl; cout << signature_string << std::endl; - g1 pk2 = g1::fromJacobianBytesBE(hexToBytes(pk_string)); - g2 signature2 = g2::fromJacobianBytesBE(hexToBytes(signature_string)); + g1 pk2 = g1::fromJacobianBytesBE(hexToBytes(pk_string)).value(); + g2 signature2 = g2::fromJacobianBytesBE(hexToBytes(signature_string)).value(); bool ok = verify(pk2, message_1, signature2); BOOST_CHECK_EQUAL(ok, true); } FC_LOG_AND_RETHROW();