From 3588c2c3c781781581d7cf516d7e5b5b11ad1464 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 5 Dec 2023 13:46:32 -0600 Subject: [PATCH] GH-215 Add a bls_signature_verify method --- .../eosiolib/core/eosio/crypto_bls_ext.hpp | 28 +++++++++++++++---- .../test_contracts/bls_primitives_tests.cpp | 17 ++--------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/libraries/eosiolib/core/eosio/crypto_bls_ext.hpp b/libraries/eosiolib/core/eosio/crypto_bls_ext.hpp index 1e73f5386..b5f5d9bb1 100644 --- a/libraries/eosiolib/core/eosio/crypto_bls_ext.hpp +++ b/libraries/eosiolib/core/eosio/crypto_bls_ext.hpp @@ -371,7 +371,8 @@ namespace detail { return ret; } - const inline std::string POP_CIPHERSUITE_ID = "BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"; + const inline std::string CIPHERSUITE_ID = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"; // basic DST + const inline std::string POP_CIPHERSUITE_ID = "BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"; // proof of possession DST // g1::one().negate().toAffineBytesLE(), 96 bytes const inline std::vector G1_ONE_NEG = {0xbb, 0xc6, 0x22, 0xdb, 0xa, 0xf0, 0x3a, 0xfb, 0xef, 0x1a, 0x7a, 0xf9, @@ -490,16 +491,33 @@ namespace detail { bls_g1 g1_points[2] = {0}; bls_g2 g2_points[2] = {0}; - memcpy(g1_points[0].data(), G1_ONE_NEG.data(), G1_ONE_NEG.size()); - memcpy(g2_points[0].data(), signature_proof.data(), signature_proof.size()); + std::memcpy(g1_points[0].data(), G1_ONE_NEG.data(), G1_ONE_NEG.size()); + std::memcpy(g2_points[0].data(), signature_proof.data(), signature_proof.size()); - memcpy(g1_points[1].data(), pubkey.data(), pubkey.size()); + std::memcpy(g1_points[1].data(), pubkey.data(), pubkey.size()); g2_fromMessage(pubkey, POP_CIPHERSUITE_ID, g2_points[1]); bls_gt r; bls_pairing(g1_points, g2_points, 2, r); - return 0 == std::memcmp(r.data(), GT_ONE.data(), sizeof(bls_gt)); + return 0 == std::memcmp(r.data(), GT_ONE.data(), GT_ONE.size()); + } + + // pubkey and signature are assumed to be in RAW affine little-endian bytes + bool bls_signature_verify(const bls_g1& pubkey, const bls_g2& signature_proof, const std::string& msg) { + bls_g1 g1_points[2]; + bls_g2 g2_points[2]; + + std::memcpy(g1_points[0].data(), detail::G1_ONE_NEG.data(), detail::G1_ONE_NEG.size()); + std::memcpy(g2_points[0].data(), signature_proof.data(), signature_proof.size()); + + std::memcpy(g1_points[1].data(), pubkey.data(), pubkey.size()); + detail::g2_fromMessage(msg, detail::CIPHERSUITE_ID, g2_points[1]); + + bls_gt r; + bls_pairing(g1_points, g2_points, 2, r); + + return 0 == std::memcmp(r.data(), detail::GT_ONE.data(), detail::GT_ONE.size()); } } diff --git a/tests/unit/test_contracts/bls_primitives_tests.cpp b/tests/unit/test_contracts/bls_primitives_tests.cpp index eb350a76f..1f0e4e7a3 100644 --- a/tests/unit/test_contracts/bls_primitives_tests.cpp +++ b/tests/unit/test_contracts/bls_primitives_tests.cpp @@ -131,7 +131,6 @@ class [[eosio::contract]] bls_primitives_tests : public contract{ check(decode_bls_signature_to_g2(base64) == *reinterpret_cast(g2.data()), "base64 to g2 decoding doesn't match" ); } - const std::string CIPHERSUITE_ID = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"; // caller of verify() must use this msg std::vector msg = {51, 23, 56, 93, 212, 129, 128, 27, 251, 12, 42, 129, 210, 9, 34, 98}; @@ -139,20 +138,10 @@ class [[eosio::contract]] bls_primitives_tests : public contract{ void verify(const std::vector& pk, const std::vector& sig) { check(pk.size() == std::tuple_size::value, "wrong pk size passed"); check(sig.size() == std::tuple_size::value, "wrong sig size passed"); - bls_g1 g1_points[2]; - bls_g2 g2_points[2]; - memcpy(g1_points[0].data(), detail::G1_ONE_NEG.data(), sizeof(bls_g1)); - memcpy(g2_points[0].data(), sig.data(), sizeof(bls_g2)); - - bls_g2 p_msg; - detail::g2_fromMessage(std::span(reinterpret_cast(msg.data()), msg.size()), CIPHERSUITE_ID, p_msg); - memcpy(g1_points[1].data(), pk.data(), sizeof(bls_g1)); - memcpy(g2_points[1].data(), p_msg.data(), sizeof(bls_g2)); - - bls_gt r; - bls_pairing(g1_points, g2_points, 2, r); - check(0 == memcmp(r.data(), detail::GT_ONE.data(), sizeof(bls_gt)), "bls signature verify failed"); + std::string msg_str; + std::copy(msg.begin(), msg.end(), std::back_inserter(msg_str)); + check(bls_signature_verify(*reinterpret_cast(pk.data()), *reinterpret_cast(sig.data()), msg_str), "raw pop verify failed"); } };