Skip to content

Commit

Permalink
added optional return values (instead of throwing exceptions) and ena…
Browse files Browse the repository at this point in the history
…bled checks in 'pairing' and 'map' functions
  • Loading branch information
mschoenebeck committed Jun 27, 2023
1 parent 1ca2373 commit 0d3203b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 26 deletions.
64 changes: 41 additions & 23 deletions libraries/chain/webassembly/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<const uint8_t*>(op1.data()), 144}, false, true);
bls12_381::g1 b = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(op2.data()), 144}, false, true);
bls12_381::g1 c = a.add(b);
std::optional<bls12_381::g1> a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(op1.data()), 144}, false, true);
std::optional<bls12_381::g1> b = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(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<uint8_t*>(result.data()), 144}, true);
return return_code::success;
}
Expand All @@ -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<const uint8_t*>(op1.data()), 288}, false, true);
bls12_381::g2 b = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(op2.data()), 288}, false, true);
bls12_381::g2 c = a.add(b);
std::optional<bls12_381::g2> a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(op1.data()), 288}, false, true);
std::optional<bls12_381::g2> b = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(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<uint8_t*>(result.data()), 288}, true);
return return_code::success;
}
Expand All @@ -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<const uint8_t*>(point.data()), 144}, false, true);
std::optional<bls12_381::g1> a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(point.data()), 144}, false, true);
if(!a.has_value())
return return_code::failure;
std::array<uint64_t, 4> b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast<const uint8_t*>(scalar.data()), 32});
bls12_381::g1 c = a.mulScalar(b);
bls12_381::g1 c = a.value().mulScalar(b);
c.toJacobianBytesLE({reinterpret_cast<uint8_t*>(result.data()), 144}, true);
return return_code::success;
}
Expand All @@ -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<const uint8_t*>(point.data()), 288}, false, true);
std::optional<bls12_381::g2> a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(point.data()), 288}, false, true);
if(!a.has_value())
return return_code::failure;
std::array<uint64_t, 4> b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast<const uint8_t*>(scalar.data()), 32});
bls12_381::g2 c = a.mulScalar(b);
bls12_381::g2 c = a.value().mulScalar(b);
c.toJacobianBytesLE({reinterpret_cast<uint8_t*>(result.data()), 288}, true);
return return_code::success;
}
Expand All @@ -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<const uint8_t*>(points.data() + i*144), 144}, false, true);
std::optional<bls12_381::g1> p = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(points.data() + i*144), 144}, false, true);
if(!p.has_value())
return return_code::failure;
std::array<uint64_t, 4> s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast<const uint8_t*>(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<uint8_t*>(result.data()), 144}, true);
return return_code::success;
}
Expand All @@ -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<const uint8_t*>(points.data() + i*288), 288}, false, true);
std::optional<bls12_381::g2> p = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(points.data() + i*288), 288}, false, true);
if(!p.has_value())
return return_code::failure;
std::array<uint64_t, 4> s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast<const uint8_t*>(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<uint8_t*>(result.data()), 288}, true);
return return_code::success;
}
Expand All @@ -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<const uint8_t*>(g1_points.data() + i*144), 144}, false, true);
bls12_381::g2 p_g2 = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(g2_points.data() + i*288), 288}, false, true);
bls12_381::pairing::add_pair(v, p_g1, p_g2);
std::optional<bls12_381::g1> p_g1 = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(g1_points.data() + i*144), 144}, true, true);
std::optional<bls12_381::g2> p_g2 = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast<const uint8_t*>(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();
}
Expand All @@ -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<const uint8_t*>(e.data()), 48}, false, true);
bls12_381::g1 c = bls12_381::g1::mapToCurve(a);
std::optional<bls12_381::fp> a = bls12_381::fp::fromBytesLE({reinterpret_cast<const uint8_t*>(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<uint8_t*>(result.data()), 144}, true);
return return_code::success;
}
Expand All @@ -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<const uint8_t*>(e.data()), 96}, false, true);
bls12_381::g2 c = bls12_381::g2::mapToCurve(a);
std::optional<bls12_381::fp2> a = bls12_381::fp2::fromBytesLE({reinterpret_cast<const uint8_t*>(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<uint8_t*>(result.data()), 288}, true);
return return_code::success;
}
Expand Down
4 changes: 2 additions & 2 deletions libraries/libfc/test/crypto/test_bls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit 0d3203b

Please sign in to comment.