From 716e72902ef5d1badd9b15159d7ff5070c8a95c4 Mon Sep 17 00:00:00 2001 From: Lu Yufei Date: Wed, 27 Dec 2023 12:54:46 +0800 Subject: [PATCH] repo-sync-2023-12-27T12:20:50+0800 (#178) * repo-sync-2023-12-27T12:20:50+0800 * Update tommath_ext_types.h --- bazel/repositories.bzl | 14 +- yacl/crypto/base/BUILD.bazel | 1 + yacl/crypto/base/aead/BUILD.bazel | 2 + yacl/crypto/base/aead/gcm_crypto.cc | 43 +- yacl/crypto/base/aead/gcm_crypto.h | 8 +- yacl/crypto/base/aead/gcm_crypto_test.cc | 2 +- yacl/crypto/base/aead/sm4_mac.cc | 3 - yacl/crypto/base/aead/sm4_mac.h | 9 + yacl/crypto/base/aes/BUILD.bazel | 5 +- yacl/crypto/base/aes/aes_intrinsics.h | 3 + yacl/crypto/base/block_cipher/BUILD.bazel | 2 +- .../base/block_cipher/symmetric_crypto.cc | 14 +- .../base/block_cipher/symmetric_crypto.h | 6 +- yacl/crypto/base/ecc/BUILD.bazel | 27 -- yacl/crypto/base/ecc/curve_meta.cc | 2 +- yacl/crypto/base/ecc/curve_meta.h | 2 +- yacl/crypto/base/ecc/mcl/BUILD.bazel | 45 +-- yacl/crypto/base/ecc/mcl/mcl_ec_group.cc | 2 +- yacl/crypto/base/ecc/mcl/mcl_util.h | 2 +- .../base/ecc/openssl/openssl_factory.cc | 2 +- yacl/crypto/base/ecc/openssl/openssl_group.cc | 124 +++--- yacl/crypto/base/ecc/openssl/openssl_group.h | 16 +- yacl/crypto/base/ecc/openssl/openssl_test.cc | 2 +- yacl/crypto/base/envelope/BUILD.bazel | 4 +- yacl/crypto/base/envelope/digital_envelope.cc | 27 +- yacl/crypto/base/envelope/digital_envelope.h | 12 +- yacl/crypto/base/field/field_spi.h | 101 ----- yacl/crypto/base/field/mcl/mcl_field.cc | 316 --------------- yacl/crypto/base/field/mcl/mcl_field.h | 142 ------- yacl/crypto/base/field/mcl/mcl_field_test.cc | 191 --------- yacl/crypto/base/hash/BUILD.bazel | 1 + yacl/crypto/base/hash/blake3.h | 2 + yacl/crypto/base/hash/hash_interface.h | 10 +- yacl/crypto/base/hash/ssl_hash.cc | 30 +- yacl/crypto/base/hash/ssl_hash.h | 2 +- yacl/crypto/base/hash/ssl_hash_all_test.cc | 2 +- yacl/crypto/base/hmac/hmac.cc | 15 +- yacl/crypto/base/hmac/hmac.h | 4 +- yacl/crypto/base/hmac/hmac_all_test.cc | 23 +- yacl/crypto/base/key_utils.cc | 66 +-- yacl/crypto/base/key_utils.h | 4 + yacl/crypto/base/openssl_wrappers.h | 15 +- .../base/{field => pairing}/BUILD.bazel | 28 +- yacl/crypto/base/pairing/mcl/BUILD.bazel | 64 +++ .../mcl/mcl_pairing_bls12_381.cc | 37 +- .../mcl/mcl_pairing_bls12_381.h | 30 +- .../mcl/mcl_pairing_factory.cc | 10 +- .../{ecc => pairing}/mcl/mcl_pairing_group.cc | 33 +- .../{ecc => pairing}/mcl/mcl_pairing_group.h | 35 +- .../{ecc => pairing}/mcl/mcl_pairing_test.cc | 24 +- .../{ecc => pairing}/mcl/pairing_header.h | 0 .../base/{ecc => pairing}/pairing_spi.cc | 16 +- .../base/{ecc => pairing}/pairing_spi.h | 39 +- .../base/{ecc => pairing}/pairing_test.cc | 33 +- yacl/crypto/base/pke/BUILD.bazel | 6 +- yacl/crypto/base/pke/asymmetric_rsa_crypto.cc | 26 +- yacl/crypto/base/pke/asymmetric_rsa_crypto.h | 6 + .../base/pke/asymmetric_rsa_crypto_test.cc | 2 + yacl/crypto/base/pke/asymmetric_sm2_crypto.cc | 28 +- yacl/crypto/base/pke/asymmetric_sm2_crypto.h | 6 + .../base/pke/asymmetric_sm2_crypto_test.cc | 2 + yacl/crypto/base/sign/BUILD.bazel | 4 +- yacl/crypto/base/sign/rsa_signing.cc | 22 +- yacl/crypto/base/sign/rsa_signing.h | 10 + yacl/crypto/base/sign/rsa_signing_test.cc | 2 + yacl/crypto/base/sign/signing.h | 4 - yacl/crypto/base/sign/sm2_signing.cc | 26 +- yacl/crypto/base/sign/sm2_signing.h | 14 +- yacl/crypto/base/sign/sm2_signing_test.cc | 2 + .../{provider => ossl-provider}/BUILD.bazel | 0 .../{provider => ossl-provider}/helper.h | 2 +- .../linux_exported_syms.lds | 0 .../macos_exported_syms.lds | 0 .../{provider => ossl-provider}/provider.cc | 4 +- .../provider_test.cc | 2 +- .../{provider => ossl-provider}/rand_impl.h | 0 .../{provider => ossl-provider}/version.h | 0 yacl/crypto/primitives/dpf/dpf.cc | 11 +- yacl/crypto/primitives/dpf/dpf.h | 18 +- yacl/crypto/primitives/ot/BUILD.bazel | 10 +- yacl/crypto/primitives/ot/base_ot.cc | 6 - yacl/crypto/primitives/ot/base_ot.h | 10 +- yacl/crypto/primitives/ot/benchmark.h | 2 + yacl/crypto/primitives/ot/ferret_ote.cc | 6 - yacl/crypto/primitives/ot/ferret_ote.h | 10 + yacl/crypto/primitives/ot/ferret_ote_rn.h | 21 +- yacl/crypto/primitives/ot/ferret_ote_un.h | 33 +- yacl/crypto/primitives/ot/gywz_ote.cc | 4 - yacl/crypto/primitives/ot/gywz_ote.h | 10 +- yacl/crypto/primitives/ot/iknp_ote.cc | 4 - yacl/crypto/primitives/ot/iknp_ote.h | 8 +- yacl/crypto/primitives/ot/kkrt_ote.cc | 16 +- yacl/crypto/primitives/ot/kkrt_ote.h | 11 +- yacl/crypto/primitives/ot/kos_ote.cc | 9 +- yacl/crypto/primitives/ot/kos_ote.h | 7 + .../primitives/ot/portable_ot_interface.h | 6 + yacl/crypto/primitives/ot/sgrr_ote.cc | 6 - yacl/crypto/primitives/ot/sgrr_ote.h | 10 +- yacl/crypto/primitives/ot/softspoken_ote.cc | 20 +- yacl/crypto/primitives/ot/softspoken_ote.h | 40 +- .../primitives/ot/x86_asm_ot_interface.h | 6 + yacl/crypto/primitives/vole/f2k/base_vole.h | 7 +- .../crypto/primitives/vole/f2k/silent_vole.cc | 24 +- yacl/crypto/primitives/vole/f2k/silent_vole.h | 24 +- .../crypto/primitives/vole/f2k/sparse_vole.cc | 6 - yacl/crypto/primitives/vole/f2k/sparse_vole.h | 13 +- yacl/crypto/tools/crhash.cc | 2 - yacl/crypto/tools/crhash.h | 3 + yacl/crypto/tools/prg.h | 5 +- yacl/crypto/tools/ro.h | 2 + yacl/crypto/tools/ro_test.cc | 8 +- yacl/crypto/tools/rp.cc | 2 - yacl/crypto/tools/rp.h | 6 +- yacl/crypto/utils/drbg/BUILD.bazel | 8 +- yacl/crypto/utils/drbg/openssl_factory.cc | 4 +- yacl/crypto/utils/rand.cc | 4 +- yacl/crypto/utils/secparam.h | 21 +- yacl/math/galois_field/gf_configs.h | 6 +- yacl/math/galois_field/gf_spi.cc | 2 + yacl/math/galois_field/gf_spi.h | 25 +- .../galois_field/mcl_field}/BUILD.bazel | 19 +- yacl/math/galois_field/mcl_field/mcl_field.cc | 377 ++++++++++++++++++ yacl/math/galois_field/mcl_field/mcl_field.h | 130 ++++++ .../galois_field/mcl_field/mcl_field_test.cc | 265 ++++++++++++ .../galois_field/mpint_field/mpint_field.cc | 6 +- .../galois_field/mpint_field/mpint_field.h | 4 +- .../mpint_field/mpint_field_test.cc | 15 +- yacl/math/mpint/tommath_ext_types.h | 2 +- yacl/utils/spi/item.h | 3 +- 129 files changed, 1653 insertions(+), 1444 deletions(-) delete mode 100644 yacl/crypto/base/field/field_spi.h delete mode 100644 yacl/crypto/base/field/mcl/mcl_field.cc delete mode 100644 yacl/crypto/base/field/mcl/mcl_field.h delete mode 100644 yacl/crypto/base/field/mcl/mcl_field_test.cc rename yacl/crypto/base/{field => pairing}/BUILD.bazel (60%) create mode 100644 yacl/crypto/base/pairing/mcl/BUILD.bazel rename yacl/crypto/base/{ecc => pairing}/mcl/mcl_pairing_bls12_381.cc (58%) rename yacl/crypto/base/{ecc => pairing}/mcl/mcl_pairing_bls12_381.h (64%) rename yacl/crypto/base/{ecc => pairing}/mcl/mcl_pairing_factory.cc (95%) rename yacl/crypto/base/{ecc => pairing}/mcl/mcl_pairing_group.cc (73%) rename yacl/crypto/base/{ecc => pairing}/mcl/mcl_pairing_group.h (79%) rename yacl/crypto/base/{ecc => pairing}/mcl/mcl_pairing_test.cc (86%) rename yacl/crypto/base/{ecc => pairing}/mcl/pairing_header.h (100%) rename yacl/crypto/base/{ecc => pairing}/pairing_spi.cc (58%) rename yacl/crypto/base/{ecc => pairing}/pairing_spi.h (65%) rename yacl/crypto/base/{ecc => pairing}/pairing_test.cc (92%) rename yacl/crypto/{provider => ossl-provider}/BUILD.bazel (100%) rename yacl/crypto/{provider => ossl-provider}/helper.h (96%) rename yacl/crypto/{provider => ossl-provider}/linux_exported_syms.lds (100%) rename yacl/crypto/{provider => ossl-provider}/macos_exported_syms.lds (100%) rename yacl/crypto/{provider => ossl-provider}/provider.cc (97%) rename yacl/crypto/{provider => ossl-provider}/provider_test.cc (99%) rename yacl/crypto/{provider => ossl-provider}/rand_impl.h (100%) rename yacl/crypto/{provider => ossl-provider}/version.h (100%) rename yacl/{crypto/base/field/mcl => math/galois_field/mcl_field}/BUILD.bazel (68%) create mode 100644 yacl/math/galois_field/mcl_field/mcl_field.cc create mode 100644 yacl/math/galois_field/mcl_field/mcl_field.h create mode 100644 yacl/math/galois_field/mcl_field/mcl_field_test.cc diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index 7949ec41..0fed20f0 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -18,11 +18,12 @@ load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") SECRETFLOW_GIT = "https://github.com/secretflow" -IC_COMMIT_ID = "b4a657d5ac39fe584dbccb7808fcbc8897ed2077" +IC_COMMIT_ID = "e9a64bfe1ae57f358b41790a1bdd82c390dd50da" SIMPLEST_OT_COMMIT_ID = "4e39b7c35721c7fd968da6e047f59c0ac92e8088" def yacl_deps(): + _rule_proto() _rule_python() _rules_foreign_cc() _com_github_madler_zlib() @@ -232,6 +233,17 @@ def _com_github_blake3team_blake3(): ], ) +def _rule_proto(): + maybe( + http_archive, + name = "rules_proto", + sha256 = "dc3fb206a2cb3441b485eb1e423165b231235a1ea9b031b4433cf7bc1fa460dd", + strip_prefix = "rules_proto-5.3.0-21.7", + urls = [ + "https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz", + ], + ) + # Required by protobuf def _rule_python(): maybe( diff --git a/yacl/crypto/base/BUILD.bazel b/yacl/crypto/base/BUILD.bazel index c66de404..f15ea987 100644 --- a/yacl/crypto/base/BUILD.bazel +++ b/yacl/crypto/base/BUILD.bazel @@ -39,6 +39,7 @@ yacl_cc_library( ], deps = [ ":openssl_wrappers", + "//yacl/crypto/utils:secparam", "//yacl/io/stream", ], ) diff --git a/yacl/crypto/base/aead/BUILD.bazel b/yacl/crypto/base/aead/BUILD.bazel index b7c21a0b..c736b531 100644 --- a/yacl/crypto/base/aead/BUILD.bazel +++ b/yacl/crypto/base/aead/BUILD.bazel @@ -23,6 +23,7 @@ yacl_cc_library( deps = [ "//yacl/base:int128", "//yacl/crypto/base:key_utils", + "//yacl/crypto/utils:secparam", ], ) @@ -42,6 +43,7 @@ yacl_cc_library( "//yacl/crypto/base/block_cipher:symmetric_crypto", "//yacl/crypto/base/hash:ssl_hash", "//yacl/crypto/base/hmac:hmac_sm3", + "//yacl/crypto/utils:secparam", ], ) diff --git a/yacl/crypto/base/aead/gcm_crypto.cc b/yacl/crypto/base/aead/gcm_crypto.cc index 4221c2f7..c183879e 100644 --- a/yacl/crypto/base/aead/gcm_crypto.cc +++ b/yacl/crypto/base/aead/gcm_crypto.cc @@ -47,29 +47,29 @@ void GcmCrypto::Encrypt(ByteContainerView plaintext, ByteContainerView aad, YACL_ENFORCE(ctx != nullptr, "Failed to new evp cipher context."); const auto cipher = openssl::FetchEvpCipher(ToString(schema_)); YACL_ENFORCE(cipher != nullptr); - YACL_ENFORCE(key_.size() == (size_t)EVP_CIPHER_key_length(cipher.get())); YACL_ENFORCE(iv_.size() == (size_t)EVP_CIPHER_iv_length(cipher.get())); - YACL_ENFORCE(EVP_EncryptInit_ex(ctx.get(), cipher.get(), nullptr, key_.data(), - iv_.data()) > 0); + + OSSL_RET_1(EVP_EncryptInit_ex(ctx.get(), cipher.get(), nullptr, key_.data(), + iv_.data())); // Provide AAD data if exist int out_length = 0; const auto aad_len = aad.size(); if (aad_len > 0) { - YACL_ENFORCE(EVP_EncryptUpdate(ctx.get(), nullptr, &out_length, aad.data(), - aad_len) > 0); + OSSL_RET_1(EVP_EncryptUpdate(ctx.get(), nullptr, &out_length, aad.data(), + aad_len)); YACL_ENFORCE(out_length == (int)aad.size()); } - YACL_ENFORCE(EVP_EncryptUpdate(ctx.get(), ciphertext.data(), &out_length, - plaintext.data(), plaintext.size()) > 0); + OSSL_RET_1(EVP_EncryptUpdate(ctx.get(), ciphertext.data(), &out_length, + plaintext.data(), plaintext.size())); YACL_ENFORCE(out_length == (int)plaintext.size(), "Unexpected encrypte out length."); // Note that get no output here as the data is always aligned for GCM. EVP_EncryptFinal_ex(ctx.get(), nullptr, &out_length); - YACL_ENFORCE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, - GetMacSize(schema_), mac.data()) > 0); + OSSL_RET_1(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, + GetMacSize(schema_), mac.data())); } void GcmCrypto::Decrypt(ByteContainerView ciphertext, ByteContainerView aad, @@ -79,32 +79,33 @@ void GcmCrypto::Decrypt(ByteContainerView ciphertext, ByteContainerView aad, YACL_ENFORCE_EQ(mac.size(), GetMacSize(schema_)); // init openssl evp cipher context - EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); - YACL_ENFORCE(ctx, "Failed to new evp cipher context."); - ON_SCOPE_EXIT([&] { EVP_CIPHER_CTX_free(ctx); }); + auto ctx = openssl::UniqueCipherCtx(EVP_CIPHER_CTX_new()); + + YACL_ENFORCE(ctx.get(), "Failed to new evp cipher context."); + const auto cipher = openssl::FetchEvpCipher(ToString(schema_)); YACL_ENFORCE_EQ(key_.size(), (size_t)EVP_CIPHER_key_length(cipher.get())); YACL_ENFORCE_EQ(iv_.size(), (size_t)EVP_CIPHER_iv_length(cipher.get())); - YACL_ENFORCE( - EVP_DecryptInit_ex(ctx, cipher.get(), nullptr, key_.data(), iv_.data())); + YACL_ENFORCE(EVP_DecryptInit_ex(ctx.get(), cipher.get(), nullptr, key_.data(), + iv_.data())); // Provide AAD data if exist int out_length = 0; const auto aad_len = aad.size(); if (aad_len > 0) { - YACL_ENFORCE( - EVP_DecryptUpdate(ctx, nullptr, &out_length, aad.data(), aad_len) > 0); + OSSL_RET_1(EVP_DecryptUpdate(ctx.get(), nullptr, &out_length, aad.data(), + aad_len)); YACL_ENFORCE(out_length == (int)aad.size()); } - YACL_ENFORCE(EVP_DecryptUpdate(ctx, plaintext.data(), &out_length, - ciphertext.data(), ciphertext.size()) > 0); + OSSL_RET_1(EVP_DecryptUpdate(ctx.get(), plaintext.data(), &out_length, + ciphertext.data(), ciphertext.size())); YACL_ENFORCE(out_length == (int)plaintext.size(), "Unexpcted decryption out length."); - YACL_ENFORCE(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, - GetMacSize(schema_), (void*)mac.data()) > 0); + OSSL_RET_1(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, + GetMacSize(schema_), (void*)mac.data())); // Note that get no output here as the data is always aligned for GCM. - YACL_ENFORCE(EVP_DecryptFinal_ex(ctx, nullptr, &out_length) > 0, + YACL_ENFORCE(EVP_DecryptFinal_ex(ctx.get(), nullptr, &out_length) > 0, "Failed to verfiy mac."); } diff --git a/yacl/crypto/base/aead/gcm_crypto.h b/yacl/crypto/base/aead/gcm_crypto.h index cf895534..61cc8edf 100644 --- a/yacl/crypto/base/aead/gcm_crypto.h +++ b/yacl/crypto/base/aead/gcm_crypto.h @@ -19,12 +19,16 @@ #include "absl/types/span.h" #include "yacl/base/byte_container_view.h" +#include "yacl/crypto/utils/secparam.h" + +/* security parameter declaration */ +YACL_MODULE_DECLARE("aes_gcm", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { enum class GcmCryptoSchema : int { - AES128_GCM, - AES256_GCM, + AES128_GCM, /* security level = 128 */ + AES256_GCM, /* security level = 256 */ // SM4_GCM /* TODO openssl 3.2 supports SM4 GCM */ }; diff --git a/yacl/crypto/base/aead/gcm_crypto_test.cc b/yacl/crypto/base/aead/gcm_crypto_test.cc index 5062ed91..f4247ec5 100644 --- a/yacl/crypto/base/aead/gcm_crypto_test.cc +++ b/yacl/crypto/base/aead/gcm_crypto_test.cc @@ -15,9 +15,9 @@ #include "yacl/crypto/base/aead/gcm_crypto.h" #include +#include #include "gtest/gtest.h" -#include "openssl/evp.h" #include "yacl/base/exception.h" diff --git a/yacl/crypto/base/aead/sm4_mac.cc b/yacl/crypto/base/aead/sm4_mac.cc index 21ac01c3..e170f211 100644 --- a/yacl/crypto/base/aead/sm4_mac.cc +++ b/yacl/crypto/base/aead/sm4_mac.cc @@ -15,9 +15,6 @@ #include "yacl/crypto/base/aead/sm4_mac.h" #include "yacl/base/exception.h" -#include "yacl/crypto/base/block_cipher/symmetric_crypto.h" -#include "yacl/crypto/base/hash/ssl_hash.h" -#include "yacl/crypto/base/hmac/hmac_sm3.h" namespace yacl::crypto { diff --git a/yacl/crypto/base/aead/sm4_mac.h b/yacl/crypto/base/aead/sm4_mac.h index a27163c7..f0fffd25 100644 --- a/yacl/crypto/base/aead/sm4_mac.h +++ b/yacl/crypto/base/aead/sm4_mac.h @@ -17,6 +17,15 @@ #include #include "yacl/base/byte_container_view.h" +#include "yacl/crypto/utils/secparam.h" + +/* submodules */ +#include "yacl/crypto/base/block_cipher/symmetric_crypto.h" +#include "yacl/crypto/base/hash/ssl_hash.h" +#include "yacl/crypto/base/hmac/hmac_sm3.h" + +/* security parameter declaration */ +YACL_MODULE_DECLARE("sm4_mac", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/base/aes/BUILD.bazel b/yacl/crypto/base/aes/BUILD.bazel index 81327008..2b262a5e 100644 --- a/yacl/crypto/base/aes/BUILD.bazel +++ b/yacl/crypto/base/aes/BUILD.bazel @@ -34,7 +34,10 @@ yacl_cc_library( "aes_intrinsics.h", ], copts = AES_COPT_FLAGS, - deps = ["//yacl/base:int128"] + select({ + deps = [ + "//yacl/base:int128", + "//yacl/crypto/utils:secparam", + ] + select({ "@platforms//cpu:aarch64": [ "@com_github_dltcollab_sse2neon//:sse2neon", ], diff --git a/yacl/crypto/base/aes/aes_intrinsics.h b/yacl/crypto/base/aes/aes_intrinsics.h index a011739c..455a7ae7 100644 --- a/yacl/crypto/base/aes/aes_intrinsics.h +++ b/yacl/crypto/base/aes/aes_intrinsics.h @@ -56,6 +56,7 @@ #include "yacl/base/exception.h" #include "yacl/base/int128.h" +#include "yacl/crypto/utils/secparam.h" #ifndef __aarch64__ // sse @@ -67,6 +68,8 @@ #include "sse2neon.h" #endif +/* security parameter declaration */ +YACL_MODULE_DECLARE("aes_intrinsics", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { namespace internal { diff --git a/yacl/crypto/base/block_cipher/BUILD.bazel b/yacl/crypto/base/block_cipher/BUILD.bazel index ec057090..741568b6 100644 --- a/yacl/crypto/base/block_cipher/BUILD.bazel +++ b/yacl/crypto/base/block_cipher/BUILD.bazel @@ -28,7 +28,7 @@ yacl_cc_library( deps = [ "//yacl/base:int128", "//yacl/crypto/base:openssl_wrappers", - "//yacl/crypto/base/aes:aes_intrinsics", + "//yacl/crypto/utils:secparam", ], ) diff --git a/yacl/crypto/base/block_cipher/symmetric_crypto.cc b/yacl/crypto/base/block_cipher/symmetric_crypto.cc index 163a506b..7cfb0457 100644 --- a/yacl/crypto/base/block_cipher/symmetric_crypto.cc +++ b/yacl/crypto/base/block_cipher/symmetric_crypto.cc @@ -18,10 +18,6 @@ #include #include -#include "openssl/aes.h" -#include "openssl/crypto.h" -#include "openssl/err.h" -#include "openssl/evp.h" #include "spdlog/spdlog.h" #include "yacl/base/exception.h" @@ -45,20 +41,20 @@ openssl::UniqueCipherCtx CreateEVPCipherCtx(SymmetricCrypto::CryptoType type, // cbc mode need to set iv if ((type == SymmetricCrypto::CryptoType::AES128_ECB) || (type == SymmetricCrypto::CryptoType::SM4_ECB)) { - YACL_ENFORCE(EVP_CipherInit_ex(ctx.get(), cipher.get(), nullptr, key_data, - nullptr, enc)); + OSSL_RET_1(EVP_CipherInit_ex(ctx.get(), cipher.get(), nullptr, key_data, + nullptr, enc)); } else { /** * @brief cbc and ctr mode set iv * for ctr the iv is the initiator counter, most case counter set 0 */ const auto* iv_data = reinterpret_cast(&iv); - YACL_ENFORCE(EVP_CipherInit_ex(ctx.get(), cipher.get(), nullptr, key_data, - iv_data, enc)); + OSSL_RET_1(EVP_CipherInit_ex(ctx.get(), cipher.get(), nullptr, key_data, + iv_data, enc)); } // No padding needed for aligned blocks. - YACL_ENFORCE(EVP_CIPHER_CTX_set_padding(ctx.get(), 0)); + OSSL_RET_1(EVP_CIPHER_CTX_set_padding(ctx.get(), 0)); return ctx; } diff --git a/yacl/crypto/base/block_cipher/symmetric_crypto.h b/yacl/crypto/base/block_cipher/symmetric_crypto.h index afa5a19a..863852e8 100644 --- a/yacl/crypto/base/block_cipher/symmetric_crypto.h +++ b/yacl/crypto/base/block_cipher/symmetric_crypto.h @@ -22,12 +22,14 @@ #include #include "absl/types/span.h" -#include "openssl/evp.h" #include "yacl/base/byte_container_view.h" #include "yacl/base/int128.h" -#include "yacl/crypto/base/aes/aes_intrinsics.h" #include "yacl/crypto/base/openssl_wrappers.h" +#include "yacl/crypto/utils/secparam.h" + +/* security parameter declaration */ +YACL_MODULE_DECLARE("aes_all_modes", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { namespace internal { diff --git a/yacl/crypto/base/ecc/BUILD.bazel b/yacl/crypto/base/ecc/BUILD.bazel index e97cddd9..9cc97893 100644 --- a/yacl/crypto/base/ecc/BUILD.bazel +++ b/yacl/crypto/base/ecc/BUILD.bazel @@ -90,30 +90,3 @@ yacl_cc_test( "@yacl//yacl/utils:parallel", ], ) - -yacl_cc_library( - name = "pairing_spi", - srcs = ["pairing_spi.cc"], - hdrs = ["pairing_spi.h"], - deps = [ - ":spi", - "//yacl/crypto/base/field:field_spi", - "@com_google_absl//absl/strings", - ], -) - -yacl_cc_library( - name = "pairing", - deps = [ - "//yacl/crypto/base/ecc/mcl:pairing", - ], -) - -yacl_cc_test( - name = "pairing_test", - srcs = ["pairing_test.cc"], - deps = [ - ":pairing", - "@yacl//yacl/utils:parallel", - ], -) diff --git a/yacl/crypto/base/ecc/curve_meta.cc b/yacl/crypto/base/ecc/curve_meta.cc index cb2fd4df..a9ce1624 100644 --- a/yacl/crypto/base/ecc/curve_meta.cc +++ b/yacl/crypto/base/ecc/curve_meta.cc @@ -826,7 +826,7 @@ std::vector kPredefinedCurves = { CurveName CurveMeta::LowerName() const { return absl::AsciiStrToLower(name); } -bool CurveMeta::IsEquivalent(CurveMeta rhs) const { +bool CurveMeta::IsEquivalent(const CurveMeta& rhs) const { return std::tie(form, field_type, secure_bits) == std::tie(rhs.form, rhs.field_type, rhs.secure_bits); } diff --git a/yacl/crypto/base/ecc/curve_meta.h b/yacl/crypto/base/ecc/curve_meta.h index a423f96c..876d82fe 100644 --- a/yacl/crypto/base/ecc/curve_meta.h +++ b/yacl/crypto/base/ecc/curve_meta.h @@ -68,7 +68,7 @@ struct CurveMeta { size_t secure_bits; CurveName LowerName() const; - bool IsEquivalent(CurveMeta rhs) const; + bool IsEquivalent(const CurveMeta& rhs) const; }; CurveMeta GetCurveMetaByName(const CurveName& name); diff --git a/yacl/crypto/base/ecc/mcl/BUILD.bazel b/yacl/crypto/base/ecc/mcl/BUILD.bazel index 587d3564..3ff1d7e8 100644 --- a/yacl/crypto/base/ecc/mcl/BUILD.bazel +++ b/yacl/crypto/base/ecc/mcl/BUILD.bazel @@ -24,11 +24,11 @@ yacl_cc_library( ], hdrs = ["mcl_ec_group.h"], deps = [ - ":pairing_header", ":util", "//yacl/crypto/base/ecc:spi", "//yacl/crypto/base/hash:blake3", "//yacl/crypto/base/hash:ssl_hash", + "//yacl/crypto/base/pairing/mcl:pairing_header", ], alwayslink = 1, ) @@ -41,49 +41,6 @@ yacl_cc_test( ], ) -yacl_cc_library( - name = "pairing_header", - hdrs = ["pairing_header.h"], - copts = [ - ], - defines = [ - # Macro `MCL_ALL_PAIRING_FOR_YACL` enables libmcl's all pairing curves - # and not that they are not standard pairing instances. - # !Only for test and don't recommmand! - # "MCL_ALL_PAIRING_FOR_YACL", - ], - deps = ["@com_github_herumi_mcl//:mcl"], -) - -yacl_cc_library( - name = "pairing", - srcs = [ - "mcl_pairing_bls12_381.cc", - "mcl_pairing_bls12_381.h", - "mcl_pairing_factory.cc", - "mcl_pairing_group.cc", - ], - hdrs = [ - "mcl_pairing_group.h", - ], - deps = [ - ":ecc", - ":pairing_header", - "//yacl/crypto/base/ecc:pairing_spi", - "//yacl/crypto/base/field/mcl:field", - ], - alwayslink = 1, -) - -yacl_cc_test( - name = "pairing_test", - srcs = ["mcl_pairing_test.cc"], - deps = [ - ":pairing", - "//yacl/crypto/utils:rand", - ], -) - yacl_cc_library( name = "util", srcs = [ diff --git a/yacl/crypto/base/ecc/mcl/mcl_ec_group.cc b/yacl/crypto/base/ecc/mcl/mcl_ec_group.cc index 2fe3b9e3..7fa2d129 100644 --- a/yacl/crypto/base/ecc/mcl/mcl_ec_group.cc +++ b/yacl/crypto/base/ecc/mcl/mcl_ec_group.cc @@ -15,8 +15,8 @@ #include "yacl/crypto/base/ecc/mcl/mcl_ec_group.h" #include "yacl/crypto/base/ecc/mcl/mcl_util.h" -#include "yacl/crypto/base/ecc/mcl/pairing_header.h" #include "yacl/crypto/base/hash/blake3.h" +#include "yacl/crypto/base/pairing/mcl/pairing_header.h" namespace yacl::crypto::hmcl { diff --git a/yacl/crypto/base/ecc/mcl/mcl_util.h b/yacl/crypto/base/ecc/mcl/mcl_util.h index fa26f14d..5a234f2e 100644 --- a/yacl/crypto/base/ecc/mcl/mcl_util.h +++ b/yacl/crypto/base/ecc/mcl/mcl_util.h @@ -25,4 +25,4 @@ using yacl::math::MPInt; MPInt Mpz2Mp(const mpz_class& m); mpz_class Mp2Mpz(const MPInt& mpi); -} // namespace yacl::crypto::hmcl \ No newline at end of file +} // namespace yacl::crypto::hmcl diff --git a/yacl/crypto/base/ecc/openssl/openssl_factory.cc b/yacl/crypto/base/ecc/openssl/openssl_factory.cc index e916c0f6..8b0375d8 100644 --- a/yacl/crypto/base/ecc/openssl/openssl_factory.cc +++ b/yacl/crypto/base/ecc/openssl/openssl_factory.cc @@ -147,7 +147,7 @@ std::unique_ptr OpensslGroup::Create(const CurveMeta &meta) { gptr != nullptr, "Openssl create curve group {} fail, nid={}, err code maybe={} (guessed)", meta.LowerName(), kName2Nid.at(meta.LowerName()), ERR_get_error()); - return std::unique_ptr(new OpensslGroup(meta, EC_GROUP_PTR(gptr))); + return std::unique_ptr(new OpensslGroup(meta, UniqueEcGroup(gptr))); } bool OpensslGroup::IsSupported(const CurveMeta &meta) { diff --git a/yacl/crypto/base/ecc/openssl/openssl_group.cc b/yacl/crypto/base/ecc/openssl/openssl_group.cc index 59e38a66..0957b6af 100644 --- a/yacl/crypto/base/ecc/openssl/openssl_group.cc +++ b/yacl/crypto/base/ecc/openssl/openssl_group.cc @@ -14,8 +14,11 @@ #include "yacl/crypto/base/ecc/openssl/openssl_group.h" +#include + #include "yacl/crypto/base/hash/blake3.h" #include "yacl/crypto/base/hash/ssl_hash.h" +#include "yacl/crypto/base/openssl_wrappers.h" #include "yacl/utils/scope_guard.h" #include "yacl/utils/spi/type_traits.h" @@ -23,26 +26,20 @@ namespace yacl::crypto::openssl { static constexpr size_t kHashToCurveCounterGuard = 100; -thread_local BN_CTX_PTR OpensslGroup::ctx_ = BN_CTX_PTR(BN_CTX_new()); - -//--- helper tools ---// - -#define SSL_RET_1(MP_ERR, ...) YACL_ENFORCE_EQ((MP_ERR), 1, __VA_ARGS__) -#define SSL_RET_N(MP_ERR, ...) YACL_ENFORCE_GE((MP_ERR), 0, __VA_ARGS__) -#define SSL_RET_ZP(MP_ERR, ...) YACL_ENFORCE_GT((MP_ERR), 0, __VA_ARGS__) +thread_local UniqueBnCtx OpensslGroup::ctx_ = UniqueBnCtx(BN_CTX_new()); -BIGNUM_PTR Mp2Bn(const MPInt &mp) { +UniqueBn Mp2Bn(const MPInt &mp) { bool is_neg = mp.IsNegative(); - BIGNUM_PTR res; + UniqueBn res; if (mp.BitCount() <= sizeof(BN_ULONG) * CHAR_BIT) { - res = BIGNUM_PTR(BN_new()); - SSL_RET_1(BN_set_word(res.get(), mp.Get())); + res = UniqueBn(BN_new()); + OSSL_RET_1(BN_set_word(res.get(), mp.Get())); } else { constexpr int MAX_NUM_BYTE = 1024; unsigned char buf[MAX_NUM_BYTE]; auto buf_len = mp.ToMagBytes(buf, MAX_NUM_BYTE, Endian::little); - res = BIGNUM_PTR(BN_lebin2bn(buf, buf_len, nullptr)); + res = UniqueBn(BN_lebin2bn(buf, buf_len, nullptr)); } if (is_neg) { // mpp is negative @@ -56,7 +53,7 @@ MPInt Bn2Mp(const BIGNUM *bn) { CheckNotNull(bn); auto buf_len = BN_num_bytes(bn); unsigned char buf[buf_len]; - SSL_RET_N(BN_bn2lebinpad(bn, buf, buf_len)); + YACL_ENFORCE(BN_bn2lebinpad(bn, buf, buf_len) >= 0); MPInt mp; mp.FromMagBytes({buf, static_cast(buf_len)}, Endian::little); @@ -72,14 +69,14 @@ AnyPtr WrapOpensslPoint(EC_POINT *point) { [](void *p) { EC_POINT_free(reinterpret_cast(p)); }}; } -OpensslGroup::OpensslGroup(const CurveMeta &meta, EC_GROUP_PTR group) +OpensslGroup::OpensslGroup(const CurveMeta &meta, UniqueEcGroup group) : EcGroupSketch(meta), group_(std::move(group)), field_p_(BN_new()) { generator_ = WrapOpensslPoint( EC_POINT_dup(EC_GROUP_get0_generator(group_.get()), group_.get())); order_ = Bn2Mp(EC_GROUP_get0_order(group_.get())); cofactor_ = Bn2Mp(EC_GROUP_get0_cofactor(group_.get())); - SSL_RET_1(EC_GROUP_get_curve(group_.get(), field_p_.get(), nullptr, nullptr, - ctx_.get())); + OSSL_RET_1(EC_GROUP_get_curve(group_.get(), field_p_.get(), nullptr, nullptr, + ctx_.get())); } AnyPtr OpensslGroup::MakeOpensslPoint() const { @@ -98,28 +95,28 @@ std::string OpensslGroup::ToString() const { return GetCurveName(); } EcPoint OpensslGroup::Add(const EcPoint &p1, const EcPoint &p2) const { auto res = MakeOpensslPoint(); - SSL_RET_1(EC_POINT_add(group_.get(), CastAny(res), - CastAny(p1), CastAny(p2), - ctx_.get())); + OSSL_RET_1(EC_POINT_add(group_.get(), CastAny(res), + CastAny(p1), CastAny(p2), + ctx_.get())); return res; } void OpensslGroup::AddInplace(EcPoint *p1, const EcPoint &p2) const { - SSL_RET_1(EC_POINT_add(group_.get(), CastAny(p1), - CastAny(p1), CastAny(p2), - ctx_.get())); + OSSL_RET_1(EC_POINT_add(group_.get(), CastAny(p1), + CastAny(p1), CastAny(p2), + ctx_.get())); } EcPoint OpensslGroup::Double(const EcPoint &p) const { auto res = MakeOpensslPoint(); - SSL_RET_1(EC_POINT_dbl(group_.get(), CastAny(res), - CastAny(p), ctx_.get())); + OSSL_RET_1(EC_POINT_dbl(group_.get(), CastAny(res), + CastAny(p), ctx_.get())); return res; } void OpensslGroup::DoubleInplace(EcPoint *p) const { - SSL_RET_1(EC_POINT_dbl(group_.get(), CastAny(p), - CastAny(p), ctx_.get())); + OSSL_RET_1(EC_POINT_dbl(group_.get(), CastAny(p), + CastAny(p), ctx_.get())); } EcPoint OpensslGroup::MulBase(const MPInt &scalar) const { @@ -128,23 +125,23 @@ EcPoint OpensslGroup::MulBase(const MPInt &scalar) const { // EC_POINT_mul has random memory leaks, be careful. // See UT for demo code. // We tested openssl 3.1.0, it still leaks. - SSL_RET_1(EC_POINT_mul(group_.get(), CastAny(res), s.get(), nullptr, - nullptr, ctx_.get())); + OSSL_RET_1(EC_POINT_mul(group_.get(), CastAny(res), s.get(), + nullptr, nullptr, ctx_.get())); return res; } EcPoint OpensslGroup::Mul(const EcPoint &point, const MPInt &scalar) const { auto res = MakeOpensslPoint(); auto s = Mp2Bn(scalar); - SSL_RET_1(EC_POINT_mul(group_.get(), CastAny(res), nullptr, - CastAny(point), s.get(), ctx_.get())); + OSSL_RET_1(EC_POINT_mul(group_.get(), CastAny(res), nullptr, + CastAny(point), s.get(), ctx_.get())); return res; } void OpensslGroup::MulInplace(EcPoint *point, const MPInt &scalar) const { auto s = Mp2Bn(scalar); - SSL_RET_1(EC_POINT_mul(group_.get(), CastAny(point), nullptr, - CastAny(point), s.get(), ctx_.get())); + OSSL_RET_1(EC_POINT_mul(group_.get(), CastAny(point), nullptr, + CastAny(point), s.get(), ctx_.get())); } EcPoint OpensslGroup::MulDoubleBase(const MPInt &s1, const MPInt &s2, @@ -152,20 +149,20 @@ EcPoint OpensslGroup::MulDoubleBase(const MPInt &s1, const MPInt &s2, auto res = MakeOpensslPoint(); auto bn1 = Mp2Bn(s1); auto bn2 = Mp2Bn(s2); - SSL_RET_1(EC_POINT_mul(group_.get(), CastAny(res), bn1.get(), - CastAny(p2), bn2.get(), ctx_.get())); + OSSL_RET_1(EC_POINT_mul(group_.get(), CastAny(res), bn1.get(), + CastAny(p2), bn2.get(), ctx_.get())); return res; } EcPoint OpensslGroup::Negate(const EcPoint &point) const { auto res = WrapOpensslPoint(EC_POINT_dup(CastAny(point), group_.get())); - SSL_RET_1(EC_POINT_invert(group_.get(), CastAny(res), ctx_.get())); + OSSL_RET_1(EC_POINT_invert(group_.get(), CastAny(res), ctx_.get())); return res; } void OpensslGroup::NegateInplace(EcPoint *point) const { - SSL_RET_1( + OSSL_RET_1( EC_POINT_invert(group_.get(), CastAny(point), ctx_.get())); } @@ -181,7 +178,7 @@ EcPoint OpensslGroup::CopyPoint(const EcPoint &point) const { auto x = Mp2Bn(p.x); auto y = Mp2Bn(p.y); auto r = MakeOpensslPoint(); - SSL_RET_1(EC_POINT_set_affine_coordinates( + OSSL_RET_1(EC_POINT_set_affine_coordinates( group_.get(), CastAny(r), x.get(), y.get(), ctx_.get())); return r; } @@ -194,9 +191,9 @@ AffinePoint OpensslGroup::GetAffinePoint(const EcPoint &point) const { return {}; } - auto x = BIGNUM_PTR(BN_new()); - auto y = BIGNUM_PTR(BN_new()); - SSL_RET_1(EC_POINT_get_affine_coordinates( + auto x = UniqueBn(BN_new()); + auto y = UniqueBn(BN_new()); + OSSL_RET_1(EC_POINT_get_affine_coordinates( group_.get(), CastAny(point), x.get(), y.get(), ctx_.get())); return {Bn2Mp(x.get()), Bn2Mp(y.get())}; } @@ -215,9 +212,9 @@ uint64_t OpensslGroup::GetSerializeLength(PointOctetFormat format) const { break; } - int64_t len = EC_POINT_point2oct(group_.get(), CastAny(generator_), - f, nullptr, 0, ctx_.get()); - SSL_RET_ZP(len, "calc serialize point size, openssl returns 0"); + size_t len = EC_POINT_point2oct(group_.get(), CastAny(generator_), + f, nullptr, 0, ctx_.get()); + YACL_ENFORCE(len != 0, "calc serialize point size, openssl returns 0"); return len; } @@ -243,14 +240,14 @@ void OpensslGroup::SerializePoint(const EcPoint &point, PointOctetFormat format, break; } - int64_t len = EC_POINT_point2oct(group_.get(), CastAny(point), f, - nullptr, 0, ctx_.get()); - SSL_RET_ZP(len, "calc serialize point size, openssl returns 0"); + size_t len = EC_POINT_point2oct(group_.get(), CastAny(point), f, + nullptr, 0, ctx_.get()); + YACL_ENFORCE(len != 0, "calc serialize point size, openssl returns 0"); buf->resize(len); len = EC_POINT_point2oct(group_.get(), CastAny(point), f, buf->data(), len, ctx_.get()); - SSL_RET_ZP(len, "serialize point to buf fail, openssl returns 0"); + YACL_ENFORCE(len != 0, "serialize point to buf fail, openssl returns 0"); } void OpensslGroup::SerializePoint(const EcPoint &point, PointOctetFormat format, @@ -268,9 +265,9 @@ void OpensslGroup::SerializePoint(const EcPoint &point, PointOctetFormat format, break; } - int64_t len = EC_POINT_point2oct(group_.get(), CastAny(point), f, - nullptr, 0, ctx_.get()); - SSL_RET_ZP(len, "calc serialize point size, openssl returns 0"); + size_t len = EC_POINT_point2oct(group_.get(), CastAny(point), f, + nullptr, 0, ctx_.get()); + YACL_ENFORCE(len != 0, "calc serialize point size, openssl returns 0"); YACL_ENFORCE(buf_size >= static_cast(len), "buf size is small than needed {}", len); len = EC_POINT_point2oct(group_.get(), CastAny(point), f, buf, len, @@ -284,9 +281,9 @@ EcPoint OpensslGroup::DeserializePoint(ByteContainerView buf, PointOctetFormat) const { auto p = MakeOpensslPoint(); // buf[0] == 0 indicate it's a infinity point, will fail if input len != 1 - SSL_RET_1(EC_POINT_oct2point(group_.get(), CastAny(p), buf.data(), - !buf.empty() && buf[0] != 0 ? buf.length() : 1, - ctx_.get())); + OSSL_RET_1(EC_POINT_oct2point(group_.get(), CastAny(p), buf.data(), + !buf.empty() && buf[0] != 0 ? buf.length() : 1, + ctx_.get())); return p; } @@ -329,13 +326,13 @@ EcPoint OpensslGroup::HashToCurve(HashToCurveStrategy strategy, } else { buf = Blake3Hash((bits + 7) / 8).Update(str).CumulativeHash(); } - auto bn = BIGNUM_PTR(BN_new()); + auto bn = UniqueBn(BN_new()); for (size_t t = 0; t < kHashToCurveCounterGuard; ++t) { // hash value to BN YACL_ENFORCE(BN_bin2bn(buf.data(), buf.size(), bn.get()) != nullptr, "Convert hash value to bignumber fail"); - SSL_RET_1(BN_nnmod(bn.get(), bn.get(), field_p_.get(), ctx_.get()), - "hash-to-curve: bn mod p fail"); + OSSL_RET_1(BN_nnmod(bn.get(), bn.get(), field_p_.get(), ctx_.get()), + "hash-to-curve: bn mod p fail"); // check BN on the curve int ret = EC_POINT_set_compressed_coordinates( @@ -363,7 +360,8 @@ size_t HashBn(const BIGNUM *bn) { } int len = BN_num_bytes(bn); char buf[len]; - SSL_RET_ZP(BN_bn2lebinpad(bn, reinterpret_cast(buf), len)); + YACL_ENFORCE(BN_bn2lebinpad(bn, reinterpret_cast(buf), len) > + 0); return std::hash{}({buf, static_cast(len)}); } } // namespace @@ -377,11 +375,11 @@ size_t OpensslGroup::HashPoint(const EcPoint &point) const { // 1. `thread_local` variables are also static variables, we can reuse these // variables to avoid frequent memory allocation. // 2. We declare variables as thread_local to ensure thread safety - thread_local BIGNUM_PTR x(BN_new()); - thread_local BIGNUM_PTR y(BN_new()); + thread_local UniqueBn x(BN_new()); + thread_local UniqueBn y(BN_new()); // You cannot use projective coordinates here because point expression is not // unique - SSL_RET_1(EC_POINT_get_affine_coordinates( + OSSL_RET_1(EC_POINT_get_affine_coordinates( group_.get(), CastAny(point), x.get(), y.get(), ctx_.get())); return HashBn(x.get()) + BN_is_odd(y.get()); } @@ -389,14 +387,16 @@ size_t OpensslGroup::HashPoint(const EcPoint &point) const { bool OpensslGroup::PointEqual(const EcPoint &p1, const EcPoint &p2) const { auto res = EC_POINT_cmp(group_.get(), CastAny(p1), CastAny(p2), ctx_.get()); - SSL_RET_N(res); + YACL_ENFORCE(res >= 0); return res == 0; } bool OpensslGroup::IsInCurveGroup(const EcPoint &point) const { + // EC_POINT_is_on_curve returns 1 if the point is on the curve, 0 if not, or + // -1 on error. auto ret = EC_POINT_is_on_curve(group_.get(), CastAny(point), ctx_.get()); - SSL_RET_N(ret, "calc point is on curve fail, err={}", ret); + YACL_ENFORCE(ret >= 0, "calc point is on curve fail, err={}", ret); return ret == 1 || IsInfinity(point); } diff --git a/yacl/crypto/base/ecc/openssl/openssl_group.h b/yacl/crypto/base/ecc/openssl/openssl_group.h index 37b31b98..fa84e839 100644 --- a/yacl/crypto/base/ecc/openssl/openssl_group.h +++ b/yacl/crypto/base/ecc/openssl/openssl_group.h @@ -14,18 +14,14 @@ #pragma once -#include "openssl/bn.h" -#include "openssl/ec.h" +#include +#include #include "yacl/crypto/base/ecc/group_sketch.h" #include "yacl/crypto/base/openssl_wrappers.h" namespace yacl::crypto::openssl { -using EC_GROUP_PTR = internal::TyHelper; -using BN_CTX_PTR = internal::TyHelper; -using BIGNUM_PTR = internal::TyHelper; - class OpensslGroup : public EcGroupSketch { public: static std::unique_ptr Create(const CurveMeta& meta); @@ -81,18 +77,18 @@ class OpensslGroup : public EcGroupSketch { bool IsInfinity(const EcPoint& point) const override; private: - explicit OpensslGroup(const CurveMeta& meta, EC_GROUP_PTR group); + explicit OpensslGroup(const CurveMeta& meta, UniqueEcGroup group); AnyPtr MakeOpensslPoint() const; - EC_GROUP_PTR group_; - BIGNUM_PTR field_p_; + UniqueEcGroup group_; + UniqueBn field_p_; MPInt order_; MPInt cofactor_; EcPoint generator_; - static thread_local BN_CTX_PTR ctx_; + static thread_local UniqueBnCtx ctx_; }; } // namespace yacl::crypto::openssl diff --git a/yacl/crypto/base/ecc/openssl/openssl_test.cc b/yacl/crypto/base/ecc/openssl/openssl_test.cc index 1c9f236a..a1f9c02f 100644 --- a/yacl/crypto/base/ecc/openssl/openssl_test.cc +++ b/yacl/crypto/base/ecc/openssl/openssl_test.cc @@ -23,7 +23,7 @@ namespace yacl::crypto::openssl { // We only need to test these two functions, other functions will be tested by // SPI -BIGNUM_PTR Mp2Bn(const MPInt &mp); +UniqueBn Mp2Bn(const MPInt &mp); MPInt Bn2Mp(const BIGNUM *bn); } // namespace yacl::crypto::openssl diff --git a/yacl/crypto/base/envelope/BUILD.bazel b/yacl/crypto/base/envelope/BUILD.bazel index 5043b62c..c1c4dc74 100644 --- a/yacl/crypto/base/envelope/BUILD.bazel +++ b/yacl/crypto/base/envelope/BUILD.bazel @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("//bazel:yacl.bzl", "AES_COPT_FLAGS", "yacl_cc_library", "yacl_cc_test") +load("//bazel:yacl.bzl", "yacl_cc_library", "yacl_cc_test") package(default_visibility = ["//visibility:public"]) @@ -28,7 +28,7 @@ yacl_cc_library( "//yacl/crypto/base/hmac:hmac_sm3", "//yacl/crypto/base/pke:asymmetric_rsa_crypto", "//yacl/crypto/base/pke:asymmetric_sm2_crypto", - "//yacl/crypto/tools:prg", + "//yacl/crypto/utils:rand", "@com_google_absl//absl/strings", "@com_google_absl//absl/types:span", ], diff --git a/yacl/crypto/base/envelope/digital_envelope.cc b/yacl/crypto/base/envelope/digital_envelope.cc index 4378f5e0..4974484d 100644 --- a/yacl/crypto/base/envelope/digital_envelope.cc +++ b/yacl/crypto/base/envelope/digital_envelope.cc @@ -14,38 +14,15 @@ #include "yacl/crypto/base/envelope/digital_envelope.h" -#include - #include "absl/types/span.h" -#include "yacl/crypto/base/aead/gcm_crypto.h" -#include "yacl/crypto/base/aead/sm4_mac.h" -#include "yacl/crypto/base/block_cipher/symmetric_crypto.h" -#include "yacl/crypto/base/hash/ssl_hash.h" -#include "yacl/crypto/base/hmac/hmac_sm3.h" -#include "yacl/crypto/base/pke/asymmetric_rsa_crypto.h" -#include "yacl/crypto/base/pke/asymmetric_sm2_crypto.h" -#include "yacl/crypto/tools/prg.h" - namespace yacl::crypto { -namespace { - -std::vector GenRandKey(size_t key_size) { - std::random_device rd; - Prg prg(rd()); - std::vector symmetric_key(key_size); - std::generate(symmetric_key.begin(), symmetric_key.end(), - [&] { return prg(); }); - return symmetric_key; -} - -} // namespace void SmEnvSeal(ByteContainerView pub_key, ByteContainerView iv, ByteContainerView plaintext, std::vector* encrypted_key, std::vector* ciphertext) { // Step 1. Generate random 16 bytes key for SM4. - std::vector symmetric_key = GenRandKey(16); + std::vector symmetric_key = SecureRandBytes(16); // Step 2. Do sm4-mac *ciphertext = Sm4MteEncrypt(symmetric_key, iv, plaintext); @@ -66,7 +43,7 @@ void RsaEnvSeal(ByteContainerView pub_key, ByteContainerView iv, ByteContainerView plaintext, std::vector* encrypted_key, std::vector* ciphertext, std::vector* mac) { - std::vector symmetric_key = GenRandKey(16); + std::vector symmetric_key = SecureRandBytes(16); ciphertext->resize(plaintext.size()); // Aes-128 mac size is 16 bytes. mac->resize(16); diff --git a/yacl/crypto/base/envelope/digital_envelope.h b/yacl/crypto/base/envelope/digital_envelope.h index 5277e8dd..c0428a57 100644 --- a/yacl/crypto/base/envelope/digital_envelope.h +++ b/yacl/crypto/base/envelope/digital_envelope.h @@ -18,6 +18,16 @@ #include "yacl/base/byte_container_view.h" +/* submodules */ +#include "yacl/crypto/base/aead/gcm_crypto.h" +#include "yacl/crypto/base/aead/sm4_mac.h" +#include "yacl/crypto/base/block_cipher/symmetric_crypto.h" +#include "yacl/crypto/base/hash/ssl_hash.h" +#include "yacl/crypto/base/hmac/hmac_sm3.h" +#include "yacl/crypto/base/pke/asymmetric_rsa_crypto.h" +#include "yacl/crypto/base/pke/asymmetric_sm2_crypto.h" +#include "yacl/crypto/utils/rand.h" + namespace yacl::crypto { // SM envelope sealing with sm4-ctr + hmac-sm3 + sm2. @@ -74,4 +84,4 @@ void RsaEnvOpen(ByteContainerView pri_key, ByteContainerView iv, ByteContainerView encrypted_key, ByteContainerView ciphertext, ByteContainerView mac, std::vector* plaintext); -} // namespace yacl::crypto \ No newline at end of file +} // namespace yacl::crypto diff --git a/yacl/crypto/base/field/field_spi.h b/yacl/crypto/base/field/field_spi.h deleted file mode 100644 index 2df83f19..00000000 --- a/yacl/crypto/base/field/field_spi.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2023 Ant Group Co., Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include - -#include "yacl/base/block.h" -#include "yacl/crypto/base/ecc/any_ptr.h" -#include "yacl/math/mpint/mp_int.h" - -namespace yacl::crypto { - -using FElement = std::variant; -using yacl::math::MPInt; - -// Finite Prime Field(FElement) and including its extension, i.e., -// FElement2,FElement6,FElement12,FElement^n -class Field { - public: - virtual ~Field() = default; - - virtual std::string GetLibraryName() const = 0; - virtual std::string GetFieldName() const = 0; - virtual int64_t GetExtensionDegree() const = 0; - // getBasePrimeP? - - // The order of Finite Field will always be k-th power of a prime number p and - // in extension field, field order and field modulus are different and not - // directly related, which is unlike in normal prime field that field order is - // just field modulus. - // Note, the origin order(p^k) of extension field(degree k>1) is actually - // useless for field computation. So we usually disable `GetOrder` for - // extension field and set it to be 0, except we are dealing within a subfield - // from the upper extension field. - virtual MPInt GetOrder() const = 0; - - virtual bool IsOne(const FElement& x) const = 0; - virtual bool IsZero(const FElement& x) const = 0; - virtual bool Equal(const FElement& x, const FElement& y) const = 0; - - virtual FElement Rand() const = 0; - - // univariate input - virtual void SetOne(FElement* x) const = 0; - virtual FElement MakeOne() const = 0; - virtual void SetZero(FElement* x) const = 0; - virtual FElement MakeZero() const = 0; - virtual FElement MakeInstance() const = 0; - virtual FElement FromInt64(int64_t i) const = 0; - virtual FElement Copy(const FElement& x) const = 0; - - virtual FElement Neg(const FElement& x) const = 0; - // virtual void NegInplace(FElement* x) const = 0; - virtual FElement Sqr(const FElement& x) const = 0; - // virtual void SqrInplace(FElement* x) const = 0; - virtual FElement Inv(const FElement& x) const = 0; - // virtual void InvInplace(FElement* x) const = 0; - - // bivariate inputs - virtual FElement Add(const FElement& x, const FElement& y) const = 0; - virtual void AddInplace(FElement* x, const FElement& y) const = 0; - - virtual FElement Sub(const FElement& x, const FElement& y) const = 0; - virtual void SubInplace(FElement* x, const FElement& y) const = 0; - - virtual FElement Mul(const FElement& x, const FElement& y) const = 0; - virtual void MulInplace(FElement* x, const FElement& y) const = 0; - - virtual FElement Div(const FElement& x, const FElement& y) const = 0; - virtual void DivInplace(FElement* x, const FElement& y) const = 0; - - virtual FElement Pow(const FElement& x, const MPInt& y) const = 0; - virtual void PowInplace(FElement* x, const MPInt& y) const = 0; - - // virtual FElement powVec(const FElement* x, const MPInt* y, uint64_t n) - // const = 0; - - // serialize - virtual std::string ToString(const FElement& x) const = 0; - virtual FElement FromString(const std::string& x) const = 0; - virtual std::string ToDecString(const FElement& x) const = 0; - virtual FElement FromDecString(const std::string& x) const = 0; - virtual std::string ToHexString(const FElement& x) const = 0; - virtual FElement FromHexString(const std::string& x) const = 0; - virtual Buffer Serialize(const FElement& x) const = 0; - virtual FElement Deserialize(ByteContainerView buffer) const = 0; -}; - -} // namespace yacl::crypto diff --git a/yacl/crypto/base/field/mcl/mcl_field.cc b/yacl/crypto/base/field/mcl/mcl_field.cc deleted file mode 100644 index a3709310..00000000 --- a/yacl/crypto/base/field/mcl/mcl_field.cc +++ /dev/null @@ -1,316 +0,0 @@ -// Copyright 2023 Ant Group Co., Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "yacl/crypto/base/field/mcl/mcl_field.h" - -#include "mcl/fp_tower.hpp" -#include "mcl/op.hpp" -#include "mcl_field.h" - -#include "yacl/crypto/base/ecc/mcl/mcl_util.h" -#include "yacl/crypto/base/ecc/mcl/pairing_header.h" - -namespace yacl::crypto::hmcl { - -template -std::string MclField::GetLibraryName() const { - return "libmcl"; -} - -template -std::string MclField::GetFieldName() const { - return fmt::format("", degree_, - Mpz2Mp(T_::BaseFp::getOp().mp)); -} - -template -int64_t MclField::GetExtensionDegree() const { - return degree_; -} - -template -MPInt MclField::GetOrder() const { - return order_; -} - -template -bool MclField::IsOne(const FElement& x) const { - return CastAny(x)->isOne(); -} - -template -bool MclField::IsZero(const FElement& x) const { - return CastAny(x)->isZero(); -} - -template -bool MclField::Equal(const FElement& x, const FElement& y) const { - return *CastAny(x) == *CastAny(y); -} - -template -FElement MclField::Rand() const { - using BaseFp = typename T_::BaseFp; - const auto per_size = (BaseFp::getOp().mp.getBitSize() + 7) / 8; - - auto ret = MakeShared(); - Buffer buf(per_size * degree_); - BaseFp p; - for (uint64_t i = 0; i < degree_; i++) { - p.setByCSPRNG(); - p.serialize(buf.data() + i * per_size, per_size); - } - - CastAny(ret)->deserialize(buf.data(), buf.size()); - return ret; -} - -template -void MclField::SetOne(FElement* x) const { - auto* p = std::get(*x).get(); - if (!p->isOne() && degree_ == 1) { - *p = 1; - } else { - p->clear(); - *(p->getFp0()) = 1; - } -} - -template -FElement MclField::MakeOne() const { - return FromInt64(1); -} - -template -void MclField::SetZero(FElement* x) const { - auto* p = std::get(*x).get(); - if (!p->isOne() && degree_ == 0) { - *p = 0; - } else { - p->clear(); - *(p->getFp0()) = 0; - } -} - -template -FElement MclField::MakeZero() const { - return MakeShared(0); -} - -template -FElement MclField::MakeInstance() const { - return MakeShared(0); -} - -template -FElement MclField::FromInt64(int64_t i) const { - return MakeShared(i); -} - -template -FElement MclField::Copy(const FElement& x) const { - auto ret = MakeShared(); - *CastAny(ret) = *CastAny(x); - return ret; -} - -template -FElement MclField::Neg(const FElement& x) const { - auto ret = MakeShared(); - T_::neg(*CastAny(ret), *CastAny(x)); - return ret; -} - -template -FElement MclField::Sqr(const FElement& x) const { - auto ret = MakeShared(); - T_::sqr(*CastAny(ret), *CastAny(x)); - return ret; -} - -template -FElement MclField::Inv(const FElement& x) const { - auto ret = MakeShared(); - T_::inv(*CastAny(ret), *CastAny(x)); - return ret; -} - -template -FElement MclField::Add(const FElement& x, - const FElement& y) const { - auto ret = MakeShared(); - T_::add(*CastAny(ret), *CastAny(x), *CastAny(y)); - return ret; -} - -template -void MclField::AddInplace(FElement* x, const FElement& y) const { - T_::add(*CastAny(*x), *CastAny(x), *CastAny(y)); -} - -template -FElement MclField::Sub(const FElement& x, - const FElement& y) const { - auto ret = MakeShared(); - T_::sub(*CastAny(ret), *CastAny(x), *CastAny(y)); - return ret; -} - -template -void MclField::SubInplace(FElement* x, const FElement& y) const { - T_::sub(*CastAny(*x), *CastAny(x), *CastAny(y)); -} - -template -FElement MclField::Mul(const FElement& x, - const FElement& y) const { - auto ret = MakeShared(); - T_::mul(*CastAny(ret), *CastAny(x), *CastAny(y)); - return ret; -} - -template -void MclField::MulInplace(FElement* x, const FElement& y) const { - T_::mul(*CastAny(*x), *CastAny(x), *CastAny(y)); -} - -template -FElement MclField::Div(const FElement& x, - const FElement& y) const { - auto ret = MakeShared(); - T_::div(*CastAny(ret), *CastAny(x), *CastAny(y)); - return ret; -} - -template -void MclField::DivInplace(FElement* x, const FElement& y) const { - T_::div(*CastAny(*x), *CastAny(x), *CastAny(y)); -} - -template -FElement MclField::Pow(const FElement& x, const MPInt& y) const { - auto ret = MakeShared(); - T_::pow(*CastAny(ret), *CastAny(x), Mp2Mpz(y)); - return ret; -} - -template -void MclField::PowInplace(FElement* x, const MPInt& y) const { - T_::pow(*CastAny(*x), *CastAny(x), Mp2Mpz(y)); -} - -template -std::string MclField::ToString(const FElement& x) const { - return ToDecString(x); -} - -template -FElement MclField::FromString(const std::string& x) const { - return FromDecString(x); -} - -template -std::string MclField::ToDecString(const FElement& x) const { - return CastAny(x)->getStr(mcl::IoDec); -} - -template -FElement MclField::FromDecString(const std::string& x) const { - auto ret = MakeShared(); - CastAny(ret)->setStr(x, mcl::IoDec); - return ret; -} - -template -std::string MclField::ToHexString(const FElement& x) const { - return CastAny(x)->getStr(mcl::IoHex); -} - -template -FElement MclField::FromHexString(const std::string& x) const { - auto ret = MakeShared(); - CastAny(ret)->setStr(x, mcl::IoHex); - return ret; -} - -template -Buffer MclField::Serialize(const FElement& x) const { - Buffer buf(sizeof(T_)); - auto size = CastAny(x)->serialize(buf.data(), buf.size()); - buf.resize(size); - return buf; -} - -template -FElement MclField::Deserialize(ByteContainerView buffer) const { - auto ret = MakeShared(); - CastAny(ret)->deserialize(buffer.data(), buffer.size()); - return ret; -} - -template -MclField::MclField(const MPInt& order, bool is_sub_field) { - order_ = order; - is_sub_field_ = is_sub_field; - // if is_sub_field_ == true, we should provide specific (not zero) order. - YACL_ENFORCE(is_sub_field_ && !order_.IsZero(), - "Should provide specific (not zero) order for subfield!"); -} - -template -MclField::MclField(const MPInt& base_prime_p, mcl::fp::Mode mode, - int xi_a) { - auto base_p = Mp2Mpz(base_prime_p); - if (degree_ == 1) { - T_::BaseFp::init(base_p, mode); - order_ = base_prime_p; - } else { - // init for extension mcl field Fp^{2,6,12} - // xi_a is used for Fp2::mul_xi(), where xi = xi_a + i and i^2 = -1 - // if xi_a = 0 then asm functions for Fp2 are not generated. - T_::BaseFp::init(xi_a, base_p, mode); - mcl::Fp2T::init(); - order_ = 0_mp; - } -} - -// =============================================================== -// Instantiate Field for test -// =============================================================== -#ifdef MCL_FIELD_YACL_TEST -template class MclField, 1>; -template class MclField, 1>; -template class MclField>, 2>; -template class MclField>, 6>; -template class MclField>, 12>; -#endif - -// =============================================================== -// Instantiate Pairing Curve Field from template -// =============================================================== -template class MclField; - -#ifdef MCL_ALL_PAIRING_FOR_YACL -template class MclField; -template class MclField; -template class MclField; -template class MclField; -template class MclField; -template class MclField; -template class MclField; -template class MclField; -template class MclField; -#endif - -} // namespace yacl::crypto::hmcl diff --git a/yacl/crypto/base/field/mcl/mcl_field.h b/yacl/crypto/base/field/mcl/mcl_field.h deleted file mode 100644 index 015ab55f..00000000 --- a/yacl/crypto/base/field/mcl/mcl_field.h +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2023 Ant Group Co., Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "mcl/fp.hpp" -#include "mcl/fp_tower.hpp" - -#include "yacl/crypto/base/ecc/mcl/pairing_header.h" -#include "yacl/crypto/base/field/field_spi.h" - -namespace yacl::crypto::hmcl { - -using yacl::math::MPInt; - -// class `MclField` have specific template parameters from libmcl, -// checker `is_supported_mcl_field` helps avoid misuse of class `MclField` -template -struct is_supported_mcl_field { - static constexpr bool value = false; -}; - -// Support template params check in template class `MclField` -// ! NOT suggest use DECLARE_SUPPORT. -// Developers should be aware of the specific field type `T` from libmcl and -// the field extension degree of `T` if use macro DECLARE_SUPPORT. -#define DECLARE_SUPPORT(T, degree) \ - template <> \ - struct is_supported_mcl_field { \ - static constexpr bool value = true; \ - }; - -template -class MclField : public Field { - private: - // Only declared field from libmcl could be instantiated in this class. - template < - typename = std::enable_if_t::value>> - MclField() {} - - public: - using T = T_; - - std::string GetLibraryName() const override; - std::string GetFieldName() const override; - int64_t GetExtensionDegree() const override; - // Note that pairing GT field's order is enabled(!=0) and != p^12, since it's - // actually a sub-field belong to field Fp^12 - MPInt GetOrder() const override; - - bool IsOne(const FElement& x) const override; - bool IsZero(const FElement& x) const override; - bool Equal(const FElement& x, const FElement& y) const override; - - FElement Rand() const override; - - // univariate input - void SetOne(FElement* x) const override; - FElement MakeOne() const override; - void SetZero(FElement* x) const override; - FElement MakeZero() const override; - FElement MakeInstance() const override; - FElement FromInt64(int64_t i) const override; - FElement Copy(const FElement& x) const override; - - FElement Neg(const FElement& x) const override; - FElement Sqr(const FElement& x) const override; - FElement Inv(const FElement& x) const override; - - // bivariate inputs - FElement Add(const FElement& x, const FElement& y) const override; - void AddInplace(FElement* x, const FElement& y) const override; - - FElement Sub(const FElement& x, const FElement& y) const override; - void SubInplace(FElement* x, const FElement& y) const override; - - FElement Mul(const FElement& x, const FElement& y) const override; - void MulInplace(FElement* x, const FElement& y) const override; - - FElement Div(const FElement& x, const FElement& y) const override; - void DivInplace(FElement* x, const FElement& y) const override; - - FElement Pow(const FElement& x, const MPInt& y) const override; - void PowInplace(FElement* x, const MPInt& y) const override; - - // serialize - std::string ToString(const FElement& x) const override; - FElement FromString(const std::string& x) const override; - std::string ToDecString(const FElement& x) const override; - FElement FromDecString(const std::string& x) const override; - std::string ToHexString(const FElement& x) const override; - FElement FromHexString(const std::string& x) const override; - Buffer Serialize(const FElement& x) const override; - FElement Deserialize(ByteContainerView buffer) const override; - - public: - explicit MclField(const MPInt& order, bool is_sub_field); - // xi_a is used for Fp2::mul_xi(), where xi = xi_a + i and i^2 = -1, see - // Fp::init(int xi_a, ...) - explicit MclField(const MPInt& base_prime_p, - mcl::fp::Mode mode = mcl::fp::FP_AUTO, int xi_a = 1); - - private: - MPInt order_; - bool is_sub_field_; -}; - -DECLARE_SUPPORT(mcl::bls12::GT, 12); - -#ifdef MCL_FIELD_YACL_TEST -DECLARE_SUPPORT(mcl::FpT<>, 1); -typedef mcl::FpT fqt256; -DECLARE_SUPPORT(fqt256, 1); -DECLARE_SUPPORT(mcl::Fp2T>, 2); -DECLARE_SUPPORT(mcl::Fp6T>, 6); -DECLARE_SUPPORT(mcl::Fp12T>, 12); -#endif - -#ifdef MCL_ALL_PAIRING_FOR_YACL -DECLARE_SUPPORT(mcl::bn254::GT, 12); -DECLARE_SUPPORT(mcl::bn382m::GT, 12); -DECLARE_SUPPORT(mcl::bn382r::GT, 12); -DECLARE_SUPPORT(mcl::bn462::GT, 12); -DECLARE_SUPPORT(mcl::bnsnark::GT, 12); -DECLARE_SUPPORT(mcl::bn160::GT, 12); -DECLARE_SUPPORT(mcl::bls123::GT, 12); -DECLARE_SUPPORT(mcl::bls124::GT, 12); -DECLARE_SUPPORT(mcl::bn256::GT, 12); -#endif - -} // namespace yacl::crypto::hmcl diff --git a/yacl/crypto/base/field/mcl/mcl_field_test.cc b/yacl/crypto/base/field/mcl/mcl_field_test.cc deleted file mode 100644 index e3efee75..00000000 --- a/yacl/crypto/base/field/mcl/mcl_field_test.cc +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2023 Ant Group Co., Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "yacl/crypto/base/field/mcl/mcl_field.h" - -#include "gtest/gtest.h" - -#include "yacl/crypto/base/ecc/mcl/mcl_pairing_group.h" -#include "yacl/crypto/utils/rand.h" - -namespace yacl::crypto::hmcl::test { - -class MclFieldTest : public ::testing::Test { - protected: - std::shared_ptr field_; // This lib/curve we should to test - std::string filed_name_; - bool is_sub_field_ = false; - - void RunAllTests() { - fmt::print("Begin to test mcl field {} \n", filed_name_); - TestCompare(); - TestArithmetic(); - if (field_->GetExtensionDegree() == 1) { - TestOrder(); - } - TestSerialize(); - fmt::print("End to test mcl field {} \n", filed_name_); - } - - void TestCompare() { - auto f1 = field_->MakeInstance(); - EXPECT_TRUE(field_->IsZero(f1)); - field_->SetOne(&f1); - EXPECT_TRUE(field_->IsOne(f1)); - EXPECT_TRUE(field_->Equal(f1, field_->MakeOne())); - - auto f2 = field_->Rand(); - EXPECT_TRUE(field_->Equal(f2, f2)); - EXPECT_FALSE(field_->Equal(f1, f2)); - } - - void TestArithmetic() { - // GIVEN - auto f1 = field_->Rand(); - auto f2 = field_->Rand(); - - // THEN - // Add, AddInplace - auto add_ret = field_->Add(f1, f2); - EXPECT_TRUE(field_->Equal(add_ret, field_->Add(f2, f1))); - auto temp = field_->Copy(f1); - field_->AddInplace(&temp, f2); - EXPECT_TRUE(field_->Equal(add_ret, temp)); - - // Neg & Sub, SubInplace - EXPECT_TRUE(field_->IsZero(field_->Add(f1, field_->Neg(f1)))); - auto sub_ret = field_->Sub(f1, f2); - EXPECT_TRUE(field_->Equal(sub_ret, field_->Add(f1, field_->Neg(f2)))); - temp = field_->Copy(f1); - field_->SubInplace(&temp, f2); - EXPECT_TRUE(field_->Equal(sub_ret, temp)); - - // Mul, MulInplace - auto mul_ret = field_->Mul(f1, f2); - EXPECT_TRUE(field_->Equal(mul_ret, field_->Mul(f2, f1))); - temp = field_->Copy(f1); - field_->MulInplace(&temp, f2); - EXPECT_TRUE(field_->Equal(mul_ret, temp)); - - // Sqr & Pow, PowInplace - EXPECT_TRUE(field_->Equal(field_->Sqr(f1), field_->Mul(f1, f1))); - auto pow_temp = field_->MakeOne(); - for (int i = 0; i < 10; i++) { - auto y = MPInt(i); - auto pow_ret = field_->Pow(f1, y); - temp = field_->Copy(f1); - field_->PowInplace(&temp, y); - EXPECT_TRUE(field_->Equal(temp, pow_ret)); - EXPECT_TRUE(field_->Equal(pow_ret, pow_temp)); - - pow_temp = field_->Mul(temp, f1); - } - - // Div, DivInplace & Inv - EXPECT_TRUE(field_->IsOne(field_->Div(f1, f1))); - auto div_ret = field_->Div(f1, f2); - temp = field_->Copy(f1); - field_->DivInplace(&temp, f2); - EXPECT_TRUE(field_->Equal(temp, div_ret)); - EXPECT_TRUE( - field_->IsOne(field_->Mul(field_->Div(f1, f2), field_->Div(f2, f1)))); - EXPECT_TRUE(field_->IsOne(field_->Mul(f1, field_->Inv(f1)))); - } - - void TestOrder() { - auto order = field_->GetOrder(); - // For Fp^n, any element x * order = 0, any element x(!=0)^(order -1) = 1 - for (int i = 0; i < 10; i++) { - auto f = field_->Rand(); - auto f_pow_order = field_->Pow(f, order); - EXPECT_TRUE(field_->Equal(f_pow_order, f)); - } - } - - void TestSerialize() { - for (int i = 0; i < 1; i++) { - auto f = field_->Rand(); - // Serialize - auto buf = field_->Serialize(f); - auto f1 = field_->Deserialize(buf); - EXPECT_TRUE(field_->Equal(f, f1)); - // toString - auto str = field_->ToString(f); - auto f2 = field_->FromString(str); - EXPECT_TRUE(field_->Equal(f, f2)); - // ToDecString - auto str10 = field_->ToDecString(f); - auto f3 = field_->FromDecString(str10); - EXPECT_TRUE(field_->Equal(f, f3)); - // ToHexString - auto str16 = field_->ToHexString(f); - auto f4 = field_->FromHexString(str16); - EXPECT_TRUE(field_->Equal(f, f4)); - } - } -}; - -#ifdef MCL_FIELD_YACL_TEST -#define DEFAULT_FIELD_TEST(intern_type, degree) \ - class Mcl##intern_type##Test : public MclFieldTest { \ - void SetUp() override { \ - auto child_ptr = std::make_unique>( \ - "0xffffffffffffffffffffffffffffffffffffffffffffff13"_mp, \ - mcl::fp::FP_AUTO); \ - field_ = std::move(child_ptr); \ - filed_name_ = #intern_type; \ - } \ - }; \ - TEST_F(Mcl##intern_type##Test, Works) { RunAllTests(); } - -using DefaultFp = mcl::FpT<>; -using DefaultFpWithSize256 = mcl::FpT; -using DefaultFp2 = mcl::Fp2T>; -using DefaultFp6 = mcl::Fp6T>; -using DefaultFp12 = mcl::Fp12T>; - -DEFAULT_FIELD_TEST(DefaultFp, 1); -DEFAULT_FIELD_TEST(DefaultFpWithSize256, 1); -DEFAULT_FIELD_TEST(DefaultFp2, 2); -DEFAULT_FIELD_TEST(DefaultFp6, 6); -DEFAULT_FIELD_TEST(DefaultFp12, 12); -#endif - -// TODO: temporarily disable mcl pairing test, since its weird error on Intel -// Mac -#define DECLARE_PAIRING_FIELD_TEST_CLASS(classname, pairing_name) \ - class MclPairing##classname##GTTest : public MclFieldTest { \ - void SetUp() override { \ - auto pairing = MclPGFactory::CreateByName(pairing_name); \ - field_ = pairing->GetGT(); \ - filed_name_ = "MclPairing" #classname "GTField"; \ - is_sub_field_ = true; \ - } \ - }; \ - TEST_F(MclPairing##classname##GTTest, DISABLED_Works) { RunAllTests(); } - -DECLARE_PAIRING_FIELD_TEST_CLASS(Bls12381, "bls12-381"); - -#ifdef MCL_ALL_PAIRING_FOR_YACL -DECLARE_PAIRING_FIELD_TEST_CLASS(BN254, "bn254"); -DECLARE_PAIRING_FIELD_TEST_CLASS(BN384M, "bn382m"); -DECLARE_PAIRING_FIELD_TEST_CLASS(BN384R, "bn382r"); -DECLARE_PAIRING_FIELD_TEST_CLASS(BN462, "bn462"); -DECLARE_PAIRING_FIELD_TEST_CLASS(BNSnark, "bn_snark1"); -DECLARE_PAIRING_FIELD_TEST_CLASS(BN160, "bn160"); -DECLARE_PAIRING_FIELD_TEST_CLASS(Bls12461, "bls12-461"); -DECLARE_PAIRING_FIELD_TEST_CLASS(BN256, "bn256"); -#endif - -} // namespace yacl::crypto::hmcl::test diff --git a/yacl/crypto/base/hash/BUILD.bazel b/yacl/crypto/base/hash/BUILD.bazel index 15477339..10466f33 100644 --- a/yacl/crypto/base/hash/BUILD.bazel +++ b/yacl/crypto/base/hash/BUILD.bazel @@ -71,6 +71,7 @@ yacl_cc_library( srcs = ["hash_interface.h"], deps = [ "//yacl/base:byte_container_view", + "//yacl/crypto/utils:secparam", "@com_github_openssl_openssl//:openssl", ], ) diff --git a/yacl/crypto/base/hash/blake3.h b/yacl/crypto/base/hash/blake3.h index 087a5cae..ca8f8933 100644 --- a/yacl/crypto/base/hash/blake3.h +++ b/yacl/crypto/base/hash/blake3.h @@ -14,6 +14,8 @@ #pragma once +#include + #include "c/blake3.h" #include "yacl/base/byte_container_view.h" diff --git a/yacl/crypto/base/hash/hash_interface.h b/yacl/crypto/base/hash/hash_interface.h index 043f6e06..fcf8714b 100644 --- a/yacl/crypto/base/hash/hash_interface.h +++ b/yacl/crypto/base/hash/hash_interface.h @@ -19,6 +19,10 @@ #include "openssl/evp.h" /* for evp type conversions */ #include "yacl/base/byte_container_view.h" +#include "yacl/crypto/utils/secparam.h" + +/* security parameter declaration */ +YACL_MODULE_DECLARE("hash_all", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { @@ -30,7 +34,7 @@ enum class HashAlgorithm : int { SHA384 = 3, SHA512 = 4, - SHA_1 = 5, + // SHA_1 = 5, // not recommended to use SM3 = 6, @@ -91,8 +95,8 @@ inline const char *ToString(HashAlgorithm hash_algo) { return "sha2-384"; case HashAlgorithm::SHA512: return "sha2-512"; - case HashAlgorithm::SHA_1: - return "sha1"; + // case HashAlgorithm::SHA_1: + // return "sha1"; case HashAlgorithm::SM3: return "sm3"; case HashAlgorithm::BLAKE2B: diff --git a/yacl/crypto/base/hash/ssl_hash.cc b/yacl/crypto/base/hash/ssl_hash.cc index 9508a9f7..9e353114 100644 --- a/yacl/crypto/base/hash/ssl_hash.cc +++ b/yacl/crypto/base/hash/ssl_hash.cc @@ -33,37 +33,37 @@ HashAlgorithm SslHash::GetHashAlgorithm() const { return hash_algo_; } size_t SslHash::DigestSize() const { return digest_size_; } SslHash& SslHash::Reset() { - YACL_ENFORCE_EQ(EVP_MD_CTX_reset(context_.get()), 1); + OSSL_RET_1(EVP_MD_CTX_reset(context_.get())); int res = 0; const auto md = openssl::FetchEvpMd(ToString(hash_algo_)); res = EVP_DigestInit_ex(context_.get(), md.get(), nullptr); - YACL_ENFORCE_EQ(res, 1, "EVP_DigestInit_ex failed."); + OSSL_RET_1(res, "EVP_DigestInit_ex failed."); return *this; } SslHash& SslHash::Update(ByteContainerView data) { - YACL_ENFORCE_EQ(EVP_DigestUpdate(context_.get(), data.data(), data.size()), - 1); + OSSL_RET_1(EVP_DigestUpdate(context_.get(), data.data(), data.size())); return *this; } std::vector SslHash::CumulativeHash() const { + unsigned int out_len = 0; + std::vector out(DigestSize()); // Do not finalize the internally stored hash context. Instead, finalize a // copy of the current context so that the current context can be updated in // future calls to Update. - EVP_MD_CTX* context_snapshot = EVP_MD_CTX_new(); - YACL_ENFORCE(context_snapshot != nullptr); - ON_SCOPE_EXIT([&] { EVP_MD_CTX_free(context_snapshot); }); - EVP_MD_CTX_init(context_snapshot); - YACL_ENFORCE_EQ(EVP_MD_CTX_copy_ex(context_snapshot, context_.get()), 1); - std::vector digest(DigestSize()); - unsigned int digest_len; - YACL_ENFORCE_EQ( - EVP_DigestFinal_ex(context_snapshot, digest.data(), &digest_len), 1); - YACL_ENFORCE_EQ(digest_len, DigestSize()); + auto ctx_snapshot = openssl::UniqueMdCtx(EVP_MD_CTX_new()); + YACL_ENFORCE(ctx_snapshot != nullptr); - return digest; + EVP_MD_CTX_init(ctx_snapshot.get()); // no return value + + OSSL_RET_1(EVP_MD_CTX_copy_ex(ctx_snapshot.get(), context_.get())); + OSSL_RET_1(EVP_DigestFinal_ex(ctx_snapshot.get(), out.data(), &out_len)); + + YACL_ENFORCE(out_len == DigestSize()); + + return out; } } // namespace yacl::crypto diff --git a/yacl/crypto/base/hash/ssl_hash.h b/yacl/crypto/base/hash/ssl_hash.h index 5ded3f5d..0757bbec 100644 --- a/yacl/crypto/base/hash/ssl_hash.h +++ b/yacl/crypto/base/hash/ssl_hash.h @@ -14,7 +14,7 @@ #pragma once -#include "openssl/evp.h" +#include #include "yacl/base/byte_container_view.h" #include "yacl/crypto/base/hash/hash_interface.h" diff --git a/yacl/crypto/base/hash/ssl_hash_all_test.cc b/yacl/crypto/base/hash/ssl_hash_all_test.cc index 719c640a..8b9126b7 100644 --- a/yacl/crypto/base/hash/ssl_hash_all_test.cc +++ b/yacl/crypto/base/hash/ssl_hash_all_test.cc @@ -75,7 +75,7 @@ class SslHashTest : public testing::Test { return test_data_blake2b_; } - YACL_THROW("Unsupported typename!"); + YACL_THROW("Unsupported type name!"); } TestData test_data_sm3_; diff --git a/yacl/crypto/base/hmac/hmac.cc b/yacl/crypto/base/hmac/hmac.cc index 51f6cf44..47a6b3ed 100644 --- a/yacl/crypto/base/hmac/hmac.cc +++ b/yacl/crypto/base/hmac/hmac.cc @@ -32,8 +32,8 @@ Hmac::Hmac(HashAlgorithm hash_algo, ByteContainerView key) "digest", const_cast(ToString(hash_algo)), /* the length of previous param is determined using strlen() */ 0); params[1] = OSSL_PARAM_construct_end(); - YACL_ENFORCE(EVP_MAC_init(ctx_.get(), key_.data(), key_.size(), - /* params */ params.data()) > 0); + OSSL_RET_1(EVP_MAC_init(ctx_.get(), key_.data(), key_.size(), + /* params */ params.data())); } HashAlgorithm Hmac::GetHashAlgorithm() const { return hash_algo_; } @@ -44,14 +44,14 @@ Hmac& Hmac::Reset() { YACL_ENFORCE(params != nullptr); // re-init the mac context - YACL_ENFORCE(EVP_MAC_init(ctx_.get(), key_.data(), key_.size(), - /* params */ params) > 0); + OSSL_RET_1(EVP_MAC_init(ctx_.get(), key_.data(), key_.size(), + /* params */ params)); return *this; } Hmac& Hmac::Update(ByteContainerView data) { YACL_ENFORCE(ctx_ != nullptr); - YACL_ENFORCE(EVP_MAC_update(ctx_.get(), data.data(), data.size()) > 0); + OSSL_RET_1(EVP_MAC_update(ctx_.get(), data.data(), data.size())); return *this; } @@ -65,12 +65,11 @@ std::vector Hmac::CumulativeMac() const { // get the outptut size size_t outlen = 0; - YACL_ENFORCE(EVP_MAC_final(ctx_copy.get(), nullptr, &outlen, 0) > 0); + OSSL_RET_1(EVP_MAC_final(ctx_copy.get(), nullptr, &outlen, 0)); // get the final output std::vector mac(outlen); - YACL_ENFORCE(EVP_MAC_final(ctx_copy.get(), mac.data(), &outlen, mac.size()) > - 0); + OSSL_RET_1(EVP_MAC_final(ctx_copy.get(), mac.data(), &outlen, mac.size())); mac.resize(outlen); // this is necessary return mac; diff --git a/yacl/crypto/base/hmac/hmac.h b/yacl/crypto/base/hmac/hmac.h index 7a3e02bd..81c49940 100644 --- a/yacl/crypto/base/hmac/hmac.h +++ b/yacl/crypto/base/hmac/hmac.h @@ -17,9 +17,11 @@ #include #include "yacl/base/byte_container_view.h" -#include "yacl/crypto/base/hash/hash_interface.h" #include "yacl/crypto/base/openssl_wrappers.h" +/* submodules */ +#include "yacl/crypto/base/hash/hash_interface.h" + namespace yacl::crypto { // Hmac defines an base for hmac functions. diff --git a/yacl/crypto/base/hmac/hmac_all_test.cc b/yacl/crypto/base/hmac/hmac_all_test.cc index e9a5eaa0..83c1bd10 100644 --- a/yacl/crypto/base/hmac/hmac_all_test.cc +++ b/yacl/crypto/base/hmac/hmac_all_test.cc @@ -111,18 +111,17 @@ TYPED_TEST(HmacTest, ResetBetweenUpdates) { // Verify that the correct hmac is computed when the input is added over several // calls to Update. -// TYPED_TEST(HmacTest, MultipleUpdates) { -// TypeParam hmac(this->Data().key); -// std::vector mac = -// hmac.Update(this->Data().vector1).CumulativeMac(); -// EXPECT_EQ(absl::BytesToHexString( -// absl::string_view((const char*)mac.data(), mac.size())), -// this->Data().result1); +TYPED_TEST(HmacTest, MultipleUpdates) { + TypeParam hmac(this->Data().key); + std::vector mac = hmac.Update(this->Data().vector1).CumulativeMac(); + EXPECT_EQ(absl::BytesToHexString( + absl::string_view((const char*)mac.data(), mac.size())), + this->Data().result1); -// mac = hmac.Update(this->Data().suffix).CumulativeMac(); -// EXPECT_EQ(absl::BytesToHexString( -// absl::string_view((const char*)mac.data(), mac.size())), -// this->Data().result2); -// } + mac = hmac.Update(this->Data().suffix).CumulativeMac(); + EXPECT_EQ(absl::BytesToHexString( + absl::string_view((const char*)mac.data(), mac.size())), + this->Data().result2); +} } // namespace yacl::crypto diff --git a/yacl/crypto/base/key_utils.cc b/yacl/crypto/base/key_utils.cc index 8124bcc3..7f5f110e 100644 --- a/yacl/crypto/base/key_utils.cc +++ b/yacl/crypto/base/key_utils.cc @@ -14,6 +14,8 @@ #include "yacl/crypto/base/key_utils.h" +#include + #include "yacl/io/stream/file_io.h" namespace yacl::crypto { @@ -83,13 +85,13 @@ openssl::UniquePkey GenRsaKeyPair(unsigned rsa_keylen) { openssl::UniquePkeyCtx ctx( EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, /* engine = default */ nullptr)); YACL_ENFORCE(ctx != nullptr); - YACL_ENFORCE(EVP_PKEY_keygen_init(ctx.get()) > 0); + OSSL_RET_1(EVP_PKEY_keygen_init(ctx.get())); // set key length bits - YACL_ENFORCE(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), rsa_keylen) > 0); + OSSL_RET_1(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx.get(), rsa_keylen)); // generate keys - YACL_ENFORCE(EVP_PKEY_keygen(ctx.get(), &pkey) > 0); + OSSL_RET_1(EVP_PKEY_keygen(ctx.get(), &pkey)); return openssl::UniquePkey(pkey); } @@ -99,10 +101,10 @@ openssl::UniquePkey GenSm2KeyPair() { openssl::UniquePkeyCtx ctx( EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, /* engine = default */ nullptr)); YACL_ENFORCE(ctx != nullptr); - YACL_ENFORCE(EVP_PKEY_keygen_init(ctx.get()) > 0); + OSSL_RET_1(EVP_PKEY_keygen_init(ctx.get())); // generate keys - YACL_ENFORCE(EVP_PKEY_keygen(ctx.get(), &pkey) > 0); + OSSL_RET_1(EVP_PKEY_keygen(ctx.get(), &pkey)); return openssl::UniquePkey(pkey); } @@ -143,7 +145,7 @@ openssl::UniquePkey LoadKeyFromBuf(ByteContainerView buf) { /* OSSL_LIB_CTX */ nullptr, /* probquery */ nullptr)); YACL_ENFORCE(decoder != nullptr, "no decoder found"); - YACL_ENFORCE(OSSL_DECODER_from_bio(decoder.get(), bio.get()) == 1); + OSSL_RET_1(OSSL_DECODER_from_bio(decoder.get(), bio.get())); return openssl::UniquePkey(pkey); } @@ -161,8 +163,8 @@ Buffer ExportPublicKeyToPemBuf( /* public key */ const openssl::UniquePkey& pkey) { openssl::UniqueBio bio(BIO_new(BIO_s_mem())); // create an empty bio // export certificate to bio - YACL_ENFORCE(PEM_write_bio_PUBKEY(bio.get(), pkey.get()) == 1, - "Failed PEM_export_bio_PUBKEY."); + OSSL_RET_1(PEM_write_bio_PUBKEY(bio.get(), pkey.get()), + "Failed PEM_export_bio_PUBKEY."); return BioToBuf(bio); } @@ -178,9 +180,9 @@ Buffer ExportSecretKeyToPemBuf( openssl::UniqueBio bio(BIO_new(BIO_s_mem())); // create an empty bio // export certificate to bio - YACL_ENFORCE(PEM_write_bio_PrivateKey(bio.get(), pkey.get(), nullptr, nullptr, - 0, nullptr, nullptr) == 1, - "Failed PEM_export_bio_PrivateKey."); + OSSL_RET_1(PEM_write_bio_PrivateKey(bio.get(), pkey.get(), nullptr, nullptr, + 0, nullptr, nullptr), + "Failed PEM_export_bio_PrivateKey."); return BioToBuf(bio); } @@ -204,7 +206,7 @@ Buffer ExportPublicKeyToDerBuf( /* format */ "DER", /* RFC 5280: X.509 structure */ "SubjectPublicKeyInfo", nullptr)); YACL_ENFORCE(encoder != nullptr, "no encoder found"); - YACL_ENFORCE(OSSL_ENCODER_to_bio(encoder.get(), bio.get()) == 1); + OSSL_RET_1(OSSL_ENCODER_to_bio(encoder.get(), bio.get())); return BioToBuf(bio); } @@ -225,7 +227,7 @@ Buffer ExportSecretKeyToDerBuf( /* format */ "DER", /* RFC 5208: PKCS#8 structure */ "PrivateKeyInfo", nullptr)); YACL_ENFORCE(encoder != nullptr, "no encoder found"); - YACL_ENFORCE(OSSL_ENCODER_to_bio(encoder.get(), bio.get()) == 1); + OSSL_RET_1(OSSL_ENCODER_to_bio(encoder.get(), bio.get())); return BioToBuf(bio); } @@ -244,9 +246,10 @@ openssl::UniqueX509 MakeX509Cert( /* subjects info */ const std::unordered_map& subjects, /* time */ unsigned days, HashAlgorithm hash) { - YACL_ENFORCE((hash == HashAlgorithm::SHA256) || (hash == HashAlgorithm::SM3)); + YACL_ENFORCE(hash == HashAlgorithm::SHA256 || hash == HashAlgorithm::SM3); + // ++++++++++++++++++++++++++++++ // Generate X509 cert (version 3) - // ---------------------------------------- + // ++++++++++++++++++++++++++++++ // * Certificate // ** Version Number // ** Serial Number @@ -265,15 +268,14 @@ openssl::UniqueX509 MakeX509Cert( // ** ... // * Certificate Signature Algorithm // * Certificate Signature - // ---------------------------------------- + // ++++++++++++++++++++++++++++++ openssl::UniqueX509 x509(X509_new()); /* version */ - YACL_ENFORCE(X509_set_version(x509.get(), kX509Version) == 1); + OSSL_RET_1(X509_set_version(x509.get(), kX509Version)); - // /* Serial Number */ - // // YACL_ENFORCE(X509_set_serialNumber(x509.get(), - // // ASN1_INTEGER_set_int64(FastRandU64()) == 1); // set random serial - // number + /* Serial Number */ + // YACL_ENFORCE(X509_set_serialNumber(x509.get(), + // ASN1_INTEGER_set_int64(FastRandU64()) == 1); // set random serial number /* time */ X509_gmtime_adj(X509_get_notBefore(x509.get()), 0); @@ -289,15 +291,15 @@ openssl::UniqueX509 MakeX509Cert( for (const auto& field : kX509SubjectFields) { auto it = subjects.find(std::string(field)); YACL_ENFORCE(it != subjects.end(), "Cannot find subject field {}.", field); - YACL_ENFORCE(X509_NAME_add_entry_by_txt( - name, it->first.c_str(), MBSTRING_ASC, - reinterpret_cast(it->second.c_str()), - -1, -1, 0), - "Set x509 name failed."); + OSSL_RET_1(X509_NAME_add_entry_by_txt( + name, it->first.c_str(), MBSTRING_ASC, + reinterpret_cast(it->second.c_str()), + -1, -1, 0), + "Set x509 name failed."); } /* issuer = subject since this cert is self-signed */ - YACL_ENFORCE(X509_set_issuer_name(x509.get(), name) == 1); + OSSL_RET_1(X509_set_issuer_name(x509.get(), name)); /* fill cert with rsa public key */ X509_set_pubkey(x509.get(), pk.get()); @@ -306,9 +308,9 @@ openssl::UniqueX509 MakeX509Cert( AddX509Extension(x509.get(), NID_subject_key_identifier, (char*)"hash"); /* self signing with digest algorithm */ - YACL_ENFORCE(X509_sign(x509.get(), sk.get(), - openssl::FetchEvpMd(ToString(hash)).get()), - "Perform self-signing failed."); + auto sign_bytes = X509_sign(x509.get(), sk.get(), + openssl::FetchEvpMd(ToString(hash)).get()); + YACL_ENFORCE(sign_bytes > 0, "Perform self-signing failed."); return x509; } @@ -349,8 +351,8 @@ Buffer ExportX509CertToBuf(const openssl::UniqueX509& x509) { openssl::UniqueBio bio(BIO_new(BIO_s_mem())); // create an empty bio // export certificate to bio - YACL_ENFORCE(PEM_write_bio_X509(bio.get(), x509.get()) == 1, - "Failed PEM_export_bio_X509."); + OSSL_RET_1(PEM_write_bio_X509(bio.get(), x509.get()), + "Failed PEM_export_bio_X509."); return BioToBuf(bio); } diff --git a/yacl/crypto/base/key_utils.h b/yacl/crypto/base/key_utils.h index 6ea4713d..36c79466 100644 --- a/yacl/crypto/base/key_utils.h +++ b/yacl/crypto/base/key_utils.h @@ -14,6 +14,10 @@ #pragma once +#include +#include +#include + #include "yacl/crypto/base/openssl_wrappers.h" namespace yacl::crypto { diff --git a/yacl/crypto/base/openssl_wrappers.h b/yacl/crypto/base/openssl_wrappers.h index c90d6782..bd8e225f 100644 --- a/yacl/crypto/base/openssl_wrappers.h +++ b/yacl/crypto/base/openssl_wrappers.h @@ -15,16 +15,19 @@ #pragma once #include +#include #include #include "hash/hash_interface.h" /* yacl hash to openssl hash */ #include "openssl/bio.h" +#include "openssl/bn.h" #include "openssl/core.h" #include "openssl/core_dispatch.h" #include "openssl/core_names.h" #include "openssl/decoder.h" +#include "openssl/ec.h" #include "openssl/encoder.h" -#include "openssl/evp.h" /* evp */ +#include "openssl/evp.h" #include "openssl/pem.h" #include "openssl/provider.h" #include "openssl/x509v3.h" @@ -88,6 +91,11 @@ using UniqueDecoder = using UniqueLib = internal::TyHelper; using UniqueProv = internal::TyHelper; +/* ec and bn */ +using UniqueEcGroup = internal::TyHelper; +using UniqueBnCtx = internal::TyHelper; +using UniqueBn = internal::TyHelper; + // ------------------ // OpenSSL EVP Enum // ------------------ @@ -106,8 +114,7 @@ inline UniqueMac FetchEvpHmac() { // --------------------------------- // Helpers for OpenSSL return values // --------------------------------- -// #define OSSL_RET_1(MP_ERR, ...) YACL_ENFORCE_EQ((MP_ERR), 1, __VA_ARGS__) -// #define OSSL_RET_N(MP_ERR, ...) YACL_ENFORCE_GE((MP_ERR), 0, __VA_ARGS__) -// #define OSSL_RET_ZP(MP_ERR, ...) YACL_ENFORCE_GT((MP_ERR), 0, __VA_ARGS__) +/* enforce return code == 1 */ +#define OSSL_RET_1(MP_ERR, ...) YACL_ENFORCE_EQ((MP_ERR), 1, __VA_ARGS__) } // namespace yacl::crypto::openssl diff --git a/yacl/crypto/base/field/BUILD.bazel b/yacl/crypto/base/pairing/BUILD.bazel similarity index 60% rename from yacl/crypto/base/field/BUILD.bazel rename to yacl/crypto/base/pairing/BUILD.bazel index 82e1a2fb..d7e070b0 100644 --- a/yacl/crypto/base/field/BUILD.bazel +++ b/yacl/crypto/base/pairing/BUILD.bazel @@ -17,12 +17,28 @@ load("//bazel:yacl.bzl", "yacl_cc_library", "yacl_cc_test") package(default_visibility = ["//visibility:public"]) yacl_cc_library( - name = "field_spi", - # srcs = ["field_spi.cc"], - hdrs = ["field_spi.h"], + name = "pairing", deps = [ - "//yacl/base:block", - "//yacl/crypto/base/ecc:any_ptr", - "//yacl/math/mpint", + "//yacl/crypto/base/pairing/mcl:pairing", + ], +) + +yacl_cc_library( + name = "pairing_spi", + srcs = ["pairing_spi.cc"], + hdrs = ["pairing_spi.h"], + deps = [ + "//yacl/crypto/base/ecc:spi", + "//yacl/math/galois_field:spi", + "@com_google_absl//absl/strings", + ], +) + +yacl_cc_test( + name = "pairing_test", + srcs = ["pairing_test.cc"], + deps = [ + ":pairing", + "@yacl//yacl/utils:parallel", ], ) diff --git a/yacl/crypto/base/pairing/mcl/BUILD.bazel b/yacl/crypto/base/pairing/mcl/BUILD.bazel new file mode 100644 index 00000000..3ef04df6 --- /dev/null +++ b/yacl/crypto/base/pairing/mcl/BUILD.bazel @@ -0,0 +1,64 @@ +# Copyright 2023 Ant Group Co., Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +load("//bazel:yacl.bzl", "yacl_cc_library", "yacl_cc_test") +load("@bazel_skylib//lib:selects.bzl", "selects") + +package(default_visibility = ["//visibility:public"]) + +yacl_cc_library( + name = "pairing_header", + hdrs = ["pairing_header.h"], + copts = [ + ], + defines = selects.with_or({ + ("@yacl//bazel:yacl_build_as_debug", "@yacl//bazel:yacl_build_as_fast"): [ + # Macro `MCL_ALL_PAIRING_FOR_YACL` enables libmcl's all pairing curves + # and not that they are not standard pairing instances. + # !Only for test and don't use this in production! + "MCL_ALL_PAIRING_FOR_YACL", + ], + "//conditions:default": [], + }), + deps = ["@com_github_herumi_mcl//:mcl"], +) + +yacl_cc_library( + name = "pairing", + srcs = [ + "mcl_pairing_bls12_381.cc", + "mcl_pairing_bls12_381.h", + "mcl_pairing_factory.cc", + "mcl_pairing_group.cc", + ], + hdrs = [ + "mcl_pairing_group.h", + ], + deps = [ + ":pairing_header", + "//yacl/crypto/base/ecc", + "//yacl/crypto/base/pairing:pairing_spi", + "//yacl/math/galois_field/mcl_field:field", + ], + alwayslink = 1, +) + +yacl_cc_test( + name = "pairing_test", + srcs = ["mcl_pairing_test.cc"], + deps = [ + ":pairing", + "//yacl/crypto/utils:rand", + ], +) diff --git a/yacl/crypto/base/ecc/mcl/mcl_pairing_bls12_381.cc b/yacl/crypto/base/pairing/mcl/mcl_pairing_bls12_381.cc similarity index 58% rename from yacl/crypto/base/ecc/mcl/mcl_pairing_bls12_381.cc rename to yacl/crypto/base/pairing/mcl/mcl_pairing_bls12_381.cc index 0cbc7fb0..6b53f56c 100644 --- a/yacl/crypto/base/ecc/mcl/mcl_pairing_bls12_381.cc +++ b/yacl/crypto/base/pairing/mcl/mcl_pairing_bls12_381.cc @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "yacl/crypto/base/ecc/mcl/mcl_pairing_bls12_381.h" +#include "yacl/crypto/base/pairing/mcl/mcl_pairing_bls12_381.h" namespace yacl::crypto::hmcl { MclPairingBls12381::MclPairingBls12381(const PairingMeta& meta, std::unique_ptr& g1, std::unique_ptr& g2, - std::unique_ptr& gt) + std::unique_ptr& gt) : meta_(meta) { g1_ = std::move(g1); g2_ = std::move(g2); @@ -39,35 +39,34 @@ size_t MclPairingBls12381::GetSecurityStrength() const { return meta_.secure_bits; } -std::shared_ptr MclPairingBls12381::GetG1() const { return g1_; } +std::shared_ptr MclPairingBls12381::GetGroup1() const { return g1_; } -std::shared_ptr MclPairingBls12381::GetG2() const { return g2_; } +std::shared_ptr MclPairingBls12381::GetGroup2() const { return g2_; } -std::shared_ptr MclPairingBls12381::GetGT() const { return gt_; } +std::shared_ptr MclPairingBls12381::GetGroupT() const { + return gt_; +} MPInt MclPairingBls12381::GetOrder() const { return g1_->GetOrder(); } -FElement MclPairingBls12381::MillerLoop(const EcPoint& group1_point, - const EcPoint& group2_point) const { - FElement ret = gt_->MakeInstance(); - mcl::bls12::millerLoop(*(CastAny(ret)), - *(CastAny(group1_point)), +GtElement MclPairingBls12381::MillerLoop(const EcPoint& group1_point, + const EcPoint& group2_point) const { + mcl::bls12::GT ret; + mcl::bls12::millerLoop(ret, *(CastAny(group1_point)), *(CastAny(group2_point))); return ret; } -FElement MclPairingBls12381::FinalExp(const FElement& x) const { - FElement ret = gt_->MakeInstance(); - mcl::bls12::finalExp(*(CastAny(ret)), - *(CastAny(x))); +GtElement MclPairingBls12381::FinalExp(const GtElement& x) const { + mcl::bls12::GT ret; + mcl::bls12::finalExp(ret, x.As()); return ret; } -FElement MclPairingBls12381::Pairing(const EcPoint& group1_point, - const EcPoint& group2_point) const { - FElement ret = gt_->MakeInstance(); - mcl::bls12::pairing(*(CastAny(ret)), - *(CastAny(group1_point)), +GtElement MclPairingBls12381::Pairing(const EcPoint& group1_point, + const EcPoint& group2_point) const { + mcl::bls12::GT ret; + mcl::bls12::pairing(ret, *(CastAny(group1_point)), *(CastAny(group2_point))); return ret; } diff --git a/yacl/crypto/base/ecc/mcl/mcl_pairing_bls12_381.h b/yacl/crypto/base/pairing/mcl/mcl_pairing_bls12_381.h similarity index 64% rename from yacl/crypto/base/ecc/mcl/mcl_pairing_bls12_381.h rename to yacl/crypto/base/pairing/mcl/mcl_pairing_bls12_381.h index 2a9882b2..795f0443 100644 --- a/yacl/crypto/base/ecc/mcl/mcl_pairing_bls12_381.h +++ b/yacl/crypto/base/pairing/mcl/mcl_pairing_bls12_381.h @@ -17,45 +17,45 @@ #include "mcl/bls12_381.hpp" #include "yacl/crypto/base/ecc/mcl/mcl_ec_group.h" -#include "yacl/crypto/base/ecc/pairing_spi.h" -#include "yacl/crypto/base/field/mcl/mcl_field.h" +#include "yacl/crypto/base/pairing/pairing_spi.h" +#include "yacl/math/galois_field/mcl_field/mcl_field.h" namespace yacl::crypto::hmcl { using MclPairingBls12381G1 = MclGroupT; using MclPairingBls12381G2 = MclGroupT; -using MclPairingBls12381GT = MclField; +using MclPairingBls12381GT = math::hmcl::MclField; class MclPairingBls12381 : public PairingGroup { public: + std::string GetLibraryName() const override; PairingName GetPairingName() const override; PairingAlgorithm GetPairingAlgorithm() const override; - std::string GetLibraryName() const override; std::string ToString() const override; size_t GetSecurityStrength() const override; - std::shared_ptr GetG1() const override; - std::shared_ptr GetG2() const override; - std::shared_ptr GetGT() const override; + std::shared_ptr GetGroup1() const override; + std::shared_ptr GetGroup2() const override; + std::shared_ptr GetGroupT() const override; MPInt GetOrder() const override; - FElement MillerLoop(const EcPoint& group1_point, - const EcPoint& group2_point) const override; - FElement FinalExp(const FElement& x) const override; - // pairing = MillerLoop + FinalExponentiation - FElement Pairing(const EcPoint& group1_point, - const EcPoint& group2_point) const override; + GtElement MillerLoop(const EcPoint& group1_point, + const EcPoint& group2_point) const override; + GtElement FinalExp(const GtElement& x) const override; + GtElement Pairing(const EcPoint& group1_point, + const EcPoint& group2_point) const override; private: PairingMeta meta_; std::shared_ptr g1_; std::shared_ptr g2_; - std::shared_ptr gt_; + std::shared_ptr gt_; friend class MclPGFactory; MclPairingBls12381(const PairingMeta& meta, std::unique_ptr& g1, - std::unique_ptr& g2, std::unique_ptr& gt); + std::unique_ptr& g2, + std::unique_ptr& gt); }; } // namespace yacl::crypto::hmcl diff --git a/yacl/crypto/base/ecc/mcl/mcl_pairing_factory.cc b/yacl/crypto/base/pairing/mcl/mcl_pairing_factory.cc similarity index 95% rename from yacl/crypto/base/ecc/mcl/mcl_pairing_factory.cc rename to yacl/crypto/base/pairing/mcl/mcl_pairing_factory.cc index 304837d5..ec6a3457 100644 --- a/yacl/crypto/base/ecc/mcl/mcl_pairing_factory.cc +++ b/yacl/crypto/base/pairing/mcl/mcl_pairing_factory.cc @@ -14,7 +14,7 @@ #include "absl/strings/ascii.h" -#include "yacl/crypto/base/ecc/mcl/mcl_pairing_group.h" +#include "yacl/crypto/base/pairing/mcl/mcl_pairing_group.h" namespace yacl::crypto::hmcl { @@ -93,8 +93,8 @@ std::unique_ptr MclPGFactory::CreateByName( static_cast( \ mcl::namespace_name::hashAndMapToG2); \ \ - auto gt = std::unique_ptr( \ - new MclPairing##class_name##GT(g1->GetOrder(), true)); \ + auto gt = std::unique_ptr(new MclPairing##class_name##GT( \ + g1->GetOrder(), math::hmcl::Type::Mul)); \ \ auto child_ptr = \ std::make_unique(meta, g1, g2, gt); \ @@ -140,8 +140,8 @@ std::unique_ptr MclPGFactory::Create(const PairingMeta& meta) { mcl::bls12::hashAndMapToG2); // Init GT - auto gt = std::unique_ptr( - new MclPairingBls12381GT(g1->GetOrder(), true)); + auto gt = std::unique_ptr( + new MclPairingBls12381GT(g1->GetOrder(), math::hmcl::Type::Mul)); return std::unique_ptr( new MclPairingBls12381(meta, g1, g2, gt)); diff --git a/yacl/crypto/base/ecc/mcl/mcl_pairing_group.cc b/yacl/crypto/base/pairing/mcl/mcl_pairing_group.cc similarity index 73% rename from yacl/crypto/base/ecc/mcl/mcl_pairing_group.cc rename to yacl/crypto/base/pairing/mcl/mcl_pairing_group.cc index c3ea0f77..3bd2ecfe 100644 --- a/yacl/crypto/base/ecc/mcl/mcl_pairing_group.cc +++ b/yacl/crypto/base/pairing/mcl/mcl_pairing_group.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "yacl/crypto/base/ecc/mcl/mcl_pairing_group.h" +#include "yacl/crypto/base/pairing/mcl/mcl_pairing_group.h" #ifdef MCL_ALL_PAIRING_FOR_YACL namespace yacl::crypto::hmcl { @@ -43,17 +43,17 @@ size_t MclPairingGroup::GetSecurityStrength() const { } template -std::shared_ptr MclPairingGroup::GetG1() const { +std::shared_ptr MclPairingGroup::GetGroup1() const { return g1_; } template -std::shared_ptr MclPairingGroup::GetG2() const { +std::shared_ptr MclPairingGroup::GetGroup2() const { return g2_; } template -std::shared_ptr MclPairingGroup::GetGT() const { +std::shared_ptr MclPairingGroup::GetGroupT() const { return gt_; } @@ -63,35 +63,34 @@ MPInt MclPairingGroup::GetOrder() const { } template -FElement MclPairingGroup::MillerLoop( +GtElement MclPairingGroup::MillerLoop( const EcPoint& group1_point, const EcPoint& group2_point) const { - FElement ret = gt_->MakeInstance(); - miller_func_(*(CastAny(ret)), *(CastAny(group1_point)), + GT_ ret; + miller_func_(ret, *(CastAny(group1_point)), *(CastAny(group2_point))); return ret; } template -FElement MclPairingGroup::FinalExp(const FElement& x) const { - FElement ret = gt_->MakeInstance(); - final_exp_func_(*(CastAny(ret)), *(CastAny(x))); +GtElement MclPairingGroup::FinalExp(const GtElement& x) const { + GT_ ret; + final_exp_func_(ret, x.As()); return ret; } template -FElement MclPairingGroup::Pairing( +GtElement MclPairingGroup::Pairing( const EcPoint& group1_point, const EcPoint& group2_point) const { - FElement ret = gt_->MakeInstance(); - pairing_func_(*(CastAny(ret)), *(CastAny(group1_point)), + GT_ ret; + pairing_func_(ret, *(CastAny(group1_point)), *(CastAny(group2_point))); return ret; } template -MclPairingGroup::MclPairingGroup(const PairingMeta& meta, - std::unique_ptr& g1, - std::unique_ptr& g2, - std::unique_ptr& gt) +MclPairingGroup::MclPairingGroup( + const PairingMeta& meta, std::unique_ptr& g1, + std::unique_ptr& g2, std::unique_ptr& gt) : meta_(meta) { g1_ = std::move(g1); g2_ = std::move(g2); diff --git a/yacl/crypto/base/ecc/mcl/mcl_pairing_group.h b/yacl/crypto/base/pairing/mcl/mcl_pairing_group.h similarity index 79% rename from yacl/crypto/base/ecc/mcl/mcl_pairing_group.h rename to yacl/crypto/base/pairing/mcl/mcl_pairing_group.h index 90f9c8d7..63bc8121 100644 --- a/yacl/crypto/base/ecc/mcl/mcl_pairing_group.h +++ b/yacl/crypto/base/pairing/mcl/mcl_pairing_group.h @@ -15,10 +15,10 @@ #pragma once #include "yacl/crypto/base/ecc/mcl/mcl_ec_group.h" -#include "yacl/crypto/base/ecc/mcl/mcl_pairing_bls12_381.h" -#include "yacl/crypto/base/ecc/mcl/pairing_header.h" -#include "yacl/crypto/base/ecc/pairing_spi.h" -#include "yacl/crypto/base/field/mcl/mcl_field.h" +#include "yacl/crypto/base/pairing/mcl/mcl_pairing_bls12_381.h" +#include "yacl/crypto/base/pairing/mcl/pairing_header.h" +#include "yacl/crypto/base/pairing/pairing_spi.h" +#include "yacl/math/galois_field/mcl_field/mcl_field.h" namespace yacl::crypto::hmcl { @@ -38,7 +38,8 @@ class MclPGFactory { MclGroupT; \ using MclPairing##classname##G2 = \ MclGroupT; \ - using MclPairing##classname##GT = MclField; + using MclPairing##classname##GT = \ + math::hmcl::MclField; PAIRING_CURVE_ALIAS(BN254, bn254); PAIRING_CURVE_ALIAS(BN384M, bn382m); @@ -55,27 +56,23 @@ PAIRING_CURVE_ALIAS(BN256, bn256); template class MclPairingGroup : public PairingGroup { public: - using G1 = G1_; - using G2 = G2_; - using GT = GT_; - std::string GetLibraryName() const override; PairingName GetPairingName() const override; PairingAlgorithm GetPairingAlgorithm() const override; std::string ToString() const override; size_t GetSecurityStrength() const override; - std::shared_ptr GetG1() const override; - std::shared_ptr GetG2() const override; - std::shared_ptr GetGT() const override; + std::shared_ptr GetGroup1() const override; + std::shared_ptr GetGroup2() const override; + std::shared_ptr GetGroupT() const override; MPInt GetOrder() const override; - FElement MillerLoop(const EcPoint& group1_point, - const EcPoint& group2_point) const override; - FElement FinalExp(const FElement& x) const override; - FElement Pairing(const EcPoint& group1_point, - const EcPoint& group2_point) const override; + GtElement MillerLoop(const EcPoint& group1_point, + const EcPoint& group2_point) const override; + GtElement FinalExp(const GtElement& x) const override; + GtElement Pairing(const EcPoint& group1_point, + const EcPoint& group2_point) const override; private: using PairingFunc = std::function; @@ -85,7 +82,7 @@ class MclPairingGroup : public PairingGroup { PairingMeta meta_; std::shared_ptr g1_; std::shared_ptr g2_; - std::shared_ptr gt_; + std::shared_ptr gt_; PairingFunc pairing_func_; MillerFunc miller_func_; @@ -97,7 +94,7 @@ class MclPairingGroup : public PairingGroup { explicit MclPairingGroup(const PairingMeta& meta, std::unique_ptr& g1, std::unique_ptr& g2, - std::unique_ptr& gt); + std::unique_ptr& gt); }; #define PAIRING_GROUP_ALIAS(classname, namespace_name) \ diff --git a/yacl/crypto/base/ecc/mcl/mcl_pairing_test.cc b/yacl/crypto/base/pairing/mcl/mcl_pairing_test.cc similarity index 86% rename from yacl/crypto/base/ecc/mcl/mcl_pairing_test.cc rename to yacl/crypto/base/pairing/mcl/mcl_pairing_test.cc index ff9dcbdd..27a5f9e3 100644 --- a/yacl/crypto/base/ecc/mcl/mcl_pairing_test.cc +++ b/yacl/crypto/base/pairing/mcl/mcl_pairing_test.cc @@ -14,7 +14,7 @@ #include "gtest/gtest.h" -#include "yacl/crypto/base/ecc/mcl/mcl_pairing_group.h" +#include "yacl/crypto/base/pairing/mcl/mcl_pairing_group.h" #include "yacl/crypto/utils/rand.h" namespace yacl::crypto::hmcl { @@ -29,7 +29,7 @@ class MclPairingTest : public ::testing::Test { std::unique_ptr pairing_group_; std::shared_ptr group1_; std::shared_ptr group2_; - std::shared_ptr gt_field_; + std::shared_ptr gt_; void TestPairingAlgo() { // GIVEN @@ -42,23 +42,23 @@ class MclPairingTest : public ::testing::Test { // THEN // Test GT group order - ASSERT_TRUE(gt_field_->IsOne(gt_field_->Pow(field_g, order))); + ASSERT_TRUE((bool)gt_->IsIdentityOne(gt_->Pow(field_g, order))); // Test Pairing for (int i = 0; i < 10; i++) { MPInt x; MPInt::RandomLtN(order, &x); // field_g^x = e(g1, g2)^x - auto ex = gt_field_->Pow(field_g, x); + auto ex = gt_->Pow(field_g, x); // g1 * x auto g1x = group1_->MulBase(x); // g2 * x auto g2x = group2_->MulBase(x); // e1 = e(g1^x, g2) = e(g1, g2)^x = ex auto e1 = pairing_group_->Pairing(g1x, g2); - ASSERT_TRUE(gt_field_->Equal(e1, ex)); + ASSERT_TRUE((bool)gt_->Equal(e1, ex)); // e1 = e(g1, g2^x) = e(g1, g2)^x = ex auto e2 = pairing_group_->Pairing(g1, g2x); - ASSERT_TRUE(gt_field_->Equal(e2, ex)); + ASSERT_TRUE((bool)gt_->Equal(e2, ex)); } // Test Pairing = Miller + FinalExp @@ -73,7 +73,7 @@ class MclPairingTest : public ::testing::Test { auto f = pairing_group_->MillerLoop(g1x, g2x); auto f1 = pairing_group_->FinalExp(f); auto f2 = pairing_group_->Pairing(g1x, g2x); - ASSERT_TRUE(gt_field_->Equal(f1, f2)); + ASSERT_TRUE((bool)gt_->Equal(f1, f2)); } } @@ -101,16 +101,16 @@ class MclPairingTest : public ::testing::Test { protected: \ void SetUp() override { \ pairing_group_ = MclPGFactory::CreateByName(pairing_name); \ - group1_ = pairing_group_->GetG1(); \ - group2_ = pairing_group_->GetG2(); \ - gt_field_ = pairing_group_->GetGT(); \ + group1_ = pairing_group_->GetGroup1(); \ + group2_ = pairing_group_->GetGroup2(); \ + gt_ = pairing_group_->GetGroupT(); \ } \ }; \ TEST_F(MclPairing##class_name##Test, DISABLED_Works) { \ fmt::print("Begin test pairing {}\n", pairing_group_->GetPairingName()); \ TestPairingAlgo(); \ - TestHashToCurve(pairing_group_->GetG1()); \ - TestHashToCurve(pairing_group_->GetG2()); \ + TestHashToCurve(pairing_group_->GetGroup1()); \ + TestHashToCurve(pairing_group_->GetGroup2()); \ fmt::print("End test pairing {}\n", pairing_group_->GetPairingName()); \ } diff --git a/yacl/crypto/base/ecc/mcl/pairing_header.h b/yacl/crypto/base/pairing/mcl/pairing_header.h similarity index 100% rename from yacl/crypto/base/ecc/mcl/pairing_header.h rename to yacl/crypto/base/pairing/mcl/pairing_header.h diff --git a/yacl/crypto/base/ecc/pairing_spi.cc b/yacl/crypto/base/pairing/pairing_spi.cc similarity index 58% rename from yacl/crypto/base/ecc/pairing_spi.cc rename to yacl/crypto/base/pairing/pairing_spi.cc index dc19a4a2..54983181 100644 --- a/yacl/crypto/base/ecc/pairing_spi.cc +++ b/yacl/crypto/base/pairing/pairing_spi.cc @@ -1,4 +1,18 @@ -#include "yacl/crypto/base/ecc/pairing_spi.h" +// Copyright 2023 Ant Group Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "yacl/crypto/base/pairing/pairing_spi.h" namespace yacl::crypto { diff --git a/yacl/crypto/base/ecc/pairing_spi.h b/yacl/crypto/base/pairing/pairing_spi.h similarity index 65% rename from yacl/crypto/base/ecc/pairing_spi.h rename to yacl/crypto/base/pairing/pairing_spi.h index c07e6a86..7b5662b1 100644 --- a/yacl/crypto/base/ecc/pairing_spi.h +++ b/yacl/crypto/base/pairing/pairing_spi.h @@ -15,13 +15,19 @@ #pragma once #include "yacl/crypto/base/ecc/ecc_spi.h" -#include "yacl/crypto/base/field/field_spi.h" +#include "yacl/math/galois_field/gf_spi.h" #include "yacl/utils/spi/spi_factory.h" namespace yacl::crypto { using PairingName = CurveName; using PairingMeta = CurveMeta; +// Alias of group element of pairing target (multiplicative) group over +// extension field $F_{q^12}$. +using GtElement = Item; +// Alias of pairing target (multiplicative) group, specifically used in +// Pairing setting. +using GroupTarget = yacl::math::GaloisField; enum class PairingAlgorithm { Weil, @@ -32,11 +38,12 @@ enum class PairingAlgorithm { Atei, }; -// Let $F_{q^k}$ be some finite extension of $F_q$ with $k ≥ 1$. The groups -// $G_1$ and $G_2$ are defined in $E(F_{q^k})$, and the target group $G_T$ is -// defined in the multiplicative group $F_{q^k}^*$ , so we usually write $G_1$ -// and $G_2$ additively, whilst we write $G_T$ multiplicatively. Thus, for $P_1, -// P_2 \in G_1$ and $Q_1, Q_2 \in G_2$, the bilinearity of $e$ means that: +// Let $F_{q^k}$ be some finite extension of field $F_q$ with $k ≥ 1$. The +// groups $G_1$ and $G_2$ are defined over specific field, and the target group +// $G_T$ is a multiplicative group over extension field $F_{q^k}^*$. So we +// usually write $G_1$ and $G_2$ additively, whilst we write $G_T$ +// multiplicatively. Thus, for $P_1, P_2 \in G_1$ and $Q_1, Q_2 \in G_2$, the +// bilinearity of $e$ means that: // - e(P_1 + P_2 , Q_1) = e(P_1, Q_1) · e(P_2 , Q_1), // - e(P_1, Q_1 + Q_2) = e(P_1, Q_1) · e(P_1, Q_2), class PairingGroup { @@ -49,21 +56,23 @@ class PairingGroup { virtual std::string ToString() const = 0; virtual size_t GetSecurityStrength() const = 0; - virtual std::shared_ptr GetG1() const = 0; - virtual std::shared_ptr GetG2() const = 0; - virtual std::shared_ptr GetGT() const = 0; + virtual std::shared_ptr GetGroup1() const = 0; + virtual std::shared_ptr GetGroup2() const = 0; + virtual std::shared_ptr GetGroupT() const = 0; virtual MPInt GetOrder() const = 0; - virtual FElement MillerLoop(const EcPoint &group1_point, - const EcPoint &group2_point) const = 0; - virtual FElement FinalExp(const FElement &x) const = 0; + virtual GtElement MillerLoop(const EcPoint &group1_point, + const EcPoint &group2_point) const = 0; + virtual GtElement FinalExp(const GtElement &x) const = 0; // pairing = MillerLoop + FinalExponentiation - virtual FElement Pairing(const EcPoint &group1_point, - const EcPoint &group2_point) const = 0; + // Group1 x Group2 -> Gt + virtual GtElement Pairing(const EcPoint &group1_point, + const EcPoint &group2_point) const = 0; // multi_miller_loop - + // TODO: @banqiang // multi_pairing + // TODO: @banqiang }; // Give pairing meta, return pairing instance. diff --git a/yacl/crypto/base/ecc/pairing_test.cc b/yacl/crypto/base/pairing/pairing_test.cc similarity index 92% rename from yacl/crypto/base/ecc/pairing_test.cc rename to yacl/crypto/base/pairing/pairing_test.cc index bb125642..e43fffc4 100644 --- a/yacl/crypto/base/ecc/pairing_test.cc +++ b/yacl/crypto/base/pairing/pairing_test.cc @@ -17,7 +17,7 @@ #include "fmt/ranges.h" #include "gtest/gtest.h" -#include "yacl/crypto/base/ecc/pairing_spi.h" +#include "yacl/crypto/base/pairing/pairing_spi.h" #include "yacl/utils/parallel.h" namespace yacl::crypto { @@ -25,14 +25,15 @@ namespace yacl::crypto { class PairingCurveTest : public ::testing::TestWithParam { protected: std::unique_ptr pairing_group_; - std::shared_ptr gt_field_; + std::shared_ptr gt_; void RunAllTests() { fmt::print("Begin to test curve {} from {} lib\n", pairing_group_->GetPairingName(), pairing_group_->GetLibraryName()); - for (const auto &ec : {pairing_group_->GetG1(), pairing_group_->GetG2()}) { + for (const auto &ec : + {pairing_group_->GetGroup1(), pairing_group_->GetGroup2()}) { TestArithmeticWorks(ec); TestMulIsAdd(ec); TestSerializeWorks(ec); @@ -250,8 +251,8 @@ class PairingCurveTest : public ::testing::TestWithParam { void TestPairingAlgo() { // GIVEN - auto g1 = pairing_group_->GetG1()->GetGenerator(); - auto g2 = pairing_group_->GetG2()->GetGenerator(); + auto g1 = pairing_group_->GetGroup1()->GetGenerator(); + auto g2 = pairing_group_->GetGroup2()->GetGenerator(); // WHEN auto field_g = pairing_group_->Pairing(g1, g2); @@ -259,23 +260,23 @@ class PairingCurveTest : public ::testing::TestWithParam { // THEN // Test GT group order - ASSERT_TRUE(gt_field_->IsOne(gt_field_->Pow(field_g, order))); + ASSERT_TRUE((bool)gt_->IsIdentityOne(gt_->Pow(field_g, order))); // Test Pairing for (int i = 0; i < 10; i++) { MPInt x; MPInt::RandomLtN(order, &x); // field_g^x = e(g1, g2)^x - auto ex = gt_field_->Pow(field_g, x); + auto ex = gt_->Pow(field_g, x); // g1 * x - auto g1x = pairing_group_->GetG1()->MulBase(x); + auto g1x = pairing_group_->GetGroup1()->MulBase(x); // g2 * x - auto g2x = pairing_group_->GetG2()->MulBase(x); + auto g2x = pairing_group_->GetGroup2()->MulBase(x); // e1 = e(g1^x, g2) = e(g1, g2)^x = ex auto e1 = pairing_group_->Pairing(g1x, g2); - ASSERT_TRUE(gt_field_->Equal(e1, ex)); + ASSERT_TRUE((bool)gt_->Equal(e1, ex)); // e1 = e(g1, g2^x) = e(g1, g2)^x = ex auto e2 = pairing_group_->Pairing(g1, g2x); - ASSERT_TRUE(gt_field_->Equal(e2, ex)); + ASSERT_TRUE((bool)gt_->Equal(e2, ex)); } // Test Pairing = Miller + FinalExp @@ -283,14 +284,14 @@ class PairingCurveTest : public ::testing::TestWithParam { MPInt x; MPInt::RandomLtN(order, &x); // g1 * x - auto g1x = pairing_group_->GetG1()->MulBase(x); + auto g1x = pairing_group_->GetGroup1()->MulBase(x); // g2 * x - auto g2x = pairing_group_->GetG2()->MulBase(x); + auto g2x = pairing_group_->GetGroup2()->MulBase(x); auto f = pairing_group_->MillerLoop(g1x, g2x); auto f1 = pairing_group_->FinalExp(f); auto f2 = pairing_group_->Pairing(g1x, g2x); - ASSERT_TRUE(gt_field_->Equal(f1, f2)); + ASSERT_TRUE((bool)gt_->Equal(f1, f2)); } } }; @@ -334,8 +335,8 @@ TEST(Pairing_Multi_Instance_Test, Works) { std::shared_ptr pairing = PairingGroupFactory::Instance().Create(pairing_name, ArgLib = lib_name); - pairing->Pairing(pairing->GetG1()->GetGenerator(), - pairing->GetG2()->GetGenerator()); + pairing->Pairing(pairing->GetGroup1()->GetGenerator(), + pairing->GetGroup2()->GetGenerator()); }); } } diff --git a/yacl/crypto/base/pke/BUILD.bazel b/yacl/crypto/base/pke/BUILD.bazel index f920bbb0..b15f5cc0 100644 --- a/yacl/crypto/base/pke/BUILD.bazel +++ b/yacl/crypto/base/pke/BUILD.bazel @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("//bazel:yacl.bzl", "AES_COPT_FLAGS", "yacl_cc_library", "yacl_cc_test") +load("//bazel:yacl.bzl", "yacl_cc_library", "yacl_cc_test") package(default_visibility = ["//visibility:public"]) @@ -32,7 +32,7 @@ yacl_cc_library( ":asymmetric_crypto", "//yacl/base:exception", "//yacl/crypto/base:key_utils", - "@com_google_absl//absl/memory", + "//yacl/crypto/utils:secparam", ], ) @@ -52,7 +52,7 @@ yacl_cc_library( ":asymmetric_crypto", "//yacl/base:exception", "//yacl/crypto/base:key_utils", - "@com_google_absl//absl/memory", + "//yacl/crypto/utils:secparam", ], ) diff --git a/yacl/crypto/base/pke/asymmetric_rsa_crypto.cc b/yacl/crypto/base/pke/asymmetric_rsa_crypto.cc index 51d05a48..71f7df8e 100644 --- a/yacl/crypto/base/pke/asymmetric_rsa_crypto.cc +++ b/yacl/crypto/base/pke/asymmetric_rsa_crypto.cc @@ -14,7 +14,7 @@ #include "yacl/crypto/base/pke/asymmetric_rsa_crypto.h" -#include "absl/memory/memory.h" +#include #include "yacl/base/exception.h" @@ -35,20 +35,20 @@ std::vector RsaEncryptor::Encrypt(ByteContainerView plaintext) { YACL_ENFORCE(ctx != nullptr); // init context - YACL_ENFORCE(EVP_PKEY_encrypt_init(ctx.get()) > 0); + OSSL_RET_1(EVP_PKEY_encrypt_init(ctx.get())); // make sure to use OAEP_PADDING - YACL_ENFORCE(EVP_PKEY_CTX_set_rsa_padding(ctx.get(), kRsaPadding) > 0); + OSSL_RET_1(EVP_PKEY_CTX_set_rsa_padding(ctx.get(), kRsaPadding)); // first, get output length size_t outlen = 0; - YACL_ENFORCE(EVP_PKEY_encrypt(ctx.get(), /* empty input */ nullptr, &outlen, - plaintext.data(), plaintext.size()) > 0); + OSSL_RET_1(EVP_PKEY_encrypt(ctx.get(), /* empty input */ nullptr, &outlen, + plaintext.data(), plaintext.size())); // then encrypt std::vector out(outlen); - YACL_ENFORCE(EVP_PKEY_encrypt(ctx.get(), out.data(), &outlen, - plaintext.data(), plaintext.size()) > 0); + OSSL_RET_1(EVP_PKEY_encrypt(ctx.get(), out.data(), &outlen, plaintext.data(), + plaintext.size())); out.resize(outlen); /* important */ return out; @@ -61,20 +61,20 @@ std::vector RsaDecryptor::Decrypt(ByteContainerView ciphertext) { YACL_ENFORCE(ctx != nullptr); // init context - YACL_ENFORCE(EVP_PKEY_decrypt_init(ctx.get()) > 0); + OSSL_RET_1(EVP_PKEY_decrypt_init(ctx.get())); // make sure to use OAEP_PADDING - YACL_ENFORCE(EVP_PKEY_CTX_set_rsa_padding(ctx.get(), kRsaPadding) > 0); + OSSL_RET_1(EVP_PKEY_CTX_set_rsa_padding(ctx.get(), kRsaPadding)); // first, get output length size_t outlen = 0; - YACL_ENFORCE(EVP_PKEY_decrypt(ctx.get(), /* empty input */ nullptr, &outlen, - ciphertext.data(), ciphertext.size()) > 0); + OSSL_RET_1(EVP_PKEY_decrypt(ctx.get(), /* empty input */ nullptr, &outlen, + ciphertext.data(), ciphertext.size())); // then decrypt std::vector out(outlen); - YACL_ENFORCE(EVP_PKEY_decrypt(ctx.get(), out.data(), &outlen, - ciphertext.data(), ciphertext.size()) > 0); + OSSL_RET_1(EVP_PKEY_decrypt(ctx.get(), out.data(), &outlen, ciphertext.data(), + ciphertext.size())); out.resize(outlen); /* important */ return out; diff --git a/yacl/crypto/base/pke/asymmetric_rsa_crypto.h b/yacl/crypto/base/pke/asymmetric_rsa_crypto.h index 82804693..bcec1096 100644 --- a/yacl/crypto/base/pke/asymmetric_rsa_crypto.h +++ b/yacl/crypto/base/pke/asymmetric_rsa_crypto.h @@ -15,9 +15,15 @@ #pragma once #include +#include +#include #include "yacl/crypto/base/key_utils.h" #include "yacl/crypto/base/pke/asymmetric_crypto.h" +#include "yacl/crypto/utils/secparam.h" + +/* security parameter declaration */ +YACL_MODULE_DECLARE("rsa_enc", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/base/pke/asymmetric_rsa_crypto_test.cc b/yacl/crypto/base/pke/asymmetric_rsa_crypto_test.cc index 0acd037a..c23ee8bb 100644 --- a/yacl/crypto/base/pke/asymmetric_rsa_crypto_test.cc +++ b/yacl/crypto/base/pke/asymmetric_rsa_crypto_test.cc @@ -14,6 +14,8 @@ #include "yacl/crypto/base/pke/asymmetric_rsa_crypto.h" +#include + #include "gtest/gtest.h" #include "yacl/crypto/base/openssl_wrappers.h" diff --git a/yacl/crypto/base/pke/asymmetric_sm2_crypto.cc b/yacl/crypto/base/pke/asymmetric_sm2_crypto.cc index 8883e93c..6d010384 100644 --- a/yacl/crypto/base/pke/asymmetric_sm2_crypto.cc +++ b/yacl/crypto/base/pke/asymmetric_sm2_crypto.cc @@ -14,7 +14,7 @@ #include "yacl/crypto/base/pke/asymmetric_sm2_crypto.h" -#include "absl/memory/memory.h" +#include #include "yacl/base/exception.h" @@ -27,20 +27,17 @@ std::vector Sm2Encryptor::Encrypt(ByteContainerView plaintext) { YACL_ENFORCE(ctx != nullptr); // init context - YACL_ENFORCE(EVP_PKEY_encrypt_init(ctx.get()) > 0); - - // make sure to use OAEP_PADDING - // YACL_ENFORCE(EVP_PKEY_CTX_set_rsa_padding(ctx.get(), kRsaPadding) > 0); + OSSL_RET_1(EVP_PKEY_encrypt_init(ctx.get())); // first, get output length size_t outlen = 0; - YACL_ENFORCE(EVP_PKEY_encrypt(ctx.get(), /* empty input */ nullptr, &outlen, - plaintext.data(), plaintext.size()) > 0); + OSSL_RET_1(EVP_PKEY_encrypt(ctx.get(), /* empty input */ nullptr, &outlen, + plaintext.data(), plaintext.size())); // then encrypt std::vector out(outlen); - YACL_ENFORCE(EVP_PKEY_encrypt(ctx.get(), out.data(), &outlen, - plaintext.data(), plaintext.size()) > 0); + OSSL_RET_1(EVP_PKEY_encrypt(ctx.get(), out.data(), &outlen, plaintext.data(), + plaintext.size())); out.resize(outlen); /* important */ return out; } @@ -52,20 +49,17 @@ std::vector Sm2Decryptor::Decrypt(ByteContainerView ciphertext) { YACL_ENFORCE(ctx != nullptr); // init context - YACL_ENFORCE(EVP_PKEY_decrypt_init(ctx.get()) > 0); - - // make sure to use OAEP_PADDING - // YACL_ENFORCE(EVP_PKEY_CTX_set_rsa_padding(ctx.get(), kRsaPadding) > 0); + OSSL_RET_1(EVP_PKEY_decrypt_init(ctx.get())); // first, get output length size_t outlen = 0; - YACL_ENFORCE(EVP_PKEY_decrypt(ctx.get(), /* empty input */ nullptr, &outlen, - ciphertext.data(), ciphertext.size()) > 0); + OSSL_RET_1(EVP_PKEY_decrypt(ctx.get(), /* empty input */ nullptr, &outlen, + ciphertext.data(), ciphertext.size())); // then decrypt std::vector out(outlen); - YACL_ENFORCE(EVP_PKEY_decrypt(ctx.get(), out.data(), &outlen, - ciphertext.data(), ciphertext.size()) > 0); + OSSL_RET_1(EVP_PKEY_decrypt(ctx.get(), out.data(), &outlen, ciphertext.data(), + ciphertext.size())); out.resize(outlen); /* important */ return out; } diff --git a/yacl/crypto/base/pke/asymmetric_sm2_crypto.h b/yacl/crypto/base/pke/asymmetric_sm2_crypto.h index 991fb815..8ef3757b 100644 --- a/yacl/crypto/base/pke/asymmetric_sm2_crypto.h +++ b/yacl/crypto/base/pke/asymmetric_sm2_crypto.h @@ -15,9 +15,15 @@ #pragma once #include +#include +#include #include "yacl/crypto/base/key_utils.h" #include "yacl/crypto/base/pke/asymmetric_crypto.h" +#include "yacl/crypto/utils/secparam.h" + +/* security parameter declaration */ +YACL_MODULE_DECLARE("sm2_enc", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/base/pke/asymmetric_sm2_crypto_test.cc b/yacl/crypto/base/pke/asymmetric_sm2_crypto_test.cc index 3e8e9f42..b2d6b64d 100644 --- a/yacl/crypto/base/pke/asymmetric_sm2_crypto_test.cc +++ b/yacl/crypto/base/pke/asymmetric_sm2_crypto_test.cc @@ -14,6 +14,8 @@ #include "yacl/crypto/base/pke/asymmetric_sm2_crypto.h" +#include + #include "gtest/gtest.h" #include "yacl/crypto/base/openssl_wrappers.h" diff --git a/yacl/crypto/base/sign/BUILD.bazel b/yacl/crypto/base/sign/BUILD.bazel index edf6e349..16823f2f 100644 --- a/yacl/crypto/base/sign/BUILD.bazel +++ b/yacl/crypto/base/sign/BUILD.bazel @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("//bazel:yacl.bzl", "AES_COPT_FLAGS", "yacl_cc_library", "yacl_cc_test") +load("//bazel:yacl.bzl", "yacl_cc_library", "yacl_cc_test") package(default_visibility = ["//visibility:public"]) @@ -32,6 +32,7 @@ yacl_cc_library( ":signing", "//yacl/crypto/base:key_utils", "//yacl/crypto/base/hash:hash_utils", + "//yacl/crypto/utils:secparam", ], ) @@ -51,6 +52,7 @@ yacl_cc_library( ":signing", "//yacl/crypto/base:key_utils", "//yacl/crypto/base/hash:hash_utils", + "//yacl/crypto/utils:secparam", ], ) diff --git a/yacl/crypto/base/sign/rsa_signing.cc b/yacl/crypto/base/sign/rsa_signing.cc index 1b611960..e4ff4ef3 100644 --- a/yacl/crypto/base/sign/rsa_signing.cc +++ b/yacl/crypto/base/sign/rsa_signing.cc @@ -14,7 +14,7 @@ #include "yacl/crypto/base/sign/rsa_signing.h" -#include "yacl/crypto/base/hash/hash_utils.h" +#include namespace yacl::crypto { @@ -33,28 +33,28 @@ std::vector RsaSigner::Sign(ByteContainerView message) const { YACL_ENFORCE(ctx != nullptr); // init context - YACL_ENFORCE(EVP_PKEY_sign_init(ctx.get()) > 0); + OSSL_RET_1(EVP_PKEY_sign_init(ctx.get())); // make sure to use OAEP_PADDING - YACL_ENFORCE(EVP_PKEY_CTX_set_rsa_padding(ctx.get(), kRsaPadding) > 0); + OSSL_RET_1(EVP_PKEY_CTX_set_rsa_padding(ctx.get(), kRsaPadding)); // use sha256 // EVP_PKEY_CTX_set_signature_md() sets the message digest type used in a // signature. It can be used in the RSA, DSA and ECDSA algorithms. - YACL_ENFORCE(EVP_PKEY_CTX_set_signature_md(ctx.get(), EVP_sha256()) > 0); + OSSL_RET_1(EVP_PKEY_CTX_set_signature_md(ctx.get(), EVP_sha256())); // sha256 on the message auto md = Sha256(message); // first, get output length size_t outlen = 0; - YACL_ENFORCE(EVP_PKEY_sign(ctx.get(), /* empty input */ nullptr, &outlen, - md.data(), md.size()) > 0); + OSSL_RET_1(EVP_PKEY_sign(ctx.get(), /* empty input */ nullptr, &outlen, + md.data(), md.size())); // then sign std::vector out(outlen); - YACL_ENFORCE( - EVP_PKEY_sign(ctx.get(), out.data(), &outlen, md.data(), md.size()) > 0); + OSSL_RET_1( + EVP_PKEY_sign(ctx.get(), out.data(), &outlen, md.data(), md.size())); return out; } @@ -67,15 +67,15 @@ bool RsaVerifier::Verify(ByteContainerView message, YACL_ENFORCE(ctx != nullptr); // init context - YACL_ENFORCE(EVP_PKEY_verify_init(ctx.get()) > 0); + OSSL_RET_1(EVP_PKEY_verify_init(ctx.get())); // make sure to use OAEP_PADDING - YACL_ENFORCE(EVP_PKEY_CTX_set_rsa_padding(ctx.get(), kRsaPadding) > 0); + OSSL_RET_1(EVP_PKEY_CTX_set_rsa_padding(ctx.get(), kRsaPadding)); // use sha256 // EVP_PKEY_CTX_set_signature_md() sets the message digest type used in a // signature. It can be used in the RSA, DSA and ECDSA algorithms. - YACL_ENFORCE(EVP_PKEY_CTX_set_signature_md(ctx.get(), EVP_sha256()) > 0); + OSSL_RET_1(EVP_PKEY_CTX_set_signature_md(ctx.get(), EVP_sha256())); // sha256 on the message auto md = Sha256(message); diff --git a/yacl/crypto/base/sign/rsa_signing.h b/yacl/crypto/base/sign/rsa_signing.h index f8a232e1..ca48537a 100644 --- a/yacl/crypto/base/sign/rsa_signing.h +++ b/yacl/crypto/base/sign/rsa_signing.h @@ -14,8 +14,18 @@ #pragma once +#include +#include + #include "yacl/crypto/base/key_utils.h" #include "yacl/crypto/base/sign/signing.h" +#include "yacl/crypto/utils/secparam.h" + +/* submodules */ +#include "yacl/crypto/base/hash/hash_utils.h" + +/* security parameter declaration */ +YACL_MODULE_DECLARE("rsa_sign", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/base/sign/rsa_signing_test.cc b/yacl/crypto/base/sign/rsa_signing_test.cc index b31813c2..e7642728 100644 --- a/yacl/crypto/base/sign/rsa_signing_test.cc +++ b/yacl/crypto/base/sign/rsa_signing_test.cc @@ -14,6 +14,8 @@ #include "yacl/crypto/base/sign/rsa_signing.h" +#include + #include "gtest/gtest.h" #include "yacl/crypto/base/openssl_wrappers.h" diff --git a/yacl/crypto/base/sign/signing.h b/yacl/crypto/base/sign/signing.h index a7abb820..272684da 100644 --- a/yacl/crypto/base/sign/signing.h +++ b/yacl/crypto/base/sign/signing.h @@ -29,18 +29,14 @@ enum class SignatureScheme : int { class AsymmetricSigner { public: virtual ~AsymmetricSigner() = default; - virtual SignatureScheme GetSignatureSchema() const = 0; - virtual std::vector Sign(ByteContainerView message) const = 0; }; class AsymmetricVerifier { public: virtual ~AsymmetricVerifier() = default; - virtual SignatureScheme GetSignatureSchema() const = 0; - virtual bool Verify(ByteContainerView message, ByteContainerView signature) const = 0; }; diff --git a/yacl/crypto/base/sign/sm2_signing.cc b/yacl/crypto/base/sign/sm2_signing.cc index bbbd5f32..e80a4c46 100644 --- a/yacl/crypto/base/sign/sm2_signing.cc +++ b/yacl/crypto/base/sign/sm2_signing.cc @@ -14,8 +14,6 @@ #include "yacl/crypto/base/sign/sm2_signing.h" -#include "yacl/crypto/base/hash/hash_utils.h" - namespace yacl::crypto { namespace { @@ -44,21 +42,19 @@ std::vector Sm2Signer::Sign(ByteContainerView message) const { EVP_MD_CTX_set_pkey_ctx(mctx.get(), ctx.get()); // set it related to pkey ctx // init sign - YACL_ENFORCE(EVP_DigestSignInit( - mctx.get(), /* pkey ctx has already been inited */ nullptr, - EVP_sm3(), - /* engine */ nullptr, sk_.get()) > 0); + OSSL_RET_1(EVP_DigestSignInit( + mctx.get(), /* pkey ctx has already been inited */ nullptr, EVP_sm3(), + /* engine */ nullptr, sk_.get())); // write hashes of message into mctx - YACL_ENFORCE( - EVP_DigestSignUpdate(mctx.get(), message.data(), message.size()) > 0); + OSSL_RET_1(EVP_DigestSignUpdate(mctx.get(), message.data(), message.size())); // get output size size_t outlen = 0; - YACL_ENFORCE(EVP_DigestSignFinal(mctx.get(), nullptr, &outlen) > 0); + OSSL_RET_1(EVP_DigestSignFinal(mctx.get(), nullptr, &outlen)); std::vector out(outlen); - YACL_ENFORCE(EVP_DigestSignFinal(mctx.get(), out.data(), &outlen) > 0); + OSSL_RET_1(EVP_DigestSignFinal(mctx.get(), out.data(), &outlen)); // Correct the signature size (this is necessary! TODO: find out why) out.resize(outlen); @@ -79,12 +75,12 @@ bool Sm2Verifier::Verify(ByteContainerView message, EVP_MD_CTX_set_pkey_ctx(mctx.get(), ctx.get()); - YACL_ENFORCE(EVP_DigestVerifyInit( - mctx.get(), /* pkey ctx has already been inited */ nullptr, - EVP_sm3(), /* engine */ nullptr, pk_.get()) > 0); + OSSL_RET_1(EVP_DigestVerifyInit( + mctx.get(), /* pkey ctx has already been inited */ nullptr, EVP_sm3(), + /* engine */ nullptr, pk_.get())); - YACL_ENFORCE( - EVP_DigestVerifyUpdate(mctx.get(), message.data(), message.size()) > 0); + OSSL_RET_1( + EVP_DigestVerifyUpdate(mctx.get(), message.data(), message.size())); int rc = EVP_DigestVerifyFinal(mctx.get(), signature.data(), signature.size()); diff --git a/yacl/crypto/base/sign/sm2_signing.h b/yacl/crypto/base/sign/sm2_signing.h index 3b540b20..6a8c342e 100644 --- a/yacl/crypto/base/sign/sm2_signing.h +++ b/yacl/crypto/base/sign/sm2_signing.h @@ -14,8 +14,18 @@ #pragma once +#include +#include + #include "yacl/crypto/base/key_utils.h" #include "yacl/crypto/base/sign/signing.h" +#include "yacl/crypto/utils/secparam.h" + +/* submodules */ +#include "yacl/crypto/base/hash/hash_utils.h" + +/* security parameter declaration */ +YACL_MODULE_DECLARE("sm2_sign", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { @@ -26,7 +36,7 @@ class Sm2Signer final : public AsymmetricSigner { explicit Sm2Signer(/* pem key */ ByteContainerView sk_buf) : sk_(LoadKeyFromBuf(sk_buf)) {} - SignatureScheme GetSignatureSchema() const override { return scheme_; }; + SignatureScheme GetSignatureSchema() const override { return scheme_; } // Sign message with the default id. std::vector Sign(ByteContainerView message) const override; @@ -56,6 +66,6 @@ class Sm2Verifier final : public AsymmetricVerifier { const SignatureScheme scheme_ = SignatureScheme::SM2_SIGNING_SM3_HASH; }; -// TODO @raofei: support sm2 certificate +// TODO(@raofei, @shanzhu): support sm2 certificate } // namespace yacl::crypto diff --git a/yacl/crypto/base/sign/sm2_signing_test.cc b/yacl/crypto/base/sign/sm2_signing_test.cc index 44aff363..ec01a0c6 100644 --- a/yacl/crypto/base/sign/sm2_signing_test.cc +++ b/yacl/crypto/base/sign/sm2_signing_test.cc @@ -14,6 +14,8 @@ #include "yacl/crypto/base/sign/sm2_signing.h" +#include + #include "gtest/gtest.h" #include "yacl/crypto/base/openssl_wrappers.h" diff --git a/yacl/crypto/provider/BUILD.bazel b/yacl/crypto/ossl-provider/BUILD.bazel similarity index 100% rename from yacl/crypto/provider/BUILD.bazel rename to yacl/crypto/ossl-provider/BUILD.bazel diff --git a/yacl/crypto/provider/helper.h b/yacl/crypto/ossl-provider/helper.h similarity index 96% rename from yacl/crypto/provider/helper.h rename to yacl/crypto/ossl-provider/helper.h index 8232bfb2..18578592 100644 --- a/yacl/crypto/provider/helper.h +++ b/yacl/crypto/ossl-provider/helper.h @@ -56,7 +56,7 @@ inline std::string GetProviderPath() { std::string path1; std::string path2; std::string path3 = - fmt::format("/yacl/crypto/provider/libprov_shared{}", SO_EXT); + fmt::format("/yacl/crypto/ossl-provider/libprov_shared{}", SO_EXT); // step 1: determine if target is "cc_test" or "cc_library" if (selfdir_str.find("sandbox") != std::string::npos) { diff --git a/yacl/crypto/provider/linux_exported_syms.lds b/yacl/crypto/ossl-provider/linux_exported_syms.lds similarity index 100% rename from yacl/crypto/provider/linux_exported_syms.lds rename to yacl/crypto/ossl-provider/linux_exported_syms.lds diff --git a/yacl/crypto/provider/macos_exported_syms.lds b/yacl/crypto/ossl-provider/macos_exported_syms.lds similarity index 100% rename from yacl/crypto/provider/macos_exported_syms.lds rename to yacl/crypto/ossl-provider/macos_exported_syms.lds diff --git a/yacl/crypto/provider/provider.cc b/yacl/crypto/ossl-provider/provider.cc similarity index 97% rename from yacl/crypto/provider/provider.cc rename to yacl/crypto/ossl-provider/provider.cc index 201b9489..a8f87d91 100644 --- a/yacl/crypto/provider/provider.cc +++ b/yacl/crypto/ossl-provider/provider.cc @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "yacl/crypto/provider/rand_impl.h" -#include "yacl/crypto/provider/version.h" +#include "yacl/crypto/ossl-provider/rand_impl.h" +#include "yacl/crypto/ossl-provider/version.h" using FuncPtr = void (*)(); diff --git a/yacl/crypto/provider/provider_test.cc b/yacl/crypto/ossl-provider/provider_test.cc similarity index 99% rename from yacl/crypto/provider/provider_test.cc rename to yacl/crypto/ossl-provider/provider_test.cc index fd06befb..9921d48e 100644 --- a/yacl/crypto/provider/provider_test.cc +++ b/yacl/crypto/ossl-provider/provider_test.cc @@ -24,7 +24,7 @@ #include "openssl/randerr.h" #include "yacl/crypto/base/openssl_wrappers.h" -#include "yacl/crypto/provider/helper.h" +#include "yacl/crypto/ossl-provider/helper.h" namespace yacl::crypto { diff --git a/yacl/crypto/provider/rand_impl.h b/yacl/crypto/ossl-provider/rand_impl.h similarity index 100% rename from yacl/crypto/provider/rand_impl.h rename to yacl/crypto/ossl-provider/rand_impl.h diff --git a/yacl/crypto/provider/version.h b/yacl/crypto/ossl-provider/version.h similarity index 100% rename from yacl/crypto/provider/version.h rename to yacl/crypto/ossl-provider/version.h diff --git a/yacl/crypto/primitives/dpf/dpf.cc b/yacl/crypto/primitives/dpf/dpf.cc index a76c85d8..9a23d4d4 100644 --- a/yacl/crypto/primitives/dpf/dpf.cc +++ b/yacl/crypto/primitives/dpf/dpf.cc @@ -12,16 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "dpf.h" +#include "yacl/crypto/primitives/dpf/dpf.h" -#include #include #include #include "spdlog/spdlog.h" -#include "yacl/crypto/tools/prg.h" - #include "yacl/crypto/primitives/dpf/serializable.pb.h" namespace yacl::crypto { @@ -45,7 +42,7 @@ std::tuple SplitDpfSeed(uint128_t seed) { bool t_left; bool t_right; - // TODO: check if this implementation is secure and efficient + // TODO(@shanzhu.cjm): check if this implementation is secure and efficient Prg prng(seed); seed_left = prng(); @@ -61,9 +58,9 @@ std::tuple SplitDpfSeed(uint128_t seed) { } // namespace -///////////////////////////////////////////////////////////////////////////////////// +// ----------------------------------------- // Full domain key generation and evaluation -///////////////////////////////////////////////////////////////////////////////////// +// ----------------------------------------- void DpfContext::Gen(DpfKey& first_key, DpfKey& second_key, DpfInStore alpha, DpfOutStore beta, uint128_t first_mk, uint128_t second_mk, diff --git a/yacl/crypto/primitives/dpf/dpf.h b/yacl/crypto/primitives/dpf/dpf.h index 94f261cd..7cf43680 100644 --- a/yacl/crypto/primitives/dpf/dpf.h +++ b/yacl/crypto/primitives/dpf/dpf.h @@ -14,17 +14,23 @@ #pragma once +#include #include #include #include +#include #include #include #include +#include #include #include "yacl/base/exception.h" #include "yacl/base/int128.h" +/* submodules */ +#include "yacl/crypto/tools/prg.h" + namespace yacl::crypto { // Implementation of Distributed Point Function (DPF) @@ -71,7 +77,7 @@ class DpfKey { // empty constructor DpfKey() = default; - DpfKey(bool rank, const uint128_t mseed) : rank_(rank), mseed_(mseed){}; + DpfKey(bool rank, const uint128_t mseed) : rank_(rank), mseed_(mseed) {} DpfKey(bool rank, size_t in_bitnum, size_t ss_bitnum, uint32_t sec_param, const uint128_t mseed) @@ -79,7 +85,7 @@ class DpfKey { in_bitnum_(in_bitnum), ss_bitnum_(ss_bitnum), sec_param_(sec_param), - mseed_(mseed){}; + mseed_(mseed) {} void EnableEvalAll() { enable_evalall = true; } void DisableFullEval() { enable_evalall = false; } @@ -111,10 +117,10 @@ class DpfContext { // constructors DpfContext() = default; - explicit DpfContext(size_t in_bitnum) : in_bitnum_(in_bitnum){}; + explicit DpfContext(size_t in_bitnum) : in_bitnum_(in_bitnum) {} DpfContext(size_t in_bitnum, size_t ss_bitnum) - : in_bitnum_(in_bitnum), ss_bitnum_(ss_bitnum){}; + : in_bitnum_(in_bitnum), ss_bitnum_(ss_bitnum) {} void SetInBitNum(size_t in_bitnum) { YACL_ENFORCE(in_bitnum <= 64); @@ -128,9 +134,9 @@ class DpfContext { } size_t GetSsBitNum() const { return ss_bitnum_; } - ///////////////////////////////////////////////////////////////////////////////////// + // -------------------------------------- // Original key generation and evaluation - ///////////////////////////////////////////////////////////////////////////////////// + // -------------------------------------- std::pair Gen(DpfInStore alpha, DpfOutStore beta, uint128_t first_mk, uint128_t second_mk, bool enable_evalall = false) { diff --git a/yacl/crypto/primitives/ot/BUILD.bazel b/yacl/crypto/primitives/ot/BUILD.bazel index b49e1a22..86870e55 100644 --- a/yacl/crypto/primitives/ot/BUILD.bazel +++ b/yacl/crypto/primitives/ot/BUILD.bazel @@ -53,6 +53,7 @@ yacl_cc_library( ":base_ot_interface", "//yacl/base:exception", "//yacl/crypto/tools:ro", + "//yacl/crypto/utils:secparam", "//yacl/link", "@simplest_ot//:simplest_ot_portable", ], @@ -70,6 +71,7 @@ yacl_cc_library( ":base_ot_interface", "//yacl/base:exception", "//yacl/crypto/tools:ro", + "//yacl/crypto/utils:secparam", "//yacl/link", "//yacl/math:gadget", "@simplest_ot//:simplest_ot_x86_asm", @@ -224,12 +226,14 @@ yacl_cc_test( yacl_cc_library( name = "ferret_ote", - srcs = ["ferret_ote.cc"], - hdrs = [ - "ferret_ote.h", + srcs = [ + "ferret_ote.cc", "ferret_ote_rn.h", "ferret_ote_un.h", ], + hdrs = [ + "ferret_ote.h", + ], deps = [ ":ot_store", "//yacl/base:exception", diff --git a/yacl/crypto/primitives/ot/base_ot.cc b/yacl/crypto/primitives/ot/base_ot.cc index 78efcb7a..42800cfa 100644 --- a/yacl/crypto/primitives/ot/base_ot.cc +++ b/yacl/crypto/primitives/ot/base_ot.cc @@ -14,12 +14,6 @@ #include "yacl/crypto/primitives/ot/base_ot.h" -#if defined(__linux__) && defined(__x86_64) -#include "yacl/crypto/primitives/ot/x86_asm_ot_interface.h" -#else -#include "yacl/crypto/primitives/ot/portable_ot_interface.h" -#endif - #include "yacl/base/exception.h" namespace yacl::crypto { diff --git a/yacl/crypto/primitives/ot/base_ot.h b/yacl/crypto/primitives/ot/base_ot.h index 44b74e8b..26586057 100644 --- a/yacl/crypto/primitives/ot/base_ot.h +++ b/yacl/crypto/primitives/ot/base_ot.h @@ -25,7 +25,15 @@ #include "yacl/crypto/utils/secparam.h" #include "yacl/link/link.h" -YACL_MODULE_DECLARE("base_ot", SecParam::C::k128, SecParam::S::INF); +/* submodules */ +#if defined(__linux__) && defined(__x86_64) +#include "yacl/crypto/primitives/ot/x86_asm_ot_interface.h" +#else +#include "yacl/crypto/primitives/ot/portable_ot_interface.h" +#endif + +/* security parameter declaration */ +// this module is only a wrapper, no need for security parameter definition namespace yacl::crypto { diff --git a/yacl/crypto/primitives/ot/benchmark.h b/yacl/crypto/primitives/ot/benchmark.h index a2ef2166..b069ac1c 100644 --- a/yacl/crypto/primitives/ot/benchmark.h +++ b/yacl/crypto/primitives/ot/benchmark.h @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#pragma once + #include #include #include diff --git a/yacl/crypto/primitives/ot/ferret_ote.cc b/yacl/crypto/primitives/ot/ferret_ote.cc index fb80b78d..0a482a61 100644 --- a/yacl/crypto/primitives/ot/ferret_ote.cc +++ b/yacl/crypto/primitives/ot/ferret_ote.cc @@ -20,12 +20,6 @@ #include #include "yacl/base/aligned_vector.h" -#include "yacl/crypto/primitives/code/linear_code.h" -#include "yacl/crypto/primitives/ot/ferret_ote_rn.h" -#include "yacl/crypto/primitives/ot/ferret_ote_un.h" -#include "yacl/crypto/primitives/ot/gywz_ote.h" -#include "yacl/crypto/primitives/ot/ot_store.h" -#include "yacl/math/gadget.h" #include "yacl/utils/cuckoo_index.h" #include "yacl/utils/serialize.h" diff --git a/yacl/crypto/primitives/ot/ferret_ote.h b/yacl/crypto/primitives/ot/ferret_ote.h index 359aa476..8441a219 100644 --- a/yacl/crypto/primitives/ot/ferret_ote.h +++ b/yacl/crypto/primitives/ot/ferret_ote.h @@ -23,6 +23,16 @@ #include "yacl/crypto/utils/secparam.h" #include "yacl/math/gadget.h" #include "yacl/utils/cuckoo_index.h" + +/* submodules */ +#include "yacl/crypto/primitives/code/linear_code.h" +#include "yacl/crypto/primitives/ot/ferret_ote_rn.h" +#include "yacl/crypto/primitives/ot/ferret_ote_un.h" +#include "yacl/crypto/primitives/ot/gywz_ote.h" + +/* security parameter declaration */ +// this module is only a wrapper, no need for security parameter definition + namespace yacl::crypto { // Ferret OT Extension Implementation diff --git a/yacl/crypto/primitives/ot/ferret_ote_rn.h b/yacl/crypto/primitives/ot/ferret_ote_rn.h index 7721d13c..33d95fdf 100644 --- a/yacl/crypto/primitives/ot/ferret_ote_rn.h +++ b/yacl/crypto/primitives/ot/ferret_ote_rn.h @@ -18,23 +18,26 @@ #include #include -#include "yacl/crypto/primitives/ot/ferret_ote.h" -#include "yacl/crypto/primitives/ot/gywz_ote.h" #include "yacl/crypto/utils/secparam.h" +#include "yacl/math/gadget.h" + +/* submodules */ +#include "yacl/crypto/primitives/ot/gywz_ote.h" +/* security parameter declaration */ YACL_MODULE_DECLARE("ferret_ote_rn", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { -uint64_t MpCotRNHelper(uint64_t idx_num, uint64_t idx_range) { +inline uint64_t MpCotRNHelper(uint64_t idx_num, uint64_t idx_range) { const auto batch_size = (idx_range + idx_num - 1) / idx_num; const auto last_size = idx_range - batch_size * (idx_num - 1); return math::Log2Ceil(batch_size) * (idx_num - 1) + math::Log2Ceil(last_size); } -void MpCotRNSend(const std::shared_ptr& ctx, - const OtSendStore& cot, uint64_t idx_range, uint64_t idx_num, - absl::Span out) { +inline void MpCotRNSend(const std::shared_ptr& ctx, + const OtSendStore& cot, uint64_t idx_range, + uint64_t idx_num, absl::Span out) { const auto full_size = idx_range; const auto batch_num = idx_num; const auto batch_size = full_size / batch_num; @@ -52,9 +55,9 @@ void MpCotRNSend(const std::shared_ptr& ctx, } } -void MpCotRNRecv(const std::shared_ptr& ctx, - const OtRecvStore& cot, uint64_t idx_range, uint64_t idx_num, - absl::Span out) { +inline void MpCotRNRecv(const std::shared_ptr& ctx, + const OtRecvStore& cot, uint64_t idx_range, + uint64_t idx_num, absl::Span out) { const auto full_size = idx_range; const auto batch_num = idx_num; const auto batch_size = full_size / batch_num; diff --git a/yacl/crypto/primitives/ot/ferret_ote_un.h b/yacl/crypto/primitives/ot/ferret_ote_un.h index 3583ed8c..c7b9c9f4 100644 --- a/yacl/crypto/primitives/ot/ferret_ote_un.h +++ b/yacl/crypto/primitives/ot/ferret_ote_un.h @@ -19,13 +19,15 @@ #include #include -#include "yacl/crypto/primitives/ot/ferret_ote.h" -#include "yacl/crypto/primitives/ot/gywz_ote.h" -#include "yacl/crypto/tools/rp.h" #include "yacl/crypto/utils/secparam.h" #include "yacl/math/gadget.h" #include "yacl/utils/cuckoo_index.h" +/* submodules */ +#include "yacl/crypto/primitives/ot/gywz_ote.h" +#include "yacl/crypto/tools/rp.h" + +/* security parameter declaration */ YACL_MODULE_DECLARE("ferret_ote_un", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { @@ -39,7 +41,7 @@ constexpr auto kFerretCuckooStashNum = 0; const auto kRP = RP(kFerretRpType, kFerretRpSeed); // for cuckoo // create simple map -std::unique_ptr MakeSimpleMap( +inline std::unique_ptr MakeSimpleMap( const CuckooIndex::Options& options, uint64_t n) { const auto bin_num = options.NumBins(); @@ -95,18 +97,18 @@ std::unique_ptr MakeSimpleMap( // Security assumptions: // > SpCotSend / SpCotRecv (see previous codes in this file) -uint64_t MpCotUNHelper(uint64_t idx_num, uint64_t idx_range) { +inline uint64_t MpCotUNHelper(uint64_t idx_num, uint64_t idx_range) { auto option = CuckooIndex::SelectParams(idx_num, kFerretCuckooStashNum, kFerretCuckooHashNum); // [note] this is larger than the actual required cot num return math::Log2Ceil(idx_range) * option.NumBins(); } -void MpCotUNSend(const std::shared_ptr& ctx, - const OtSendStore& cot, - const std::unique_ptr& simple_map, - const CuckooIndex::Options& cuckoo_option, - absl::Span out) { +inline void MpCotUNSend(const std::shared_ptr& ctx, + const OtSendStore& cot, + const std::unique_ptr& simple_map, + const CuckooIndex::Options& cuckoo_option, + absl::Span out) { const uint64_t bin_num = cuckoo_option.NumBins(); // for each bin, call single-point cot @@ -138,11 +140,12 @@ void MpCotUNSend(const std::shared_ptr& ctx, } } -void MpCotUNRecv(const std::shared_ptr& ctx, - const OtRecvStore& cot, - const std::unique_ptr& simple_map, - const CuckooIndex::Options& cuckoo_option, - absl::Span idxes, absl::Span out) { +inline void MpCotUNRecv(const std::shared_ptr& ctx, + const OtRecvStore& cot, + const std::unique_ptr& simple_map, + const CuckooIndex::Options& cuckoo_option, + absl::Span idxes, + absl::Span out) { const uint64_t bin_num = cuckoo_option.NumBins(); // random permutation diff --git a/yacl/crypto/primitives/ot/gywz_ote.cc b/yacl/crypto/primitives/ot/gywz_ote.cc index 5fed04a6..25eb9a34 100644 --- a/yacl/crypto/primitives/ot/gywz_ote.cc +++ b/yacl/crypto/primitives/ot/gywz_ote.cc @@ -20,10 +20,6 @@ #include "yacl/base/byte_container_view.h" #include "yacl/base/dynamic_bitset.h" #include "yacl/base/exception.h" -#include "yacl/crypto/base/aes/aes_opt.h" -#include "yacl/crypto/primitives/ot/ot_store.h" -#include "yacl/crypto/tools/crhash.h" -#include "yacl/crypto/tools/prg.h" #include "yacl/math/gadget.h" namespace yacl::crypto { diff --git a/yacl/crypto/primitives/ot/gywz_ote.h b/yacl/crypto/primitives/ot/gywz_ote.h index 6d1f2edd..566a60b3 100644 --- a/yacl/crypto/primitives/ot/gywz_ote.h +++ b/yacl/crypto/primitives/ot/gywz_ote.h @@ -19,12 +19,18 @@ #include "absl/types/span.h" #include "yacl/base/int128.h" +#include "yacl/crypto/utils/secparam.h" +#include "yacl/link/link.h" + +/* submodules */ +#include "yacl/crypto/base/aes/aes_opt.h" #include "yacl/crypto/primitives/ot/gywz_ote.h" #include "yacl/crypto/primitives/ot/ot_store.h" +#include "yacl/crypto/tools/crhash.h" +#include "yacl/crypto/tools/prg.h" #include "yacl/crypto/utils/rand.h" -#include "yacl/crypto/utils/secparam.h" -#include "yacl/link/link.h" +/* security parameter declaration */ YACL_MODULE_DECLARE("gywz_ote", SecParam::C::INF, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/primitives/ot/iknp_ote.cc b/yacl/crypto/primitives/ot/iknp_ote.cc index 61aac5d5..f43cca78 100644 --- a/yacl/crypto/primitives/ot/iknp_ote.cc +++ b/yacl/crypto/primitives/ot/iknp_ote.cc @@ -18,10 +18,6 @@ #include #include -#include "yacl/crypto/tools/prg.h" -#include "yacl/crypto/tools/rp.h" -#include "yacl/utils/matrix_utils.h" - namespace yacl::crypto { namespace { diff --git a/yacl/crypto/primitives/ot/iknp_ote.h b/yacl/crypto/primitives/ot/iknp_ote.h index ff86312a..756e72d5 100644 --- a/yacl/crypto/primitives/ot/iknp_ote.h +++ b/yacl/crypto/primitives/ot/iknp_ote.h @@ -21,10 +21,16 @@ #include "yacl/base/dynamic_bitset.h" #include "yacl/crypto/primitives/ot/ot_store.h" -#include "yacl/crypto/tools/crhash.h" #include "yacl/crypto/utils/secparam.h" #include "yacl/link/link.h" +#include "yacl/utils/matrix_utils.h" + +/* submodules */ +#include "yacl/crypto/tools/crhash.h" +#include "yacl/crypto/tools/prg.h" +#include "yacl/crypto/tools/rp.h" +/* security parameter declaration */ YACL_MODULE_DECLARE("iknp_ote", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/primitives/ot/kkrt_ote.cc b/yacl/crypto/primitives/ot/kkrt_ote.cc index 805d5b97..3a125d46 100644 --- a/yacl/crypto/primitives/ot/kkrt_ote.cc +++ b/yacl/crypto/primitives/ot/kkrt_ote.cc @@ -18,21 +18,13 @@ #include #include -#include "c/blake3.h" - #include "yacl/base/block.h" #include "yacl/base/byte_container_view.h" #include "yacl/base/int128.h" -#include "yacl/crypto/base/aes/aes_opt.h" -#include "yacl/crypto/base/block_cipher/symmetric_crypto.h" -#include "yacl/crypto/base/hash/hash_utils.h" -#include "yacl/crypto/tools/prg.h" -#include "yacl/crypto/tools/ro.h" -#include "yacl/crypto/utils/rand.h" #include "yacl/utils/matrix_utils.h" #include "yacl/utils/serialize.h" -namespace yacl::crypto { +namespace yacl::crypto { namespace { constexpr int kKappa = YACL_MODULE_SECPARAM_C_UINT("kkrt_ote"); @@ -80,7 +72,8 @@ class KkrtGroupPRF : public IGroupPRF { size_t Size() const override { return size_; } - // According to KKRT paper, the final PRF output should be: H(q ^ (c(r) & s)) + // According to KKRT paper, the final PRF output should be: H(q ^ (c(r) & + // s)) uint128_t Eval(size_t group_idx, uint128_t input) override { YACL_ENFORCE_LT(group_idx, size_); KkrtRow prc_buf; @@ -95,7 +88,8 @@ class KkrtGroupPRF : public IGroupPRF { return RO_Blake3_128(ByteContainerView(prc_buf.data(), sizeof(prc_buf))); } - // According to KKRT paper, the final PRF output should be: H(q ^ (c(r) & s)) + // According to KKRT paper, the final PRF output should be: H(q ^ (c(r) & + // s)) void Eval(size_t group_idx, uint128_t input, uint8_t* outbuf, size_t bufsize) override { YACL_ENFORCE_LT(group_idx, size_); diff --git a/yacl/crypto/primitives/ot/kkrt_ote.h b/yacl/crypto/primitives/ot/kkrt_ote.h index 2462a9ba..d821f686 100644 --- a/yacl/crypto/primitives/ot/kkrt_ote.h +++ b/yacl/crypto/primitives/ot/kkrt_ote.h @@ -19,11 +19,20 @@ #include "absl/types/span.h" -#include "yacl/crypto/base/aes/aes_intrinsics.h" #include "yacl/crypto/primitives/ot/ot_store.h" #include "yacl/crypto/utils/secparam.h" #include "yacl/link/link.h" +/* submodules */ +#include "yacl/crypto/base/aes/aes_intrinsics.h" +#include "yacl/crypto/base/aes/aes_opt.h" +#include "yacl/crypto/base/block_cipher/symmetric_crypto.h" +#include "yacl/crypto/base/hash/hash_utils.h" +#include "yacl/crypto/tools/prg.h" +#include "yacl/crypto/tools/ro.h" +#include "yacl/crypto/utils/rand.h" + +/* security parameter declaration */ YACL_MODULE_DECLARE("kkrt_ote", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/primitives/ot/kos_ote.cc b/yacl/crypto/primitives/ot/kos_ote.cc index ea17bfe0..bdb5824f 100644 --- a/yacl/crypto/primitives/ot/kos_ote.cc +++ b/yacl/crypto/primitives/ot/kos_ote.cc @@ -16,16 +16,11 @@ #include #include -#include #include #include #include "yacl/base/byte_container_view.h" #include "yacl/base/int128.h" -#include "yacl/crypto/tools/crhash.h" -#include "yacl/crypto/tools/prg.h" -#include "yacl/crypto/tools/rp.h" -#include "yacl/crypto/utils/rand.h" #include "yacl/math/f2k/f2k.h" #include "yacl/utils/matrix_utils.h" #include "yacl/utils/serialize.h" @@ -212,7 +207,7 @@ void KosOtExtSend(const std::shared_ptr& ctx, auto& batch0 = q_ext; auto batch1 = VecXorMonochrome(absl::MakeSpan(q_ext), delta); - if (cot == false) { + if (!cot) { ParaCrHashInplace_128(absl::MakeSpan(batch0)); ParaCrHashInplace_128(absl::MakeSpan(batch1)); } @@ -309,7 +304,7 @@ void KosOtExtRecv(const std::shared_ptr& ctx, } t_ext.resize(ot_num_valid); - if (cot == false) { + if (!cot) { ParaCrHashInplace_128(absl::MakeSpan(t_ext)); } for (size_t i = 0; i < ot_num_valid; i++) { diff --git a/yacl/crypto/primitives/ot/kos_ote.h b/yacl/crypto/primitives/ot/kos_ote.h index cf3e6400..21c84a31 100644 --- a/yacl/crypto/primitives/ot/kos_ote.h +++ b/yacl/crypto/primitives/ot/kos_ote.h @@ -23,6 +23,13 @@ #include "yacl/crypto/utils/secparam.h" #include "yacl/link/link.h" +/* submodules */ +#include "yacl/crypto/tools/crhash.h" +#include "yacl/crypto/tools/prg.h" +#include "yacl/crypto/tools/rp.h" +#include "yacl/crypto/utils/rand.h" + +/* security parameter declaration */ YACL_MODULE_DECLARE("kos_ote", SecParam::C::k128, SecParam::S::k64); namespace yacl::crypto { diff --git a/yacl/crypto/primitives/ot/portable_ot_interface.h b/yacl/crypto/primitives/ot/portable_ot_interface.h index a3e6eab4..8ce2c788 100644 --- a/yacl/crypto/primitives/ot/portable_ot_interface.h +++ b/yacl/crypto/primitives/ot/portable_ot_interface.h @@ -14,6 +14,8 @@ #pragma once +#include + #ifndef HAS_OT_INTERFACE #define HAS_OT_INTERFACE #else @@ -21,6 +23,10 @@ #endif #include "yacl/crypto/primitives/ot/base_ot_interface.h" +#include "yacl/crypto/utils/secparam.h" + +/* security parameter declaration */ +YACL_MODULE_DECLARE("base_ot_portable", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/primitives/ot/sgrr_ote.cc b/yacl/crypto/primitives/ot/sgrr_ote.cc index 7e53aa3b..0ead682d 100644 --- a/yacl/crypto/primitives/ot/sgrr_ote.cc +++ b/yacl/crypto/primitives/ot/sgrr_ote.cc @@ -25,12 +25,6 @@ #include "yacl/base/dynamic_bitset.h" #include "yacl/base/exception.h" #include "yacl/base/int128.h" -#include "yacl/crypto/base/aes/aes_opt.h" -#include "yacl/crypto/tools/crhash.h" -#include "yacl/crypto/tools/prg.h" -#include "yacl/crypto/tools/ro.h" -#include "yacl/crypto/tools/rp.h" -#include "yacl/crypto/utils/rand.h" #include "yacl/math/gadget.h" namespace yacl::crypto { diff --git a/yacl/crypto/primitives/ot/sgrr_ote.h b/yacl/crypto/primitives/ot/sgrr_ote.h index b3fc4707..da9bb54b 100644 --- a/yacl/crypto/primitives/ot/sgrr_ote.h +++ b/yacl/crypto/primitives/ot/sgrr_ote.h @@ -19,10 +19,18 @@ #include "absl/types/span.h" #include "yacl/crypto/primitives/ot/ot_store.h" -#include "yacl/crypto/utils/rand.h" #include "yacl/crypto/utils/secparam.h" #include "yacl/link/link.h" +/* submodules */ +#include "yacl/crypto/base/aes/aes_opt.h" +#include "yacl/crypto/tools/crhash.h" +#include "yacl/crypto/tools/prg.h" +#include "yacl/crypto/tools/ro.h" +#include "yacl/crypto/tools/rp.h" +#include "yacl/crypto/utils/rand.h" + +/* security parameter declaration */ YACL_MODULE_DECLARE("sgrr_ote", SecParam::C::INF, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/primitives/ot/softspoken_ote.cc b/yacl/crypto/primitives/ot/softspoken_ote.cc index 51aa9c4a..f27a784e 100644 --- a/yacl/crypto/primitives/ot/softspoken_ote.cc +++ b/yacl/crypto/primitives/ot/softspoken_ote.cc @@ -16,17 +16,14 @@ #include +#include #include #include #include "yacl/base/aligned_vector.h" -#include "yacl/base/dynamic_bitset.h" -#include "yacl/base/int128.h" -#include "yacl/crypto/primitives/ot/base_ot.h" -#include "yacl/crypto/tools/crhash.h" -#include "yacl/crypto/tools/prg.h" -#include "yacl/crypto/utils/rand.h" +#include "yacl/base/byte_container_view.h" #include "yacl/math/f2k/f2k.h" +#include "yacl/utils/matrix_utils.h" #include "yacl/utils/serialize.h" #ifndef __aarch64__ @@ -42,15 +39,6 @@ #include #include -#include "ot_store.h" - -#include "yacl/base/byte_container_view.h" -#include "yacl/base/exception.h" -#include "yacl/base/int128.h" -#include "yacl/crypto/primitives/ot/sgrr_ote.h" -#include "yacl/crypto/tools/rp.h" -#include "yacl/utils/matrix_utils.h" - namespace yacl::crypto { namespace { @@ -254,7 +242,7 @@ void SoftspokenOtExtSender::OneTimeSetup( const uint64_t range_limit = static_cast(1) << k_limit; // i-th OT instances auto sub_ot = dup_base_ot.NextSlice(k_limit); - // TODO: [low efficiency] It would copy dynamic_bitset. + // TODO(@wenfan): [low efficiency] It would copy dynamic_bitset. // punctured index for i-th pprf punctured_idx_[i] = sub_ot.CopyChoice().data()[0]; // punctured leaves for the i-th pprf diff --git a/yacl/crypto/primitives/ot/softspoken_ote.h b/yacl/crypto/primitives/ot/softspoken_ote.h index 2d11b16f..ce3b1b98 100644 --- a/yacl/crypto/primitives/ot/softspoken_ote.h +++ b/yacl/crypto/primitives/ot/softspoken_ote.h @@ -22,12 +22,20 @@ #include "yacl/base/dynamic_bitset.h" #include "yacl/base/exception.h" #include "yacl/base/int128.h" -#include "yacl/crypto/primitives/ot/ot_store.h" -#include "yacl/crypto/utils/rand.h" #include "yacl/crypto/utils/secparam.h" #include "yacl/link/context.h" #include "yacl/link/link.h" +/* submodules */ +#include "yacl/crypto/primitives/ot/base_ot.h" +#include "yacl/crypto/primitives/ot/ot_store.h" +#include "yacl/crypto/primitives/ot/sgrr_ote.h" +#include "yacl/crypto/tools/crhash.h" +#include "yacl/crypto/tools/prg.h" +#include "yacl/crypto/tools/rp.h" +#include "yacl/crypto/utils/rand.h" + +/* security parameter declaration */ YACL_MODULE_DECLARE("softspoken_ote", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { @@ -49,26 +57,27 @@ namespace yacl::crypto { // (one-time setup) // (a.k.a (N-1)-out-of-N OT) (a.k.a subfield VOLE) // -// > k: Softspoken parameter (decide the instances and num for PPRF) -// > kappa: computation security parameter (128 for example) +// => k: Softspoken parameter (decide the instances and num for PPRF) +// => kappa: computation security parameter (128 for example) // // Security assumptions: -// *. correlation-robust hash function, for more details about its -// implementation, see `yacl/crypto/tools/rp.h` +// => correlation-robust hash function, for more details about its +// implementation, see `yacl/crypto/tools/rp.h` // // NOTE: -// * OT Extension sender requires receiver base ot context. -// * OT Extension receiver requires sender base ot context. -// * Computation cost would be O(2^k/k). -// * Communication for each OT needs 128/k bits. -// * parameter k should be a small number (no greater than 10). -// * k = 2, 4, 8 are recommended in the localhost, LAN, WAN setting +// => OT Extension sender requires receiver base ot context. +// => OT Extension receiver requires sender base ot context. +// => Computation cost would be O(2^k/k). +// => Communication for each OT needs 128/k bits. +// => parameter k should be a small number (no greater than 10). +// => k = 2, 4, 8 are recommended in the localhost, LAN, WAN setting // respectively. -// * step = 64 for k = 1 or 2; step = 32 for k = 3 or 4. +// => step = 64 for k = 1 or 2; step = 32 for k = 3 or 4. class SoftspokenOtExtSender { public: - SoftspokenOtExtSender(uint64_t k = 2, uint64_t step = 0, bool mal = false); + explicit SoftspokenOtExtSender(uint64_t k = 2, uint64_t step = 0, + bool mal = false); void OneTimeSetup(const std::shared_ptr& ctx); @@ -128,7 +137,8 @@ class SoftspokenOtExtSender { class SoftspokenOtExtReceiver { public: - SoftspokenOtExtReceiver(uint64_t k = 2, uint64_t step = 0, bool mal = false); + explicit SoftspokenOtExtReceiver(uint64_t k = 2, uint64_t step = 0, + bool mal = false); void OneTimeSetup(const std::shared_ptr& ctx); diff --git a/yacl/crypto/primitives/ot/x86_asm_ot_interface.h b/yacl/crypto/primitives/ot/x86_asm_ot_interface.h index 76dff6c6..b50a5915 100644 --- a/yacl/crypto/primitives/ot/x86_asm_ot_interface.h +++ b/yacl/crypto/primitives/ot/x86_asm_ot_interface.h @@ -20,7 +20,13 @@ #error "OT interface already defined" #endif +#include + #include "yacl/crypto/primitives/ot/base_ot_interface.h" +#include "yacl/crypto/utils/secparam.h" + +/* security parameter declaration */ +YACL_MODULE_DECLARE("base_ot_x86_asm", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/primitives/vole/f2k/base_vole.h b/yacl/crypto/primitives/vole/f2k/base_vole.h index bd3f9afe..b42b294f 100644 --- a/yacl/crypto/primitives/vole/f2k/base_vole.h +++ b/yacl/crypto/primitives/vole/f2k/base_vole.h @@ -20,12 +20,15 @@ #include "yacl/base/exception.h" #include "yacl/base/int128.h" #include "yacl/crypto/primitives/ot/ot_store.h" -#include "yacl/crypto/primitives/ot/softspoken_ote.h" -#include "yacl/crypto/utils/rand.h" #include "yacl/crypto/utils/secparam.h" #include "yacl/math/f2k/f2k.h" #include "yacl/math/gadget.h" +/* submodules */ +#include "yacl/crypto/primitives/ot/softspoken_ote.h" +#include "yacl/crypto/utils/rand.h" + +/* security parameter declaration */ YACL_MODULE_DECLARE("base_vole", SecParam::C::INF, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/primitives/vole/f2k/silent_vole.cc b/yacl/crypto/primitives/vole/f2k/silent_vole.cc index 50a42972..783fa92e 100644 --- a/yacl/crypto/primitives/vole/f2k/silent_vole.cc +++ b/yacl/crypto/primitives/vole/f2k/silent_vole.cc @@ -14,18 +14,12 @@ #include "yacl/crypto/primitives/vole/f2k/silent_vole.h" -#include +#include +#include #include "yacl/base/aligned_vector.h" #include "yacl/base/dynamic_bitset.h" #include "yacl/base/int128.h" -#include "yacl/crypto/primitives/code/code_interface.h" -#include "yacl/crypto/primitives/code/ea_code.h" -#include "yacl/crypto/primitives/code/silver_code.h" -#include "yacl/crypto/primitives/ot/ferret_ote.h" -#include "yacl/crypto/primitives/vole/f2k/base_vole.h" -#include "yacl/crypto/primitives/vole/f2k/sparse_vole.h" -#include "yacl/crypto/utils/rand.h" #include "yacl/math/gadget.h" namespace yacl::crypto { @@ -42,13 +36,13 @@ namespace { // https://github.com/osu-crypto/libOTe/blob/master/libOTe/TwoChooseOne/ConfigureCode.cpp // which would return the number of noise in MpVole // -uint64_t GenRegNoiseWeight(double min_dist_ratio, uint64_t sec) { +uint64_t GenRegNoiseWeight(double min_dist_ratio, uint64_t security_param) { if (min_dist_ratio > 0.5 || min_dist_ratio <= 0) { YACL_THROW("mini distance too small, rate {}", min_dist_ratio); } - auto d = std::log2(1 - 2 * min_dist_ratio); - auto t = std::max(128, -double(sec) / d); + auto d = -std::log2(1 - 2 * min_dist_ratio); + auto t = std::max(128, double(security_param) / d); return math::RoundUpTo(t, 8); } @@ -96,7 +90,7 @@ struct VoleParam { case CodeType::ExAcc40: min_dist_ratio = 0.2; break; - // TODO: @wenfan + // TODO(@wenfan) // support ExConv Code default: break; @@ -155,7 +149,7 @@ std::shared_ptr GetEncoder(const VoleParam& param) { case CodeType::ExAcc40: encoder = std::make_shared>(vole_num, mp_vole_size); break; - // TODO: @wenfan + // TODO(@wenfan) // support ExConv Code default: break; @@ -230,7 +224,7 @@ void SilentVoleReceiver::SfRecv(const std::shared_ptr& ctx, template void SilentVoleSender::SendImpl(const std::shared_ptr& ctx, absl::Span c) { - if (is_inited_ == false) { + if (!is_inited_) { OneTimeSetup(ctx); } @@ -259,7 +253,7 @@ void SilentVoleSender::SendImpl(const std::shared_ptr& ctx, template void SilentVoleReceiver::RecvImpl(const std::shared_ptr& ctx, absl::Span a, absl::Span b) { - if (is_inited_ == false) { + if (!is_inited_) { OneTimeSetup(ctx); } diff --git a/yacl/crypto/primitives/vole/f2k/silent_vole.h b/yacl/crypto/primitives/vole/f2k/silent_vole.h index a855bc83..4420ca51 100644 --- a/yacl/crypto/primitives/vole/f2k/silent_vole.h +++ b/yacl/crypto/primitives/vole/f2k/silent_vole.h @@ -15,13 +15,23 @@ #pragma once #include +#include #include "yacl/base/exception.h" #include "yacl/base/int128.h" -#include "yacl/crypto/primitives/ot/softspoken_ote.h" #include "yacl/crypto/utils/secparam.h" #include "yacl/link/context.h" +/* submodules */ +#include "yacl/crypto/primitives/code/code_interface.h" +#include "yacl/crypto/primitives/code/ea_code.h" +#include "yacl/crypto/primitives/code/silver_code.h" +#include "yacl/crypto/primitives/ot/ferret_ote.h" +#include "yacl/crypto/primitives/vole/f2k/base_vole.h" +#include "yacl/crypto/primitives/vole/f2k/sparse_vole.h" +#include "yacl/crypto/utils/rand.h" + +/* security parameter declaration */ YACL_MODULE_DECLARE("silent_vole", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { @@ -34,7 +44,7 @@ enum class CodeType { ExAcc11, ExAcc21, ExAcc40, - // TODO: @wenfan + // TODO(@wenfan) // Support ExConv Code ExConv7x24, ExConv21x24 @@ -78,14 +88,14 @@ enum class CodeType { class SilentVoleSender { public: - SilentVoleSender(CodeType code) { + explicit SilentVoleSender(CodeType code) { ss_sender_ = SoftspokenOtExtSender(2); codetype_ = code; delta_ = MakeUint128(0, 0); // init delta_ } void OneTimeSetup(const std::shared_ptr& ctx) { - if (is_inited_ == false) { + if (!is_inited_) { ss_sender_.OneTimeSetup(ctx); delta_ = ss_sender_.GetDelta(); is_inited_ = true; @@ -129,13 +139,13 @@ class SilentVoleSender { class SilentVoleReceiver { public: - SilentVoleReceiver(CodeType code) { + explicit SilentVoleReceiver(CodeType code) { ss_receiver_ = SoftspokenOtExtReceiver(2); codetype_ = code; } void OneTimeSetup(const std::shared_ptr& ctx) { - if (is_inited_ == false) { + if (!is_inited_) { ss_receiver_.OneTimeSetup(ctx); is_inited_ = true; } @@ -165,4 +175,4 @@ class SilentVoleReceiver { absl::Span b); }; -} // namespace yacl::crypto \ No newline at end of file +} // namespace yacl::crypto diff --git a/yacl/crypto/primitives/vole/f2k/sparse_vole.cc b/yacl/crypto/primitives/vole/f2k/sparse_vole.cc index 1a07b458..d9acf831 100644 --- a/yacl/crypto/primitives/vole/f2k/sparse_vole.cc +++ b/yacl/crypto/primitives/vole/f2k/sparse_vole.cc @@ -17,15 +17,9 @@ #include #include -#include "sparse_vole.h" - #include "yacl/base/aligned_vector.h" #include "yacl/base/byte_container_view.h" #include "yacl/base/int128.h" -#include "yacl/crypto/primitives/ot/gywz_ote.h" -#include "yacl/crypto/primitives/ot/sgrr_ote.h" -#include "yacl/crypto/tools/crhash.h" -#include "yacl/crypto/tools/rp.h" #include "yacl/math/f2k/f2k.h" #include "yacl/math/gadget.h" #include "yacl/utils/serialize.h" diff --git a/yacl/crypto/primitives/vole/f2k/sparse_vole.h b/yacl/crypto/primitives/vole/f2k/sparse_vole.h index ad21ef07..57ac5cc1 100644 --- a/yacl/crypto/primitives/vole/f2k/sparse_vole.h +++ b/yacl/crypto/primitives/vole/f2k/sparse_vole.h @@ -14,13 +14,20 @@ #pragma once -#include "yacl/crypto/primitives/ot/ferret_ote.h" #include "yacl/crypto/primitives/ot/ot_store.h" -#include "yacl/crypto/primitives/ot/softspoken_ote.h" -#include "yacl/crypto/utils/rand.h" #include "yacl/crypto/utils/secparam.h" #include "yacl/math/gadget.h" +/* submodules */ +#include "yacl/crypto/primitives/ot/ferret_ote.h" +#include "yacl/crypto/primitives/ot/gywz_ote.h" +#include "yacl/crypto/primitives/ot/sgrr_ote.h" +#include "yacl/crypto/primitives/ot/softspoken_ote.h" +#include "yacl/crypto/tools/crhash.h" +#include "yacl/crypto/tools/rp.h" +#include "yacl/crypto/utils/rand.h" + +/* security parameter declaration */ YACL_MODULE_DECLARE("sparse_vole", SecParam::C::INF, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/tools/crhash.cc b/yacl/crypto/tools/crhash.cc index 6d1ffd45..baef1cbc 100644 --- a/yacl/crypto/tools/crhash.cc +++ b/yacl/crypto/tools/crhash.cc @@ -14,8 +14,6 @@ #include "yacl/crypto/tools/crhash.h" -#include "yacl/crypto/tools/rp.h" - #ifndef __aarch64__ // sse #include diff --git a/yacl/crypto/tools/crhash.h b/yacl/crypto/tools/crhash.h index 2ba6b665..7e94b72c 100644 --- a/yacl/crypto/tools/crhash.h +++ b/yacl/crypto/tools/crhash.h @@ -20,6 +20,9 @@ #include "yacl/base/int128.h" +/* submodules */ +#include "yacl/crypto/tools/rp.h" + namespace yacl::crypto { // Correlation Robust Hash function (Single Block input) diff --git a/yacl/crypto/tools/prg.h b/yacl/crypto/tools/prg.h index ee16278b..b479131e 100644 --- a/yacl/crypto/tools/prg.h +++ b/yacl/crypto/tools/prg.h @@ -22,9 +22,12 @@ #include "yacl/base/dynamic_bitset.h" #include "yacl/base/int128.h" -#include "yacl/crypto/base/block_cipher/symmetric_crypto.h" #include "yacl/crypto/utils/secparam.h" +/* submodules */ +#include "yacl/crypto/base/block_cipher/symmetric_crypto.h" + +/* security parameter declaration */ YACL_MODULE_DECLARE("prg", SecParam::C::k128, SecParam::S::INF); namespace yacl::crypto { diff --git a/yacl/crypto/tools/ro.h b/yacl/crypto/tools/ro.h index 98c861d2..4c51af2f 100644 --- a/yacl/crypto/tools/ro.h +++ b/yacl/crypto/tools/ro.h @@ -20,6 +20,8 @@ #include "yacl/base/buffer.h" #include "yacl/base/exception.h" + +/* submodules */ #include "yacl/crypto/base/hash/hash_utils.h" namespace yacl::crypto { diff --git a/yacl/crypto/tools/ro_test.cc b/yacl/crypto/tools/ro_test.cc index f671b946..da78f87b 100644 --- a/yacl/crypto/tools/ro_test.cc +++ b/yacl/crypto/tools/ro_test.cc @@ -33,14 +33,14 @@ INSTANTIATE_TEST_SUITE_P(VarInputLen, RandomOracleTest, TEST_P(RandomOracleTest, Default) { const auto& param = GetParam(); const auto& RO = RandomOracle::GetDefault(); - auto input = RandBytes(param); + auto input = FastRandBytes(param); EXPECT_EQ(RO.Gen(input), RO.Gen(input)); } TEST_P(RandomOracleTest, OutLen8) { const auto& param = GetParam(); auto RO = RandomOracle(HashAlgorithm::BLAKE3, 8); - auto input = RandBytes(param); + auto input = FastRandBytes(param); EXPECT_EQ(RO.Gen(input), RO.Gen(input)); } @@ -64,7 +64,7 @@ void inline CheckType(const RandomOracle& ro, ByteContainerView input) { TEST_P(RandomOracleTest, GetTypeTest) { const auto& param = GetParam(); const auto& RO = RandomOracle::GetDefault(); - auto input = RandBytes(param); + auto input = FastRandBytes(param); CheckType(RO, input); CheckType(RO, input); CheckType(RO, input); @@ -79,7 +79,7 @@ TEST_P(RandomOracleTest, GetTypeTest) { TEST_P(RandomOracleTest, TwoParamTest) { const auto& param = GetParam(); const auto& RO = RandomOracle::GetDefault(); - auto input_bytes = RandBytes(param); + auto input_bytes = FastRandBytes(param); auto input_u64 = FastRandU64(); EXPECT_EQ(RO.Gen(input_bytes, input_u64), diff --git a/yacl/crypto/tools/rp.cc b/yacl/crypto/tools/rp.cc index 75966e8f..aed00c21 100644 --- a/yacl/crypto/tools/rp.cc +++ b/yacl/crypto/tools/rp.cc @@ -17,8 +17,6 @@ #include #include -#include "yacl/crypto/base/block_cipher/symmetric_crypto.h" - namespace yacl::crypto { using Ctype = SymmetricCrypto::CryptoType; diff --git a/yacl/crypto/tools/rp.h b/yacl/crypto/tools/rp.h index ab6954c5..4fe871e1 100644 --- a/yacl/crypto/tools/rp.h +++ b/yacl/crypto/tools/rp.h @@ -20,7 +20,9 @@ #include "yacl/base/exception.h" #include "yacl/base/int128.h" -#include "yacl/crypto/base/aes/aes_intrinsics.h" + +/* submodules */ +// #include "yacl/crypto/base/aes/aes_intrinsics.h" #include "yacl/crypto/base/block_cipher/symmetric_crypto.h" namespace yacl::crypto { @@ -69,7 +71,7 @@ class RP { } static const RP& GetCrDefault() { - const static RP rp(Ctype::AES128_ECB, 0x12345678); + static const RP rp(Ctype::AES128_ECB, 0x12345678); return rp; } diff --git a/yacl/crypto/utils/drbg/BUILD.bazel b/yacl/crypto/utils/drbg/BUILD.bazel index b7cc41b1..f4b649b9 100644 --- a/yacl/crypto/utils/drbg/BUILD.bazel +++ b/yacl/crypto/utils/drbg/BUILD.bazel @@ -50,13 +50,13 @@ yacl_cc_library( "openssl_factory.h", ], data = [ - "//yacl/crypto/provider:prov_shared", # openssl provider shared lib + "//yacl/crypto/ossl-provider:prov_shared", # openssl provider shared lib ], visibility = ["//visibility:private"], deps = [ ":spi", "//yacl/crypto/base:openssl_wrappers", - "//yacl/crypto/provider:helper", # helper + "//yacl/crypto/ossl-provider:helper", # helper "//yacl/crypto/utils/entropy_source", ], alwayslink = 1, @@ -72,13 +72,13 @@ yacl_cc_library( "ic_factory.h", ], data = [ - "//yacl/crypto/provider:prov_shared", # openssl provider shared lib + "//yacl/crypto/ossl-provider:prov_shared", # openssl provider shared lib ], visibility = ["//visibility:private"], deps = [ ":spi", "//yacl/crypto/base:openssl_wrappers", - "//yacl/crypto/provider:helper", # helper + "//yacl/crypto/ossl-provider:helper", # helper "//yacl/crypto/utils/entropy_source", "@com_github_greendow_hash_drbg//:hash_drbg", ], diff --git a/yacl/crypto/utils/drbg/openssl_factory.cc b/yacl/crypto/utils/drbg/openssl_factory.cc index c242f78a..b5704672 100644 --- a/yacl/crypto/utils/drbg/openssl_factory.cc +++ b/yacl/crypto/utils/drbg/openssl_factory.cc @@ -21,10 +21,8 @@ #include #include -#include "openssl/objects.h" - #include "yacl/base/exception.h" -#include "yacl/crypto/provider/helper.h" +#include "yacl/crypto/ossl-provider/helper.h" #include "yacl/crypto/utils/secparam.h" namespace yacl::crypto { diff --git a/yacl/crypto/utils/rand.cc b/yacl/crypto/utils/rand.cc index cd75f94a..73346d65 100644 --- a/yacl/crypto/utils/rand.cc +++ b/yacl/crypto/utils/rand.cc @@ -17,11 +17,9 @@ #include #include -#include "openssl/rand.h" - #include "yacl/base/byte_container_view.h" #include "yacl/base/dynamic_bitset.h" -#include "yacl/crypto/provider/helper.h" +#include "yacl/crypto/ossl-provider/helper.h" #include "yacl/crypto/utils/entropy_source/entropy_source.h" namespace yacl::crypto { diff --git a/yacl/crypto/utils/secparam.h b/yacl/crypto/utils/secparam.h index e90e279a..1f5c6d08 100644 --- a/yacl/crypto/utils/secparam.h +++ b/yacl/crypto/utils/secparam.h @@ -206,9 +206,17 @@ class YaclModuleHandler { static void PrintAll() { fmt::print(fg(fmt::color::green), "{:-^50}\n", "module summary"); interate_helper(std::make_integer_sequence{}, true); - fmt::print(fg(fmt::color::yellow), "{0:<10}\t{1:<5}\t{2:<5}\n", "*target*", - SecParam::MakeInt(SecParam::glob_c), - SecParam::MakeInt(SecParam::glob_s)); + std::string c_str = fmt::format("{}", SecParam::MakeInt(SecParam::glob_c)); + std::string s_str = fmt::format("{}", SecParam::MakeInt(SecParam::glob_s)); + if (SecParam::MakeInt(SecParam::glob_c) == UINT32_MAX) { + c_str = "-"; + } + if (SecParam::MakeInt(SecParam::glob_s) == UINT32_MAX) { + s_str = "-"; + } + + fmt::print(fg(fmt::color::yellow), "{0:<10}\t{1:<5}\t{2:<5}\n", "*all*", + c_str, s_str); fmt::print(fg(fmt::color::green), "{:-^50}\n", ""); } @@ -293,7 +301,7 @@ class YaclModuleHandler { // Print all module summary #define YACL_PRINT_MODULE_SUMMARY() \ - YaclModuleHandler::PrintAll(); + YaclModuleHandler::PrintAll() // Enforce Yacl security level, fails when condition not met #define YACL_ENFORCE_SECPARAM(COMP, STAT) \ @@ -302,4 +310,7 @@ class YaclModuleHandler { "Enforce SecurityParameter failed, expected c>{}, s>{}, but yacl got " \ "global (c, s) = ({}, {})", \ SecParam::MakeInt(COMP), SecParam::MakeInt(STAT), \ - YACL_GLOB_SECPARAM_C_UINT, YACL_GLOB_SECPARAM_S_UINT); + YACL_GLOB_SECPARAM_C_UINT, YACL_GLOB_SECPARAM_S_UINT) + +// alias +using SecParam = yacl::crypto::SecParam; diff --git a/yacl/math/galois_field/gf_configs.h b/yacl/math/galois_field/gf_configs.h index 6ed4a32e..18e31d4c 100644 --- a/yacl/math/galois_field/gf_configs.h +++ b/yacl/math/galois_field/gf_configs.h @@ -31,7 +31,10 @@ inline const std::string kBinaryField = "GF_2^k"; DECLARE_ARG(MPInt, Mod); // the value of p in GF_p // configs for kExtensionField, kBinaryField -DECLARE_ARG(uint64_t, degree); +DECLARE_ARG(uint64_t, Degree); + +// configs for max bit size for underlying prime number +DECLARE_ARG(uint64_t, MaxBitSize); //== Supported lib list... ==// @@ -49,5 +52,6 @@ DECLARE_ARG(uint64_t, degree); // Note 2: Get mpint field instance by `GaloisFieldFactory::Instance().Create()` inline const std::string kMPIntLib = "mpint"; +inline const std::string kMclLib = "libmcl"; } // namespace yacl::math diff --git a/yacl/math/galois_field/gf_spi.cc b/yacl/math/galois_field/gf_spi.cc index 75c2d77c..f6731173 100644 --- a/yacl/math/galois_field/gf_spi.cc +++ b/yacl/math/galois_field/gf_spi.cc @@ -19,6 +19,8 @@ namespace yacl::math { DEFINE_ARG(MPInt, Mod); +DEFINE_ARG(uint64_t, Degree); +DEFINE_ARG(uint64_t, MaxBitSize); GaloisFieldFactory& GaloisFieldFactory::Instance() { static GaloisFieldFactory factory; diff --git a/yacl/math/galois_field/gf_spi.h b/yacl/math/galois_field/gf_spi.h index 92c85053..34c5828c 100644 --- a/yacl/math/galois_field/gf_spi.h +++ b/yacl/math/galois_field/gf_spi.h @@ -34,17 +34,22 @@ class GaloisField { virtual std::string GetLibraryName() const = 0; virtual std::string GetFieldName() const = 0; - // The order of Finite Field will always be k-th power of a prime number p. - // And in extension field, field order and field modulus are different and not - // directly related, which is unlike in normal prime field that field order is - // just field modulus. - // Note, the origin order(p^k) of extension field(degree k>1) is actually - // useless for field computation. So we usually disable `GetOrder` for - // extension field and set it to be 0, except we are dealing within a subfield - // from the upper extension field. + // The order of Finite Field will always be k-th power(p^k) of a prime number + // p. And in extension field, field order and field modulus are different and + // not directly related, which is unlike in normal prime field that field + // order is just field modulus. + // !Note, we will set the default order to be 0 for extension field, since the + // origin order(p^k) of extension field(degree k>1) is actually useless for + // field computation. Actually, we often deal within a subgroup(additive or + // multiplicative) over the extension field, so we provide the other two + // interfaces for `order`(GetMulGroupOrder and GetAddGroupOrder). virtual MPInt GetOrder() const = 0; - virtual MPInt GetExtensionDegree() const = 0; // the k of GF(p^k) - virtual MPInt GetBaseFieldOrder() const = 0; // the p of GF(p^k) + virtual uint64_t GetExtensionDegree() const = 0; // the k of GF(p^k) + virtual MPInt GetBaseFieldOrder() const = 0; // the p of GF(p^k) + // Get order of a multiplicative (sub)group over field + virtual MPInt GetMulGroupOrder() const = 0; + // Get order of a additive (sub)group over field + virtual MPInt GetAddGroupOrder() const = 0; // get the additive identity virtual Item GetIdentityZero() const = 0; diff --git a/yacl/crypto/base/field/mcl/BUILD.bazel b/yacl/math/galois_field/mcl_field/BUILD.bazel similarity index 68% rename from yacl/crypto/base/field/mcl/BUILD.bazel rename to yacl/math/galois_field/mcl_field/BUILD.bazel index 08cac7f0..0269651c 100644 --- a/yacl/crypto/base/field/mcl/BUILD.bazel +++ b/yacl/math/galois_field/mcl_field/BUILD.bazel @@ -13,6 +13,7 @@ # limitations under the License. load("//bazel:yacl.bzl", "yacl_cc_library", "yacl_cc_test") +load("@bazel_skylib//lib:selects.bzl", "selects") package(default_visibility = ["//visibility:public"]) @@ -22,15 +23,17 @@ yacl_cc_library( "mcl_field.cc", ], hdrs = ["mcl_field.h"], - defines = [ - # ! Flag only for test ! - # "MCL_FIELD_YACL_TEST", - ], + defines = selects.with_or({ + ("@yacl//bazel:yacl_build_as_debug", "@yacl//bazel:yacl_build_as_fast"): [ + # !Only for test and don't use this in production! + "MCL_FIELD_YACL_TEST", + ], + "//conditions:default": [], + }), deps = [ - "//yacl/crypto/base/ecc/mcl:pairing_header", "//yacl/crypto/base/ecc/mcl:util", - "//yacl/crypto/base/field:field_spi", - "@com_github_herumi_mcl//:mcl", + "//yacl/crypto/base/pairing/mcl:pairing_header", + "//yacl/math/galois_field:sketch", ], ) @@ -39,7 +42,7 @@ yacl_cc_test( srcs = ["mcl_field_test.cc"], deps = [ ":field", - "//yacl/crypto/base/ecc/mcl:pairing", + "//yacl/crypto/base/pairing/mcl:pairing", "//yacl/crypto/utils:rand", ], ) diff --git a/yacl/math/galois_field/mcl_field/mcl_field.cc b/yacl/math/galois_field/mcl_field/mcl_field.cc new file mode 100644 index 00000000..450b111e --- /dev/null +++ b/yacl/math/galois_field/mcl_field/mcl_field.cc @@ -0,0 +1,377 @@ +// Copyright 2023 Ant Group Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "yacl/math/galois_field/mcl_field/mcl_field.h" + +#include + +#include "mcl/fp_tower.hpp" +#include "mcl/op.hpp" + +#include "yacl/crypto/base/ecc/mcl/mcl_util.h" +#include "yacl/crypto/base/pairing/mcl/pairing_header.h" +#include "yacl/math/galois_field/gf_configs.h" + +namespace yacl::math::hmcl { + +REGISTER_GF_LIBRARY(kMclLib, 200, MclFieldFactory::Check, + MclFieldFactory::Create); + +struct MclFieldMeta { + std::string field_name; + // Specified by ArgDegree + uint64_t degree; + // Specified by ArgMaxBitSize + uint64_t max_bit_size; + + bool IsEquivalent(const MclFieldMeta& rhs) const { + return std::tie(field_name, degree, max_bit_size) == + std::tie(rhs.field_name, rhs.degree, rhs.max_bit_size); + } + MclFieldMeta(std::string field_name, uint64_t degree, uint64_t max_bit_size) { + this->field_name = field_name; + this->degree = degree; + this->max_bit_size = max_bit_size; + } +}; + +const std::vector kMclFieldMetas = { +#ifdef MCL_FIELD_YACL_TEST + {kPrimeField, 1, 256}, {kPrimeField, 1, 512}, + {kExtensionField, 2, 512}, {kExtensionField, 6, 512}, + {kExtensionField, 12, 512}, +#endif +}; + +std::unique_ptr MclFieldFactory::Create( + const std::string& field_name, const SpiArgs& args) { + auto mod = args.GetRequired(ArgMod); + auto degree = args.Get(ArgDegree, 1); + auto maxBitSize = args.Get(ArgMaxBitSize, 512); + auto it = kMclFieldMetas.cbegin(); + for (; it != kMclFieldMetas.cend(); it++) { + if (it->IsEquivalent({field_name, degree, maxBitSize})) { + break; + } + } + YACL_ENFORCE(it != kMclFieldMetas.cend()); + + switch (it->degree) { + case 1: + if (maxBitSize == 256) { + return std::unique_ptr( + new MclField, 1>(mod)); + } else { + return std::unique_ptr( + new MclField, 1>(mod)); + } + case 2: + return std::unique_ptr( + new MclField>, 2>(mod)); + case 6: + return std::unique_ptr( + new MclField>, 6>(mod)); + case 12: + return std::unique_ptr( + new MclField>, 12>(mod)); + default: + YACL_THROW("Not supported Field by {}", kMclLib); + } +} + +bool MclFieldFactory::Check(const std::string& field_name, + const SpiArgs& args) { + auto degree = args.Get(ArgDegree, 1); + auto maxBitSize = args.Get(ArgMaxBitSize, 512); + MclFieldMeta meta = {field_name, degree, maxBitSize}; + for (auto it : kMclFieldMetas) { + if (meta.IsEquivalent(it)) { + return true; + } + } + return false; +} + +namespace ch = yacl::crypto::hmcl; + +#define BASE_FP_SIZE ((T::BaseFp::getOp().mp.getBitSize() + 7) / 8) + +template +std::string MclField::GetLibraryName() const { + return kMclLib; +} + +template +std::string MclField::GetFieldName() const { + return degree == 1 ? kPrimeField : kExtensionField; +} + +template +uint64_t MclField::GetExtensionDegree() const { + return degree; +} + +template +MPInt MclField::GetOrder() const { + return order_; +} + +template +MPInt MclField::GetMulGroupOrder() const { + return order_mul_; +} + +template +MPInt MclField::GetAddGroupOrder() const { + return order_add_; +} + +template +MPInt MclField::GetBaseFieldOrder() const { + return ch::Mpz2Mp(T::BaseFp::getOp().mp); +} + +template +Item MclField::GetIdentityZero() const { + return T(0); +} + +template +Item MclField::GetIdentityOne() const { + return T(1); +} + +template +inline bool MclField::IsIdentityOne(const T& x) const { + return x.isOne(); +} + +template +bool MclField::IsIdentityZero(const T& x) const { + return x.isZero(); +} + +template +bool MclField::IsInField(const T&) const { + // Cause only valid element could be managed by class T, so element in class T + // is always valid. + return true; +} + +template +bool MclField::Equal(const T& x, const T& y) const { + return x == y; +} + +template +T MclField::Neg(const T& x) const { + T ret; + T::neg(ret, x); + return ret; +} + +template +void MclField::NegInplace(T* x) const { + T::neg(*x, *x); +} + +template +T MclField::Inv(const T& x) const { + T ret; + T::inv(ret, x); + return ret; +} + +template +void MclField::InvInplace(T* x) const { + T::inv(*x, *x); +} + +template +T MclField::Add(const T& x, const T& y) const { + return x + y; +} + +template +void MclField::AddInplace(T* x, const T& y) const { + T::add(*x, *x, y); +} + +template +T MclField::Sub(const T& x, const T& y) const { + return x - y; +} + +template +void MclField::SubInplace(T* x, const T& y) const { + T::sub(*x, *x, y); +} + +template +T MclField::Mul(const T& x, const T& y) const { + return x * y; +} + +template +void MclField::MulInplace(T* x, const T& y) const { + T::mul(*x, *x, y); +} + +template +T MclField::Div(const T& x, const T& y) const { + return x / y; +} + +template +void MclField::DivInplace(T* x, const T& y) const { + T::div(*x, *x, y); +} + +template +T MclField::Pow(const T& x, const MPInt& y) const { + T ret; + T::pow(ret, x, ch::Mp2Mpz(y)); + return ret; +} + +template +void MclField::PowInplace(T* x, const MPInt& y) const { + T::pow(*x, *x, ch::Mp2Mpz(y)); +} + +template +T MclField::RandomT() const { + const auto per_size = BASE_FP_SIZE; + + T ret; + Buffer buf(per_size * degree); + typename T::BaseFp p; + for (uint64_t i = 0; i < degree; i++) { + p.setByCSPRNG(); + p.serialize(buf.data() + i * per_size, per_size); + } + + ret.deserialize(buf.data(), buf.size()); + return ret; +} + +template +T MclField::DeepCopy(const T& x) const { + return x; +} + +template +std::string MclField::ToString(const T& x) const { + return x.getStr(mcl::IoDec); +} + +template +Buffer MclField::Serialize(const T& x) const { + Buffer buf(BASE_FP_SIZE * degree); + auto size = x.serialize(buf.data(), buf.size()); + buf.resize(size); + return buf; +} + +template +size_t MclField::Serialize(const T& x, uint8_t* buf, + size_t buf_len) const { + if (buf == nullptr) { + return BASE_FP_SIZE * degree; + } + YACL_ENFORCE(BASE_FP_SIZE * degree <= buf_len); + auto sz = x.serialize(buf, buf_len); + return sz; +} + +template +T MclField::DeserializeT(ByteContainerView buffer) const { + T ret; + ret.deserialize(buffer.data(), buffer.size()); + return ret; +} + +template +MclField::MclField(const MPInt& order, Type field_type) { + switch (field_type) { + case Type::Normal: { + order_ = 0_mp; + order_mul_ = 0_mp; + order_add_ = order; + break; + } + case Type::Mul: { + order_ = 0_mp; + order_mul_ = order; + order_add_ = 0_mp; + break; + } + default: { + order_ = order; + order_mul_ = order - 1_mp; + order_add_ = order_; + } + } +} + +template +MclField::MclField(const MPInt& base_prime_p, mcl::fp::Mode mode, + int xi_a) { + auto base_p = ch::Mp2Mpz(base_prime_p); + if (degree == 1) { + T::BaseFp::init(base_p, mode); + order_ = base_prime_p; + order_mul_ = order_ - 1_mp; + order_add_ = order_; + } else { + // init for extension mcl field Fp^{2,6,12} + // xi_a is used for Fp2::mul_xi(), where xi = xi_a + i and i^2 = -1 + // if xi_a = 0 then asm functions for Fp2 are not generated. + T::BaseFp::init(xi_a, base_p, mode); + mcl::Fp2T::init(); + order_ = 0_mp; + order_mul_ = order_; + order_add_ = order_; + } +} + +// =============================================================== +// Instantiate Field for test +// =============================================================== +#ifdef MCL_FIELD_YACL_TEST +template class MclField; +template class MclField; +template class MclField; +template class MclField; +template class MclField; +#endif + +// =============================================================== +// Instantiate Pairing Curve Field from template +// =============================================================== +template class MclField; + +#ifdef MCL_ALL_PAIRING_FOR_YACL +template class MclField; +template class MclField; +template class MclField; +template class MclField; +template class MclField; +template class MclField; +template class MclField; +template class MclField; +template class MclField; +#endif + +} // namespace yacl::math::hmcl diff --git a/yacl/math/galois_field/mcl_field/mcl_field.h b/yacl/math/galois_field/mcl_field/mcl_field.h new file mode 100644 index 00000000..5ab77e37 --- /dev/null +++ b/yacl/math/galois_field/mcl_field/mcl_field.h @@ -0,0 +1,130 @@ +// Copyright 2023 Ant Group Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "mcl/fp.hpp" +#include "mcl/fp_tower.hpp" + +#include "yacl/crypto/base/pairing/mcl/pairing_header.h" +#include "yacl/math/galois_field/gf_scalar.h" + +namespace yacl::math::hmcl { + +class MclFieldFactory { + public: + static std::unique_ptr Create(const std::string& field_name, + const SpiArgs& args); + static bool Check(const std::string& field_name, const SpiArgs&); +}; + +enum Type { + Normal, + Add, + Mul, +}; + +template +class MclField : public GFScalarSketch { + private: + public: + using T_ = T; + std::string GetLibraryName() const override; + std::string GetFieldName() const override; + + MPInt GetOrder() const override; + MPInt GetMulGroupOrder() const override; + MPInt GetAddGroupOrder() const override; + uint64_t GetExtensionDegree() const override; + MPInt GetBaseFieldOrder() const override; + + Item GetIdentityZero() const override; + Item GetIdentityOne() const override; + + bool IsIdentityOne(const T& x) const override; + bool IsIdentityZero(const T& x) const override; + bool IsInField(const T& x) const override; + + bool Equal(const T& x, const T& y) const override; + + //==================================// + // operations defined on field // + //==================================// + + // get the additive inverse −a for all elements in set + T Neg(const T& x) const override; + void NegInplace(T* x) const override; + + // get the multiplicative inverse 1/b for every nonzero element in set + T Inv(const T& x) const override; + void InvInplace(T* x) const override; + + T Add(const T& x, const T& y) const override; + void AddInplace(T* x, const T& y) const override; + + T Sub(const T& x, const T& y) const override; + void SubInplace(T* x, const T& y) const override; + + T Mul(const T& x, const T& y) const override; + void MulInplace(T* x, const T& y) const override; + + T Div(const T& x, const T& y) const override; + void DivInplace(T* x, const T& y) const override; + + T Pow(const T& x, const MPInt& y) const override; + void PowInplace(T* x, const MPInt& y) const override; + + // scalar version: return a random scalar element + T RandomT() const override; + + //==================================// + // operations defined on field // + //==================================// + + T DeepCopy(const T& x) const override; + + // To human-readable string + std::string ToString(const T& x) const override; + + Buffer Serialize(const T& x) const override; + size_t Serialize(const T& x, uint8_t* buf, size_t buf_len) const override; + + T DeserializeT(ByteContainerView buffer) const override; + + explicit MclField(const MPInt& order, Type field_type); + + private: + // xi_a is used for Fp2::mul_xi(), where xi = xi_a + i and i^2 = -1, see + // Fp::init(int xi_a, ...) + MclField(const MPInt& base_prime_p, mcl::fp::Mode mode = mcl::fp::FP_AUTO, + int xi_a = 1); + // Sometimes the order_ maybe used as the subgroup order over field + // For additive group, given an element $e$ in field, $e * order_ = 0$, + // For multiplicative group, given an element $e$ in field, $e^(order_-1)=1$. + MPInt order_; + MPInt order_mul_; + MPInt order_add_; + + friend class MclFieldFactory; +}; + +#ifdef MCL_FIELD_YACL_TEST +using DefaultFp = mcl::FpT<>; // size 512 +using FpWithSize256 = mcl::FpT; // Max element size 256 bits +using DefaultFp2 = mcl::Fp2T>; +using DefaultFp6 = mcl::Fp6T>; +using DefaultFp12 = mcl::Fp12T>; // size 512 +#endif + +} // namespace yacl::math::hmcl diff --git a/yacl/math/galois_field/mcl_field/mcl_field_test.cc b/yacl/math/galois_field/mcl_field/mcl_field_test.cc new file mode 100644 index 00000000..7dfc4cb9 --- /dev/null +++ b/yacl/math/galois_field/mcl_field/mcl_field_test.cc @@ -0,0 +1,265 @@ +// Copyright 2023 Ant Group Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "yacl/math/galois_field/mcl_field/mcl_field.h" + +#include "gtest/gtest.h" + +#include "yacl/crypto/base/ecc/mcl/mcl_util.h" +#include "yacl/crypto/base/pairing/mcl/mcl_pairing_group.h" +#include "yacl/crypto/utils/rand.h" +#include "yacl/math/galois_field/gf_configs.h" + +namespace yacl::math::hmcl::test { + +template +class MclFieldTest : public ::testing::Test { + protected: + using T = typename F::T_; + + std::shared_ptr field_; // This lib/curve we should to test + std::string filed_name_; + bool is_sub_field_ = false; + + void RunAllTests() { + fmt::print("Begin to test mcl field {} \n", filed_name_); + TestCompare(); + TestArithmetic(); + TestArithmeticVector(); + // TestOrder(); + TestSerialize(); + fmt::print("End to test mcl field {} \n", filed_name_); + } + + void TestCompare() { + auto f1 = field_->GetIdentityZero(); + EXPECT_TRUE((bool)field_->IsIdentityZero(f1)); + f1 = field_->GetIdentityOne(); + EXPECT_TRUE((bool)field_->IsIdentityOne(f1)); + EXPECT_TRUE((bool)field_->Equal(f1, field_->GetIdentityOne())); + + auto f2 = field_->Random(); + EXPECT_TRUE((bool)field_->Equal(f2, f2)); + EXPECT_FALSE((bool)field_->Equal(f1, f2)); + } + + void TestArithmetic() { + // GIVEN + auto f1 = field_->Random(); + auto f2 = field_->Random(); + + // THEN + // Add, AddInplace + auto add_ret = field_->Add(f1, f2); + EXPECT_TRUE((bool)field_->Equal(add_ret, field_->Add(f2, f1))); + Item temp = field_->DeepCopy(f1); + field_->AddInplace(&temp, f2); + EXPECT_TRUE((bool)field_->Equal(add_ret, temp)); + + // Neg & Sub, SubInplace + EXPECT_TRUE((bool)field_->IsIdentityZero(field_->Add(f1, field_->Neg(f1)))); + auto sub_ret = field_->Sub(f1, f2); + EXPECT_TRUE((bool)field_->Equal(sub_ret, field_->Add(f1, field_->Neg(f2)))); + temp = field_->DeepCopy(f1); + field_->SubInplace(&temp, f2); + EXPECT_TRUE((bool)field_->Equal(sub_ret, temp)); + + // Mul, MulInplace + auto mul_ret = field_->Mul(f1, f2); + EXPECT_TRUE((bool)field_->Equal(mul_ret, field_->Mul(f2, f1))); + temp = field_->DeepCopy(f1); + field_->MulInplace(&temp, f2); + EXPECT_TRUE((bool)field_->Equal(mul_ret, temp)); + + // Pow, PowInplace + // Test f1^r + auto r = 1000_mp; + auto pow_temp = field_->GetIdentityOne(); + for (int i = 0; i < 1000; i++) { + field_->MulInplace(&pow_temp, f1); + } + auto pow_ret1 = field_->Pow(f1, r); + EXPECT_TRUE((bool)field_->Equal(pow_ret1, pow_temp)); + auto pow_ret2 = field_->DeepCopy(f1); + field_->PowInplace(&pow_ret2, r); + EXPECT_TRUE((bool)field_->Equal(pow_ret2, pow_temp)); + + // Div, DivInplace & Inv + EXPECT_TRUE((bool)field_->IsIdentityOne(field_->Div(f1, f1))); + auto div_ret = field_->Div(f1, f2); + temp = field_->DeepCopy(f1); + field_->DivInplace(&temp, f2); + EXPECT_TRUE((bool)field_->Equal(temp, div_ret)); + EXPECT_TRUE((bool)field_->IsIdentityOne( + field_->Mul(field_->Div(f1, f2), field_->Div(f2, f1)))); + EXPECT_TRUE((bool)field_->IsIdentityOne(field_->Mul(f1, field_->Inv(f1)))); + } + + void TestArithmeticVector() { + // GIVEN + auto t1 = std::vector({field_->Random().As(), field_->Random().As(), + field_->Random().As(), field_->Random().As()}); + auto t2 = std::vector({field_->Random().As(), field_->Random().As(), + field_->Random().As(), field_->Random().As()}); + auto f1 = Item::Ref(t1); // 4 items + auto f2 = Item::Ref(t2); // 4 items + + // THEN + // Add, AddInplace + auto add_ret = field_->Add(f1, f2); + EXPECT_TRUE((bool)field_->Equal(add_ret, field_->Add(f2, f1))); + Item temp = field_->DeepCopy(f1); + field_->AddInplace(&temp, f2); + EXPECT_TRUE((bool)field_->Equal(add_ret, temp)); + + // Neg & Sub, SubInplace + EXPECT_EQ(field_->IsIdentityZero(field_->Add(f1, field_->Neg(f1))), + std::vector(4, true)); + auto sub_ret = field_->Sub(f1, f2); + EXPECT_TRUE((bool)field_->Equal(sub_ret, field_->Add(f1, field_->Neg(f2)))); + temp = field_->DeepCopy(f1); + field_->SubInplace(&temp, f2); + EXPECT_TRUE((bool)field_->Equal(sub_ret, temp)); + + // Mul, MulInplace + auto mul_ret = field_->Mul(f1, f2); + EXPECT_TRUE((bool)field_->Equal(mul_ret, field_->Mul(f2, f1))); + temp = field_->DeepCopy(f1); + field_->MulInplace(&temp, f2); + EXPECT_TRUE((bool)field_->Equal(mul_ret, temp)); + + // Pow, PowInplace + // Test f1^r + auto r = 1000_mp; + auto ones = std::vector( + {field_->GetIdentityOne().As(), field_->GetIdentityOne().As(), + field_->GetIdentityOne().As(), field_->GetIdentityOne().As()}); + auto pow_temp = Item::Ref(ones); + for (int i = 0; i < 1000; i++) { + field_->MulInplace(&pow_temp, f1); + } + auto pow_ret1 = field_->Pow(f1, r); + EXPECT_TRUE((bool)field_->Equal(pow_ret1, pow_temp)); + auto pow_ret2 = field_->DeepCopy(f1); + field_->PowInplace(&pow_ret2, r); + EXPECT_TRUE((bool)field_->Equal(pow_ret2, pow_temp)); + + // Div, DivInplace & Inv + EXPECT_EQ(field_->IsIdentityOne(field_->Div(f1, f1)), + std::vector(4, true)); + auto div_ret = field_->Div(f1, f2); + temp = field_->DeepCopy(f1); + field_->DivInplace(&temp, f2); + EXPECT_TRUE((bool)field_->Equal(temp, div_ret)); + EXPECT_EQ(field_->IsIdentityOne( + field_->Mul(field_->Div(f1, f2), field_->Div(f2, f1))), + std::vector(4, true)); + EXPECT_EQ(field_->IsIdentityOne(field_->Mul(f1, field_->Inv(f1))), + std::vector(4, true)); + } + + void TestOrder() { + auto order = field_->GetOrder(); + + if (field_->GetExtensionDegree() == 1) { + auto f = field_->Random(); + EXPECT_EQ(field_->GetOrder() - 1_mp, field_->GetMulGroupOrder()); + EXPECT_EQ(field_->GetOrder(), field_->GetAddGroupOrder()); + // mul order + if (!field_->GetMulGroupOrder().IsZero()) { + auto t = field_->Pow(f, field_->GetMulGroupOrder()); + EXPECT_TRUE((bool)field_->Equal(t, field_->GetIdentityOne())); + } + // add order + if (!field_->GetAddGroupOrder().IsZero()) { + typename T::BaseFp order_fp; + // TODO: mpint 2 Fp + // order_fp.setMpz(crypto::hmcl::Mp2Mpz(order)); + auto t = field_->Mul(f, order_fp); + EXPECT_TRUE((bool)field_->Equal(t, field_->GetIdentityZero())); + } + } + } + + void TestSerialize() { + for (int i = 0; i < 1; i++) { + auto f = field_->Random(); + // Serialize + auto buf = field_->Serialize(f); + auto f1 = field_->Deserialize(buf); + EXPECT_TRUE((bool)field_->Equal(f, f1)); + // toString + auto one = field_->GetIdentityOne(); + if (field_->GetExtensionDegree() == 1) { + EXPECT_EQ(field_->ToString(one), "1"); + } else if (field_->GetExtensionDegree() == 2) { + EXPECT_EQ(field_->ToString(one), "1 0"); + } else if (field_->GetExtensionDegree() == 6) { + EXPECT_EQ(field_->ToString(one), "1 0 0 0 0 0"); + } else if (field_->GetExtensionDegree() == 12) { + EXPECT_EQ(field_->ToString(one), "1 0 0 0 0 0 0 0 0 0 0 0"); + } + } + } +}; + +#ifdef MCL_FIELD_YACL_TEST +#define DEFAULT_FIELD_TEST(intern_type, fieldType, degree, maxBitSize) \ + class Mcl##intern_type##Test \ + : public MclFieldTest> { \ + void SetUp() override { \ + field_ = GaloisFieldFactory::Instance().Create( \ + fieldType, ArgLib = kMclLib, \ + ArgMod = "0xffffffffffffffffffffffffffffffffffffffffffffff13"_mp, \ + ArgDegree = degree, ArgMaxBitSize = maxBitSize); \ + filed_name_ = field_->GetFieldName(); \ + } \ + }; \ + TEST_F(Mcl##intern_type##Test, Works) { RunAllTests(); } + +DEFAULT_FIELD_TEST(DefaultFp, kPrimeField, 1, 512); +DEFAULT_FIELD_TEST(FpWithSize256, kPrimeField, 1, 256); +DEFAULT_FIELD_TEST(DefaultFp2, kExtensionField, 2, 512); +DEFAULT_FIELD_TEST(DefaultFp6, kExtensionField, 6, 512); +DEFAULT_FIELD_TEST(DefaultFp12, kExtensionField, 12, 512); +#endif + +// TODO: temporarily disable mcl pairing test, since its weird error on Intel +// Mac +#define DECLARE_PAIRING_FIELD_TEST_CLASS(classname, pairing_name) \ + class MclPairing##classname##GTTest \ + : public MclFieldTest { \ + void SetUp() override { \ + auto pairing = crypto::hmcl::MclPGFactory::CreateByName(pairing_name); \ + field_ = pairing->GetGroupT(); \ + filed_name_ = "MclPairing" #classname "GTField"; \ + is_sub_field_ = true; \ + } \ + }; \ + TEST_F(MclPairing##classname##GTTest, DISABLED_Works) { RunAllTests(); } + +DECLARE_PAIRING_FIELD_TEST_CLASS(Bls12381, "bls12-381"); + +#ifdef MCL_ALL_PAIRING_FOR_YACL +DECLARE_PAIRING_FIELD_TEST_CLASS(BN254, "bn254"); +DECLARE_PAIRING_FIELD_TEST_CLASS(BN384M, "bn382m"); +DECLARE_PAIRING_FIELD_TEST_CLASS(BN384R, "bn382r"); +DECLARE_PAIRING_FIELD_TEST_CLASS(BN462, "bn462"); +DECLARE_PAIRING_FIELD_TEST_CLASS(BNSnark, "bn_snark1"); +DECLARE_PAIRING_FIELD_TEST_CLASS(BN160, "bn160"); +DECLARE_PAIRING_FIELD_TEST_CLASS(Bls12461, "bls12-461"); +DECLARE_PAIRING_FIELD_TEST_CLASS(BN256, "bn256"); +#endif + +} // namespace yacl::math::hmcl::test diff --git a/yacl/math/galois_field/mpint_field/mpint_field.cc b/yacl/math/galois_field/mpint_field/mpint_field.cc index f86c4a8e..25d85546 100644 --- a/yacl/math/galois_field/mpint_field/mpint_field.cc +++ b/yacl/math/galois_field/mpint_field/mpint_field.cc @@ -38,7 +38,11 @@ std::string MPIntField::GetFieldName() const { return kPrimeField; } MPInt MPIntField::GetOrder() const { return mod_; } -MPInt MPIntField::GetExtensionDegree() const { return MPInt::_1_; } +MPInt MPIntField::GetMulGroupOrder() const { return mod_ - 1_mp; } + +MPInt MPIntField::GetAddGroupOrder() const { return mod_; } + +uint64_t MPIntField::GetExtensionDegree() const { return 1; } MPInt MPIntField::GetBaseFieldOrder() const { return mod_; } diff --git a/yacl/math/galois_field/mpint_field/mpint_field.h b/yacl/math/galois_field/mpint_field/mpint_field.h index bc0feee0..1d8e3c08 100644 --- a/yacl/math/galois_field/mpint_field/mpint_field.h +++ b/yacl/math/galois_field/mpint_field/mpint_field.h @@ -32,7 +32,9 @@ class MPIntField : public GFScalarSketch { std::string GetFieldName() const override; MPInt GetOrder() const override; - MPInt GetExtensionDegree() const override; + MPInt GetMulGroupOrder() const override; + MPInt GetAddGroupOrder() const override; + uint64_t GetExtensionDegree() const override; MPInt GetBaseFieldOrder() const override; Item GetIdentityZero() const override; diff --git a/yacl/math/galois_field/mpint_field/mpint_field_test.cc b/yacl/math/galois_field/mpint_field/mpint_field_test.cc index f088ad5d..7b34ab06 100644 --- a/yacl/math/galois_field/mpint_field/mpint_field_test.cc +++ b/yacl/math/galois_field/mpint_field/mpint_field_test.cc @@ -29,7 +29,7 @@ TEST_F(MPIntFieldTest, AddWorks) { EXPECT_EQ(gf->GetFieldName(), kPrimeField); EXPECT_EQ(gf->GetOrder(), 13_mp); - EXPECT_TRUE(gf->GetExtensionDegree().IsOne()); + EXPECT_TRUE(gf->GetExtensionDegree() == 1); EXPECT_EQ(gf->GetBaseFieldOrder(), 13_mp); EXPECT_EQ(gf->GetIdentityZero(), 0_mp); @@ -312,4 +312,17 @@ TEST_F(MPIntFieldTest, VectorInplaceWorks) { ASSERT_EQ(a.AsSpan(), std::vector({10_mp, 10_mp, 4_mp})); } +TEST_F(MPIntFieldTest, OrderWorks) { + auto gf = GaloisFieldFactory::Instance().Create( + kPrimeField, ArgLib = kMPIntLib, ArgMod = 13_mp); + EXPECT_EQ(gf->GetOrder(), 13_mp); + auto x = 5_mp; + EXPECT_EQ(gf->GetOrder(), gf->GetAddGroupOrder()); + EXPECT_EQ(gf->GetOrder() - 1_mp, gf->GetMulGroupOrder()); + // Test additive order, x * order = 0(IdentityZero); + EXPECT_TRUE((bool)gf->IsIdentityZero(gf->Mul(x, gf->GetAddGroupOrder()))); + // Test multiplicative order, x ^ order = 1(IdentityOne); + EXPECT_TRUE((bool)gf->IsIdentityOne(gf->Pow(x, gf->GetMulGroupOrder()))); +} + } // namespace yacl::math::mpf::test diff --git a/yacl/math/mpint/tommath_ext_types.h b/yacl/math/mpint/tommath_ext_types.h index d3a0fad4..3e6f2b2c 100644 --- a/yacl/math/mpint/tommath_ext_types.h +++ b/yacl/math/mpint/tommath_ext_types.h @@ -19,7 +19,7 @@ #include "yacl/base/int128.h" #define MP_BITS_TO_DIGITS(bits) ((bits) + MP_DIGIT_BIT - 1) / MP_DIGIT_BIT -#define MP_BYTES_TO_DIGITS(bytes) MP_BITS_TO_DIGITS((bytes)*CHAR_BIT) +#define MP_BYTES_TO_DIGITS(bytes) MP_BITS_TO_DIGITS((bytes) * CHAR_BIT) void mpx_init(mp_int *a); void mpx_reserve(mp_int *a, size_t n_digits); diff --git a/yacl/utils/spi/item.h b/yacl/utils/spi/item.h index 5f63dff7..bffea4a3 100644 --- a/yacl/utils/spi/item.h +++ b/yacl/utils/spi/item.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "absl/types/span.h" @@ -262,7 +263,7 @@ class Item { OperandType operator,(const Item& other) const { return static_cast(((meta_ & 1) << 1) | (other.meta_ & 1)); - }; + } // operations only for array template