From 480756d2f0c658881e5684b6707b522a6b59ffd5 Mon Sep 17 00:00:00 2001 From: caojiafeng Date: Wed, 29 Nov 2023 11:23:15 +0800 Subject: [PATCH 01/21] [feat][aptos-stdlib] crypto algebra bn254 Signed-off-by: caojiafeng --- Cargo.lock | 12 + Cargo.toml | 1 + .../src/gas_schedule/aptos_framework.rs | 86 +++ .../src/components/feature_flags.rs | 3 + aptos-move/framework/Cargo.toml | 1 + .../aptos-stdlib/doc/bn254_algebra.md | 519 ++++++++++++++++++ .../framework/aptos-stdlib/doc/overview.md | 1 + .../sources/cryptography/bn254_algebra.move | 25 + .../framework/move-stdlib/doc/features.md | 60 ++ .../move-stdlib/sources/configs/features.move | 11 + .../cryptography/algebra/arithmetics/add.rs | 55 +- .../cryptography/algebra/arithmetics/div.rs | 49 +- .../algebra/arithmetics/double.rs | 38 +- .../cryptography/algebra/arithmetics/inv.rs | 29 +- .../cryptography/algebra/arithmetics/mul.rs | 41 +- .../cryptography/algebra/arithmetics/neg.rs | 56 +- .../algebra/arithmetics/scalar_mul.rs | 114 +++- .../cryptography/algebra/arithmetics/sqr.rs | 53 +- .../cryptography/algebra/arithmetics/sub.rs | 55 +- .../natives/cryptography/algebra/casting.rs | 28 +- .../natives/cryptography/algebra/constants.rs | 94 +++- .../src/natives/cryptography/algebra/eq.rs | 47 +- .../src/natives/cryptography/algebra/mod.rs | 99 +++- .../src/natives/cryptography/algebra/new.rs | 35 +- .../natives/cryptography/algebra/pairing.rs | 123 ++++- .../src/natives/cryptography/algebra/rand.rs | 41 +- .../cryptography/algebra/serialization.rs | 334 ++++++++++- aptos-move/vm-genesis/src/lib.rs | 1 + types/src/on_chain_config/aptos_features.rs | 1 + 29 files changed, 1974 insertions(+), 38 deletions(-) create mode 100644 aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md create mode 100644 aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move diff --git a/Cargo.lock b/Cargo.lock index 2e75442e86278..3b1cce5b82500 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1659,6 +1659,7 @@ dependencies = [ "aptos-vm", "aptos-vm-types", "ark-bls12-381", + "ark-bn254", "ark-ec", "ark-ff", "ark-serialize", @@ -4265,6 +4266,17 @@ dependencies = [ "ark-std", ] +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + [[package]] name = "ark-ec" version = "0.4.1" diff --git a/Cargo.toml b/Cargo.toml index eb41ba1379574..4649da3214fdc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -435,6 +435,7 @@ anstyle = "1.0.1" arc-swap = "1.6.0" arr_macro = "0.2.1" ark-bls12-381 = "0.4.0" +ark-bn254 = "0.4.0" ark-ec = "0.4.0" ark-ff = "0.4.0" ark-serialize = "0.4.0" diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs index 2334629380719..24dcb7b9a452b 100644 --- a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs @@ -16,6 +16,92 @@ crate::gas_schedule::macros::define_gas_parameters!( [account_create_address_base: InternalGas, "account.create_address.base", 6000], [account_create_signer_base: InternalGas, "account.create_signer.base", 6000], + [algebra_ark_bn254_fq2_add: InternalGas, { 12.. => "algebra.ark_bn254_fq2_add" }, 36380], + [algebra_ark_bn254_fq2_clone: InternalGas, { 12.. => "algebra.ark_bn254_fq2_clone" }, 4220], + [algebra_ark_bn254_fq2_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq2_deser" }, 223600], + [algebra_ark_bn254_fq2_div: InternalGas, { 12.. => "algebra.ark_bn254_fq2_div" }, 5016260], + [algebra_ark_bn254_fq2_eq: InternalGas, { 12.. => "algebra.ark_bn254_fq2_eq" }, 14520], + [algebra_ark_bn254_fq2_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fq2_from_u64" }, 18020], + [algebra_ark_bn254_fq2_inv: InternalGas, { 12.. => "algebra.ark_bn254_fq2_inv" }, 4010460], + [algebra_ark_bn254_fq2_mul: InternalGas, { 12.. => "algebra.ark_bn254_fq2_mul" }, 997720], + [algebra_ark_bn254_fq2_neg: InternalGas, { 12.. => "algebra.ark_bn254_fq2_neg" }, 23620], + [algebra_ark_bn254_fq2_one: InternalGas, { 12.. => "algebra.ark_bn254_fq2_one" }, 220], + [algebra_ark_bn254_fq2_pow_u256: InternalGas, { 12.. => "algebra.ark_bn254_fq2_pow_u256" }, 293284140], + [algebra_ark_bn254_fq2_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fq2_serialize" }, 161560], + [algebra_ark_bn254_fq2_square: InternalGas, { 12.. => "algebra.ark_bn254_fq2_square" }, 702900], + [algebra_ark_bn254_fq2_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq2_sub" }, 35160], + [algebra_ark_bn254_fq2_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq2_zero" }, 4220], + [algebra_ark_bn254_fq12_add: InternalGas, { 12.. => "algebra.ark_bn254_fq12_add" }, 36380], + [algebra_ark_bn254_fq12_clone: InternalGas, { 12.. => "algebra.ark_bn254_fq12_clone" }, 4220], + [algebra_ark_bn254_fq12_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq12_deser" }, 223600], + [algebra_ark_bn254_fq12_div: InternalGas, { 12.. => "algebra.ark_bn254_fq12_div" }, 5016260], + [algebra_ark_bn254_fq12_eq: InternalGas, { 12.. => "algebra.ark_bn254_fq12_eq" }, 14520], + [algebra_ark_bn254_fq12_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fq12_from_u64" }, 18020], + [algebra_ark_bn254_fq12_inv: InternalGas, { 12.. => "algebra.ark_bn254_fq12_inv" }, 4010460], + [algebra_ark_bn254_fq12_mul: InternalGas, { 12.. => "algebra.ark_bn254_fq12_mul" }, 997720], + [algebra_ark_bn254_fq12_neg: InternalGas, { 12.. => "algebra.ark_bn254_fq12_neg" }, 23620], + [algebra_ark_bn254_fq12_one: InternalGas, { 12.. => "algebra.ark_bn254_fq12_one" }, 220], + [algebra_ark_bn254_fq12_pow_u256: InternalGas, { 12.. => "algebra.ark_bn254_fq12_pow_u256" }, 293284140], + [algebra_ark_bn254_fq12_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fq12_serialize" }, 161560], + [algebra_ark_bn254_fq12_square: InternalGas, { 12.. => "algebra.ark_bn254_fq12_square" }, 702900], + [algebra_ark_bn254_fq12_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq12_sub" }, 35160], + [algebra_ark_bn254_fq12_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq12_zero" }, 4220], + [algebra_ark_bn254_fr_add: InternalGas, { 12.. => "algebra.ark_bn254_fr_add" }, 4220], + [algebra_ark_bn254_fr_deser: InternalGas, { 12.. => "algebra.ark_bn254_fr_deser" }, 15040], + [algebra_ark_bn254_fr_div: InternalGas, { 12.. => "algebra.ark_bn254_fr_div" }, 1188800], + [algebra_ark_bn254_fr_eq: InternalGas, { 12.. => "algebra.ark_bn254_fr_eq" }, 4240], + [algebra_ark_bn254_fr_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fr_from_u64" }, 9880], + [algebra_ark_bn254_fr_inv: InternalGas, { 12.. => "algebra.ark_bn254_fr_inv" }, 1172200], + [algebra_ark_bn254_fr_mul: InternalGas, { 12.. => "algebra.ark_bn254_fr_mul" }, 10040], + [algebra_ark_bn254_fr_neg: InternalGas, { 12.. => "algebra.ark_bn254_fr_neg" }, 4260], + [algebra_ark_bn254_fr_one: InternalGas, { 12.. => "algebra.ark_bn254_fr_one" }, 4220], + [algebra_ark_bn254_fr_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fr_serialize" }, 22060], + [algebra_ark_bn254_fr_square: InternalGas, { 12.. => "algebra.ark_bn254_fr_square" }, 9500], + [algebra_ark_bn254_fr_sub: InternalGas, { 12.. => "algebra.ark_bn254_fr_sub" }, 5800], + [algebra_ark_bn254_fr_zero: InternalGas, { 12.. => "algebra.ark_bn254_fr_zero" }, 4220], + [algebra_ark_bn254_fq_add: InternalGas, { 12.. => "algebra.ark_bn254_fq_add" }, 4220], + [algebra_ark_bn254_fq_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq_deser" }, 15040], + [algebra_ark_bn254_fq_div: InternalGas, { 12.. => "algebra.ark_bn254_fq_div" }, 1188800], + [algebra_ark_bn254_fq_eq: InternalGas, { 12.. => "algebra.ark_bn254_fq_eq" }, 4240], + [algebra_ark_bn254_fq_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fq_from_u64" }, 9880], + [algebra_ark_bn254_fq_inv: InternalGas, { 12.. => "algebra.ark_bn254_fq_inv" }, 1172200], + [algebra_ark_bn254_fq_mul: InternalGas, { 12.. => "algebra.ark_bn254_fq_mul" }, 10040], + [algebra_ark_bn254_fq_neg: InternalGas, { 12.. => "algebra.ark_bn254_fq_neg" }, 4260], + [algebra_ark_bn254_fq_one: InternalGas, { 12.. => "algebra.ark_bn254_fq_one" }, 4220], + [algebra_ark_bn254_fq_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fq_serialize" }, 22060], + [algebra_ark_bn254_fq_square: InternalGas, { 12.. => "algebra.ark_bn254_fq_square" }, 9500], + [algebra_ark_bn254_fq_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq_sub" }, 5800], + [algebra_ark_bn254_fq_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq_zero" }, 4220], + [algebra_ark_bn254_g1_affine_deser_comp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_deser_comp" }, 20591980], + [algebra_ark_bn254_g1_affine_deser_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_deser_uncomp" }, 14412760], + [algebra_ark_bn254_g1_affine_serialize_comp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_serialize_comp" }, 40280], + [algebra_ark_bn254_g1_affine_serialize_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_serialize_uncomp" }, 48660], + [algebra_ark_bn254_g1_proj_add: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_add" }, 216120], + [algebra_ark_bn254_g1_proj_double: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_double" }, 105280], + [algebra_ark_bn254_g1_proj_eq: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_eq" }, 100700], + [algebra_ark_bn254_g1_proj_generator: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_generator" }, 220], + [algebra_ark_bn254_g1_proj_infinity: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_infinity" }, 220], + [algebra_ark_bn254_g1_proj_neg: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_neg" }, 220], + [algebra_ark_bn254_g1_proj_scalar_mul: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_scalar_mul" }, 50470420], + [algebra_ark_bn254_g1_proj_sub: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_sub" }, 222940], + [algebra_ark_bn254_g1_proj_to_affine: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_to_affine" }, 2420700], + [algebra_ark_bn254_g2_affine_deser_comp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_deser_comp" }, 41201360], + [algebra_ark_bn254_g2_affine_deser_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_deser_uncomp" }, 20359580], + [algebra_ark_bn254_g2_affine_serialize_comp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_serialize_comp" }, 67560], + [algebra_ark_bn254_g2_affine_serialize_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_serialize_uncomp" }, 84340], + [algebra_ark_bn254_g2_proj_add: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_add" }, 648020], + [algebra_ark_bn254_g2_proj_double: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_double" }, 296780], + [algebra_ark_bn254_g2_proj_eq: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_eq" }, 303100], + [algebra_ark_bn254_g2_proj_generator: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_generator" }, 220], + [algebra_ark_bn254_g2_proj_infinity: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_infinity" }, 220], + [algebra_ark_bn254_g2_proj_neg: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_neg" }, 220], + [algebra_ark_bn254_g2_proj_scalar_mul: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_scalar_mul" }, 150530160], + [algebra_ark_bn254_g2_proj_sub: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_sub" }, 657380], + [algebra_ark_bn254_g2_proj_to_affine: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_to_affine" }, 2577140], + [algebra_ark_bn254_multi_pairing_base: InternalGas, { 12.. => "algebra.ark_bn254_multi_pairing_base" }, 179972980], + [algebra_ark_bn254_multi_pairing_per_pair: InternalGasPerArg, { 12.. => "algebra.ark_bn254_multi_pairing_per_pair" }, 92052840], + [algebra_ark_bn254_pairing: InternalGas, { 12.. => "algebra.ark_bn254_pairing" }, 296644400], + // Algebra gas parameters begin. // Generated at time 1680606720.0709136 by `scripts/algebra-gas/update_algebra_gas_params.py` with gas_per_ns=10.23. [algebra_ark_bls12_381_fq12_add: InternalGas, { 8.. => "algebra.ark_bls12_381_fq12_add" }, 36380], diff --git a/aptos-move/aptos-release-builder/src/components/feature_flags.rs b/aptos-move/aptos-release-builder/src/components/feature_flags.rs index 30b61a2758a5a..8b522629e3ab3 100644 --- a/aptos-move/aptos-release-builder/src/components/feature_flags.rs +++ b/aptos-move/aptos-release-builder/src/components/feature_flags.rs @@ -93,6 +93,7 @@ pub enum FeatureFlag { VMBinaryFormatV7, ResourceGroupsChargeAsSizeSum, CommissionChangeDelegationPool, + BN254Structures, } fn generate_features_blob(writer: &CodeWriter, data: &[u64]) { @@ -244,6 +245,7 @@ impl From for AptosFeatureFlag { FeatureFlag::CommissionChangeDelegationPool => { AptosFeatureFlag::COMMISSION_CHANGE_DELEGATION_POOL }, + FeatureFlag::BN254Structures => AptosFeatureFlag::BN254_STRUCTURES, } } } @@ -318,6 +320,7 @@ impl From for FeatureFlag { AptosFeatureFlag::COMMISSION_CHANGE_DELEGATION_POOL => { FeatureFlag::CommissionChangeDelegationPool }, + AptosFeatureFlag::BN254_STRUCTURES => FeatureFlag::BN254Structures, } } } diff --git a/aptos-move/framework/Cargo.toml b/aptos-move/framework/Cargo.toml index 6f3cf5b8e48bd..f3444ba520e71 100644 --- a/aptos-move/framework/Cargo.toml +++ b/aptos-move/framework/Cargo.toml @@ -26,6 +26,7 @@ aptos-table-natives = { workspace = true } aptos-types = { workspace = true } aptos-vm-types = { workspace = true } ark-bls12-381 = { workspace = true } +ark-bn254 = { workspace = true } ark-ec = { workspace = true } ark-ff = { workspace = true } ark-serialize = { workspace = true } diff --git a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md new file mode 100644 index 0000000000000..eb5e6803d86ae --- /dev/null +++ b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md @@ -0,0 +1,519 @@ + + + +# Module `0x1::bn254_algebra` + + + +- [Struct `Fr`](#0x1_bn254_algebra_Fr) +- [Struct `FormatFrLsb`](#0x1_bn254_algebra_FormatFrLsb) +- [Struct `FormatFrMsb`](#0x1_bn254_algebra_FormatFrMsb) +- [Struct `Fq`](#0x1_bn254_algebra_Fq) +- [Struct `FormatFqLsb`](#0x1_bn254_algebra_FormatFqLsb) +- [Struct `FormatFqMsb`](#0x1_bn254_algebra_FormatFqMsb) +- [Struct `Fq2`](#0x1_bn254_algebra_Fq2) +- [Struct `FormatFq2LscLsb`](#0x1_bn254_algebra_FormatFq2LscLsb) +- [Struct `Fq12`](#0x1_bn254_algebra_Fq12) +- [Struct `FormatFq12LscLsb`](#0x1_bn254_algebra_FormatFq12LscLsb) +- [Struct `G1`](#0x1_bn254_algebra_G1) +- [Struct `FormatG1Uncompr`](#0x1_bn254_algebra_FormatG1Uncompr) +- [Struct `FormatG1Compr`](#0x1_bn254_algebra_FormatG1Compr) +- [Struct `G2`](#0x1_bn254_algebra_G2) +- [Struct `FormatG2Uncompr`](#0x1_bn254_algebra_FormatG2Uncompr) +- [Struct `FormatG2Compr`](#0x1_bn254_algebra_FormatG2Compr) +- [Struct `Gt`](#0x1_bn254_algebra_Gt) +- [Struct `FormatGt`](#0x1_bn254_algebra_FormatGt) + + +
+ + + + + +## Struct `Fr` + + + +
struct Fr
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `FormatFrLsb` + + + +
struct FormatFrLsb
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `FormatFrMsb` + + + +
struct FormatFrMsb
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `Fq` + + + +
struct Fq
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `FormatFqLsb` + + + +
struct FormatFqLsb
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `FormatFqMsb` + + + +
struct FormatFqMsb
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `Fq2` + + + +
struct Fq2
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `FormatFq2LscLsb` + + + +
struct FormatFq2LscLsb
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `Fq12` + + + +
struct Fq12
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `FormatFq12LscLsb` + + + +
struct FormatFq12LscLsb
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `G1` + + + +
struct G1
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `FormatG1Uncompr` + + + +
struct FormatG1Uncompr
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `FormatG1Compr` + + + +
struct FormatG1Compr
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `G2` + + + +
struct G2
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `FormatG2Uncompr` + + + +
struct FormatG2Uncompr
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `FormatG2Compr` + + + +
struct FormatG2Compr
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `Gt` + + + +
struct Gt
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + + +## Struct `FormatGt` + + + +
struct FormatGt
+
+ + + +
+Fields + + +
+
+dummy_field: bool +
+
+ +
+
+ + +
+ + +[move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-stdlib/doc/overview.md b/aptos-move/framework/aptos-stdlib/doc/overview.md index 2429ae42c644f..6176385db1d97 100644 --- a/aptos-move/framework/aptos-stdlib/doc/overview.md +++ b/aptos-move/framework/aptos-stdlib/doc/overview.md @@ -17,6 +17,7 @@ This is the reference documentation of the Aptos standard library. - [`0x1::big_vector`](big_vector.md#0x1_big_vector) - [`0x1::bls12381`](bls12381.md#0x1_bls12381) - [`0x1::bls12381_algebra`](bls12381_algebra.md#0x1_bls12381_algebra) +- [`0x1::bn254_algebra`](bn254_algebra.md#0x1_bn254_algebra) - [`0x1::capability`](capability.md#0x1_capability) - [`0x1::comparator`](comparator.md#0x1_comparator) - [`0x1::copyable_any`](copyable_any.md#0x1_copyable_any) diff --git a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move new file mode 100644 index 0000000000000..3a28c9c271858 --- /dev/null +++ b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move @@ -0,0 +1,25 @@ +module std::bn254_algebra { + struct Fr {} + struct FormatFrLsb {} + struct FormatFrMsb {} + + struct Fq {} + struct FormatFqLsb {} + struct FormatFqMsb {} + + struct Fq2 {} + struct FormatFq2LscLsb {} + + struct Fq12 {} + struct FormatFq12LscLsb {} + + struct G1 {} + struct FormatG1Uncompr {} + struct FormatG1Compr {} + struct G2 {} + struct FormatG2Uncompr {} + struct FormatG2Compr {} + + struct Gt {} + struct FormatGt {} +} diff --git a/aptos-move/framework/move-stdlib/doc/features.md b/aptos-move/framework/move-stdlib/doc/features.md index c85b2b6bc24fa..17aeed218f41e 100644 --- a/aptos-move/framework/move-stdlib/doc/features.md +++ b/aptos-move/framework/move-stdlib/doc/features.md @@ -55,6 +55,8 @@ return true. - [Function `cryptography_algebra_enabled`](#0x1_features_cryptography_algebra_enabled) - [Function `get_bls12_381_strutures_feature`](#0x1_features_get_bls12_381_strutures_feature) - [Function `bls12_381_structures_enabled`](#0x1_features_bls12_381_structures_enabled) +- [Function `get_bn254_strutures_feature`](#0x1_features_get_bn254_strutures_feature) +- [Function `bn254_structures_enabled`](#0x1_features_bn254_structures_enabled) - [Function `get_periodical_reward_rate_decrease_feature`](#0x1_features_get_periodical_reward_rate_decrease_feature) - [Function `periodical_reward_rate_decrease_enabled`](#0x1_features_periodical_reward_rate_decrease_enabled) - [Function `get_partial_governance_voting`](#0x1_features_get_partial_governance_voting) @@ -207,6 +209,18 @@ Lifetime: transient + + +Whether the generic algebra implementation for BN254 operations are enabled. + +Lifetime: transient + + +
const BN254_STRUCTURES: u64 = 43;
+
+ + + Whether the Bulletproofs zero-knowledge range proof module is enabled, and the related native function is @@ -1115,6 +1129,52 @@ Lifetime: transient + + + + +## Function `get_bn254_strutures_feature` + + + +
public fun get_bn254_strutures_feature(): u64
+
+ + + +
+Implementation + + +
public fun get_bn254_strutures_feature(): u64 { BN254_STRUCTURES }
+
+ + + +
+ + + +## Function `bn254_structures_enabled` + + + +
public fun bn254_structures_enabled(): bool
+
+ + + +
+Implementation + + +
public fun bn254_structures_enabled(): bool acquires Features {
+    is_enabled(BN254_STRUCTURES)
+}
+
+ + +
diff --git a/aptos-move/framework/move-stdlib/sources/configs/features.move b/aptos-move/framework/move-stdlib/sources/configs/features.move index 9381807c40241..bd01c5f617bdf 100644 --- a/aptos-move/framework/move-stdlib/sources/configs/features.move +++ b/aptos-move/framework/move-stdlib/sources/configs/features.move @@ -145,6 +145,17 @@ module std::features { is_enabled(BLS12_381_STRUCTURES) } + /// Whether the generic algebra implementation for BN254 operations are enabled. + /// + /// Lifetime: transient + const BN254_STRUCTURES: u64 = 43; + + public fun get_bn254_strutures_feature(): u64 { BN254_STRUCTURES } + + public fun bn254_structures_enabled(): bool acquires Features { + is_enabled(BN254_STRUCTURES) + } + /// Whether native_public_key_validate aborts when a public key of the wrong length is given /// Lifetime: ephemeral const ED25519_PUBKEY_VALIDATE_RETURN_FALSE_WRONG_LENGTH: u64 = 14; diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/add.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/add.rs index ccace30f08b90..8b1fce1f0fff9 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/add.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/add.rs @@ -4,8 +4,8 @@ use crate::{ abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled, ark_binary_op_internal, natives::cryptography::algebra::{ - abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure, - E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure, + Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, safe_borrow_element, store_element, structure_from_ty_arg, }; @@ -63,8 +63,59 @@ pub fn add_internal( mul, ALGEBRA_ARK_BLS12_381_FQ12_MUL ), + Some(Structure::BN254(s)) => add_internal_bn254(context, args, s), _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), } } + +fn add_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr => { + ark_binary_op_internal!(context, args, ark_bn254::Fr, add, ALGEBRA_ARK_BN254_FR_ADD) + }, + BN254Structure::BN254Fq => { + ark_binary_op_internal!(context, args, ark_bn254::Fq, add, ALGEBRA_ARK_BN254_FQ_ADD) + }, + BN254Structure::BN254Fq2 => ark_binary_op_internal!( + context, + args, + ark_bn254::Fq2, + add, + ALGEBRA_ARK_BN254_FQ2_ADD + ), + BN254Structure::BN254Fq12 => ark_binary_op_internal!( + context, + args, + ark_bn254::Fq12, + add, + ALGEBRA_ARK_BN254_FQ12_ADD + ), + BN254Structure::BN254G1 => ark_binary_op_internal!( + context, + args, + ark_bn254::G1Projective, + add, + ALGEBRA_ARK_BN254_G1_PROJ_ADD + ), + BN254Structure::BN254G2 => ark_binary_op_internal!( + context, + args, + ark_bn254::G2Projective, + add, + ALGEBRA_ARK_BN254_G2_PROJ_ADD + ), + BN254Structure::BN254Gt => ark_binary_op_internal!( + context, + args, + ark_bn254::Fq12, + mul, + ALGEBRA_ARK_BN254_FQ12_MUL + ), + } +} diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/div.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/div.rs index 1b1f5a977a5b0..688eb53879a34 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/div.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/div.rs @@ -3,8 +3,8 @@ use crate::{ abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled, natives::cryptography::algebra::{ - abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure, - E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure, + Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, safe_borrow_element, store_element, structure_from_ty_arg, }; @@ -59,6 +59,51 @@ pub fn div_internal( ALGEBRA_ARK_BLS12_381_FQ12_EQ, ALGEBRA_ARK_BLS12_381_FQ12_DIV ), + Some(Structure::BN254(s)) => div_internal_bn254(context, args, s), + _ => Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, + }), + } +} + +fn div_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr => ark_div_internal!( + context, + args, + ark_bn254::Fr, + div, + ALGEBRA_ARK_BN254_FR_EQ, + ALGEBRA_ARK_BN254_FR_DIV + ), + BN254Structure::BN254Fq => ark_div_internal!( + context, + args, + ark_bn254::Fq, + div, + ALGEBRA_ARK_BN254_FQ_EQ, + ALGEBRA_ARK_BN254_FQ_DIV + ), + BN254Structure::BN254Fq2 => ark_div_internal!( + context, + args, + ark_bn254::Fq2, + div, + ALGEBRA_ARK_BN254_FQ2_EQ, + ALGEBRA_ARK_BN254_FQ2_DIV + ), + BN254Structure::BN254Fq12 => ark_div_internal!( + context, + args, + ark_bn254::Fq12, + div, + ALGEBRA_ARK_BN254_FQ12_EQ, + ALGEBRA_ARK_BN254_FQ12_DIV + ), _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/double.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/double.rs index f6137121b01e9..9a6ed0190c9f6 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/double.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/double.rs @@ -4,8 +4,8 @@ use crate::{ abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled, ark_unary_op_internal, natives::cryptography::algebra::{ - abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure, - E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure, + Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, safe_borrow_element, store_element, structure_from_ty_arg, }; @@ -47,6 +47,40 @@ pub fn double_internal( square, ALGEBRA_ARK_BLS12_381_FQ12_SQUARE ), + Some(Structure::BN254(s)) => double_internal_bn254(context, args, s), + _ => Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, + }), + } +} + +fn double_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254G1 => ark_unary_op_internal!( + context, + args, + ark_bn254::G1Projective, + double, + ALGEBRA_ARK_BN254_G1_PROJ_DOUBLE + ), + BN254Structure::BN254G2 => ark_unary_op_internal!( + context, + args, + ark_bn254::G2Projective, + double, + ALGEBRA_ARK_BN254_G2_PROJ_DOUBLE + ), + BN254Structure::BN254Gt => ark_unary_op_internal!( + context, + args, + ark_bn254::Fq12, + square, + ALGEBRA_ARK_BN254_FQ12_SQUARE + ), _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/inv.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/inv.rs index 5500230abfe8d..e73a3302d18d1 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/inv.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/inv.rs @@ -3,8 +3,8 @@ use crate::{ abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled, natives::cryptography::algebra::{ - abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure, - E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure, + Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, safe_borrow_element, store_element, structure_from_ty_arg, }; @@ -52,6 +52,31 @@ pub fn inv_internal( ark_bls12_381::Fq12, ALGEBRA_ARK_BLS12_381_FQ12_INV ), + Some(Structure::BN254(s)) => inv_internal_bn254(context, args, s), + _ => Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, + }), + } +} + +fn inv_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr => { + ark_inverse_internal!(context, args, ark_bn254::Fr, ALGEBRA_ARK_BN254_FR_INV) + }, + BN254Structure::BN254Fq => { + ark_inverse_internal!(context, args, ark_bn254::Fq, ALGEBRA_ARK_BN254_FQ_INV) + }, + BN254Structure::BN254Fq2 => { + ark_inverse_internal!(context, args, ark_bn254::Fq2, ALGEBRA_ARK_BN254_FQ2_INV) + }, + BN254Structure::BN254Fq12 => { + ark_inverse_internal!(context, args, ark_bn254::Fq12, ALGEBRA_ARK_BN254_FQ12_INV) + }, _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/mul.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/mul.rs index 6233190dd65b6..e377522e84673 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/mul.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/mul.rs @@ -4,8 +4,8 @@ use crate::{ abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled, ark_binary_op_internal, natives::cryptography::algebra::{ - abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure, - E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure, + Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, safe_borrow_element, store_element, structure_from_ty_arg, }; @@ -38,6 +38,43 @@ pub fn mul_internal( mul, ALGEBRA_ARK_BLS12_381_FQ12_MUL ), + Some(Structure::BN254(s)) => mul_internal_bn254(context, args, s), + _ => Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, + }), + } +} + +fn mul_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr => { + ark_binary_op_internal!(context, args, ark_bn254::Fr, mul, ALGEBRA_ARK_BN254_FR_MUL) + }, + BN254Structure::BN254Fq => { + ark_binary_op_internal!(context, args, ark_bn254::Fq, mul, ALGEBRA_ARK_BN254_FQ_MUL) + }, + BN254Structure::BN254Fq2 => { + ark_binary_op_internal!( + context, + args, + ark_bn254::Fq2, + mul, + ALGEBRA_ARK_BN254_FQ2_MUL + ) + }, + BN254Structure::BN254Fq12 => { + ark_binary_op_internal!( + context, + args, + ark_bn254::Fq12, + mul, + ALGEBRA_ARK_BN254_FQ12_MUL + ) + }, _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/neg.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/neg.rs index e0dfdf0b2f339..96a371eae35f6 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/neg.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/neg.rs @@ -4,8 +4,8 @@ use crate::{ abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled, ark_unary_op_internal, natives::cryptography::algebra::{ - abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure, - E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure, + Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, safe_borrow_element, store_element, structure_from_ty_arg, }; @@ -63,8 +63,60 @@ pub fn neg_internal( let new_handle = store_element!(context, new_element)?; Ok(smallvec![Value::u64(new_handle as u64)]) }, + Some(Structure::BN254(s)) => neg_internal_bn254(context, args, s), _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), } } + +fn neg_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr => { + ark_unary_op_internal!(context, args, ark_bn254::Fr, neg, ALGEBRA_ARK_BN254_FR_NEG) + }, + BN254Structure::BN254Fq => { + ark_unary_op_internal!(context, args, ark_bn254::Fq, neg, ALGEBRA_ARK_BN254_FQ_NEG) + }, + BN254Structure::BN254Fq2 => ark_unary_op_internal!( + context, + args, + ark_bn254::Fq2, + neg, + ALGEBRA_ARK_BN254_FQ2_NEG + ), + BN254Structure::BN254Fq12 => ark_unary_op_internal!( + context, + args, + ark_bn254::Fq12, + neg, + ALGEBRA_ARK_BN254_FQ12_NEG + ), + BN254Structure::BN254G1 => ark_unary_op_internal!( + context, + args, + ark_bn254::G1Projective, + neg, + ALGEBRA_ARK_BN254_G1_PROJ_NEG + ), + BN254Structure::BN254G2 => ark_unary_op_internal!( + context, + args, + ark_bn254::G2Projective, + neg, + ALGEBRA_ARK_BN254_G2_PROJ_NEG + ), + BN254Structure::BN254Gt => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!(context, handle, ark_bn254::Fq12, element_ptr, element); + context.charge(ALGEBRA_ARK_BN254_FQ12_INV)?; + let new_element = element.inverse().ok_or_else(abort_invariant_violated)?; + let new_handle = store_element!(context, new_element)?; + Ok(smallvec![Value::u64(new_handle as u64)]) + }, + } +} diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/scalar_mul.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/scalar_mul.rs index a144385762d07..e62961789cde2 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/scalar_mul.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/scalar_mul.rs @@ -4,9 +4,9 @@ use crate::{ abort_unless_feature_flag_enabled, natives::cryptography::{ algebra::{ - abort_invariant_violated, AlgebraContext, Structure, E_TOO_MUCH_MEMORY_USED, - MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_INPUT_VECTOR_SIZES_NOT_MATCHING, - MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, AlgebraContext, BN254Structure, Structure, + E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, + MOVE_ABORT_CODE_INPUT_VECTOR_SIZES_NOT_MATCHING, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, helpers::log2_ceil, }, @@ -35,6 +35,19 @@ fn feature_flag_of_group_scalar_mul( | (Some(Structure::BLS12381Gt), Some(Structure::BLS12381Fr)) => { Some(FeatureFlag::BLS12_381_STRUCTURES) }, + ( + Some(Structure::BN254(BN254Structure::BN254G1)), + Some(Structure::BN254(BN254Structure::BN254Fr)), + ) + | ( + Some(Structure::BN254(BN254Structure::BN254G2)), + Some(Structure::BN254(BN254Structure::BN254Fr)), + ) + | ( + Some(Structure::BN254(BN254Structure::BN254Gt)), + Some(Structure::BN254(BN254Structure::BN254Fr)), + ) => Some(FeatureFlag::BN254_STRUCTURES), + _ => None, } } @@ -134,6 +147,60 @@ pub fn scalar_mul_internal( let new_handle = store_element!(context, new_element)?; Ok(smallvec![Value::u64(new_handle as u64)]) }, + ( + Some(Structure::BN254(group_structure)), + Some(Structure::BN254(scalar_field_structure)), + ) => scalar_mul_internal_bn254(context, args, group_structure, scalar_field_structure), + _ => Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, + }), + } +} + +fn scalar_mul_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + group_structure: BN254Structure, + scalar_field_structure: BN254Structure, +) -> SafeNativeResult> { + match (group_structure, scalar_field_structure) { + (BN254Structure::BN254G1, BN254Structure::BN254Fr) => { + ark_scalar_mul_internal!( + context, + args, + ark_bn254::G1Projective, + ark_bn254::Fr, + mul_bigint, + ALGEBRA_ARK_BN254_G1_PROJ_SCALAR_MUL + ) + }, + (BN254Structure::BN254G2, BN254Structure::BN254Fr) => { + ark_scalar_mul_internal!( + context, + args, + ark_bn254::G2Projective, + ark_bn254::Fr, + mul_bigint, + ALGEBRA_ARK_BN254_G2_PROJ_SCALAR_MUL + ) + }, + (BN254Structure::BN254Gt, BN254Structure::BN254Fr) => { + let scalar_handle = safely_pop_arg!(args, u64) as usize; + let element_handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!( + context, + element_handle, + ark_bn254::Fq12, + element_ptr, + element + ); + safe_borrow_element!(context, scalar_handle, ark_bn254::Fr, scalar_ptr, scalar); + let scalar_bigint: ark_ff::BigInteger256 = (*scalar).into(); + context.charge(ALGEBRA_ARK_BN254_FQ12_POW_U256)?; + let new_element = element.pow(scalar_bigint); + let new_handle = store_element!(context, new_element)?; + Ok(smallvec![Value::u64(new_handle as u64)]) + }, _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), @@ -220,6 +287,47 @@ pub fn multi_scalar_mul_internal( ark_bls12_381::Fr ) }, + ( + Some(Structure::BN254(group_structure)), + Some(Structure::BN254(scalar_field_structure)), + ) => { + multi_scalar_mul_internal_bn254(context, args, group_structure, scalar_field_structure) + }, + _ => Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, + }), + } +} + +fn multi_scalar_mul_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + group_structure: BN254Structure, + scalar_field_structure: BN254Structure, +) -> SafeNativeResult> { + match (group_structure, scalar_field_structure) { + (BN254Structure::BN254G1, BN254Structure::BN254Fr) => { + ark_msm_internal!( + context, + args, + ALGEBRA_ARK_BN254_G1_PROJ_TO_AFFINE.per::(), + ALGEBRA_ARK_BN254_G1_PROJ_ADD.per::(), + ALGEBRA_ARK_BN254_G1_PROJ_DOUBLE.per::(), + ark_bn254::G1Projective, + ark_bn254::Fr + ) + }, + (BN254Structure::BN254G2, BN254Structure::BN254Fr) => { + ark_msm_internal!( + context, + args, + ALGEBRA_ARK_BN254_G2_PROJ_TO_AFFINE.per::(), + ALGEBRA_ARK_BN254_G2_PROJ_ADD.per::(), + ALGEBRA_ARK_BN254_G2_PROJ_DOUBLE.per::(), + ark_bn254::G2Projective, + ark_bn254::Fr + ) + }, _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sqr.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sqr.rs index 34fe76f3f0b94..bcf36dcbc473e 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sqr.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sqr.rs @@ -4,8 +4,8 @@ use crate::{ abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled, ark_unary_op_internal, natives::cryptography::algebra::{ - abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure, - E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure, + Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, safe_borrow_element, store_element, structure_from_ty_arg, }; @@ -38,6 +38,55 @@ pub fn sqr_internal( square, ALGEBRA_ARK_BLS12_381_FQ12_SQUARE ), + Some(Structure::BN254(s)) => sqr_internal_bn254(context, args, s), + _ => Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, + }), + } +} + +fn sqr_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr => { + ark_unary_op_internal!( + context, + args, + ark_bn254::Fr, + square, + ALGEBRA_ARK_BN254_FR_SQUARE + ) + }, + BN254Structure::BN254Fq => { + ark_unary_op_internal!( + context, + args, + ark_bn254::Fq, + square, + ALGEBRA_ARK_BN254_FQ_SQUARE + ) + }, + BN254Structure::BN254Fq2 => { + ark_unary_op_internal!( + context, + args, + ark_bn254::Fq2, + square, + ALGEBRA_ARK_BN254_FQ2_SQUARE + ) + }, + BN254Structure::BN254Fq12 => { + ark_unary_op_internal!( + context, + args, + ark_bn254::Fq12, + square, + ALGEBRA_ARK_BN254_FQ12_SQUARE + ) + }, _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sub.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sub.rs index 08ce570f41408..8b586a33ed065 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sub.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sub.rs @@ -4,8 +4,8 @@ use crate::{ abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled, ark_binary_op_internal, natives::cryptography::algebra::{ - abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure, - E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure, + Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, safe_borrow_element, store_element, structure_from_ty_arg, }; @@ -63,8 +63,59 @@ pub fn sub_internal( div, ALGEBRA_ARK_BLS12_381_FQ12_DIV ), + Some(Structure::BN254(s)) => sub_internal_bn254(context, args, s), _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), } } + +fn sub_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr => { + ark_binary_op_internal!(context, args, ark_bn254::Fr, sub, ALGEBRA_ARK_BN254_FR_SUB) + }, + BN254Structure::BN254Fq => { + ark_binary_op_internal!(context, args, ark_bn254::Fq, sub, ALGEBRA_ARK_BN254_FQ_SUB) + }, + BN254Structure::BN254Fq2 => ark_binary_op_internal!( + context, + args, + ark_bn254::Fq2, + sub, + ALGEBRA_ARK_BN254_FQ2_SUB + ), + BN254Structure::BN254Fq12 => ark_binary_op_internal!( + context, + args, + ark_bn254::Fq12, + sub, + ALGEBRA_ARK_BN254_FQ12_SUB + ), + BN254Structure::BN254G1 => ark_binary_op_internal!( + context, + args, + ark_bn254::G1Projective, + sub, + ALGEBRA_ARK_BN254_G1_PROJ_SUB + ), + BN254Structure::BN254G2 => ark_binary_op_internal!( + context, + args, + ark_bn254::G2Projective, + sub, + ALGEBRA_ARK_BN254_G2_PROJ_SUB + ), + BN254Structure::BN254Gt => ark_binary_op_internal!( + context, + args, + ark_bn254::Fq12, + div, + ALGEBRA_ARK_BN254_FQ12_DIV + ), + } +} diff --git a/aptos-move/framework/src/natives/cryptography/algebra/casting.rs b/aptos-move/framework/src/natives/cryptography/algebra/casting.rs index 43bd4d09f840e..26a71b07c8118 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/casting.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/casting.rs @@ -3,8 +3,8 @@ use crate::{ abort_unless_feature_flag_enabled, natives::cryptography::algebra::{ - abort_invariant_violated, AlgebraContext, Structure, BLS12381_R_SCALAR, - MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, AlgebraContext, BN254Structure, Structure, BLS12381_R_SCALAR, + BN254_R_SCALAR, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, safe_borrow_element, structure_from_ty_arg, }; @@ -27,6 +27,10 @@ fn feature_flag_of_casting( (Some(Structure::BLS12381Fq12), Some(Structure::BLS12381Gt)) => { Some(FeatureFlag::BLS12_381_STRUCTURES) }, + ( + Some(Structure::BN254(BN254Structure::BN254Fq12)), + Some(Structure::BN254(BN254Structure::BN254Gt)), + ) => Some(FeatureFlag::BN254_STRUCTURES), _ => None, } } @@ -58,6 +62,19 @@ pub fn downcast_internal( Ok(smallvec![Value::bool(false), Value::u64(handle as u64)]) } }, + ( + Some(Structure::BN254(BN254Structure::BN254Fq12)), + Some(Structure::BN254(BN254Structure::BN254Gt)), + ) => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!(context, handle, ark_bn254::Fq12, element_ptr, element); + context.charge(ALGEBRA_ARK_BN254_FQ12_POW_U256)?; + if element.pow(BN254_R_SCALAR.0) == ark_bn254::Fq12::one() { + Ok(smallvec![Value::bool(true), Value::u64(handle as u64)]) + } else { + Ok(smallvec![Value::bool(false), Value::u64(handle as u64)]) + } + }, _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), @@ -78,6 +95,13 @@ pub fn upcast_internal( let handle = safely_pop_arg!(args, u64); Ok(smallvec![Value::u64(handle)]) }, + ( + Some(Structure::BN254(BN254Structure::BN254Gt)), + Some(Structure::BN254(BN254Structure::BN254Fq12)), + ) => { + let handle = safely_pop_arg!(args, u64); + Ok(smallvec![Value::u64(handle)]) + }, _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), diff --git a/aptos-move/framework/src/natives/cryptography/algebra/constants.rs b/aptos-move/framework/src/natives/cryptography/algebra/constants.rs index 73eadaf01d38d..f4d12284e59e7 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/constants.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/constants.rs @@ -3,9 +3,10 @@ use crate::{ abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled, natives::cryptography::algebra::{ - feature_flag_from_structure, AlgebraContext, Structure, BLS12381_GT_GENERATOR, - BLS12381_Q12_LENDIAN, BLS12381_R_LENDIAN, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, - MOVE_ABORT_CODE_NOT_IMPLEMENTED, + feature_flag_from_structure, AlgebraContext, BN254Structure, Structure, + BLS12381_GT_GENERATOR, BLS12381_Q12_LENDIAN, BLS12381_R_LENDIAN, BN254_GT_GENERATOR, + BN254_Q12_LENDIAN, BN254_Q2_LENDIAN, BN254_Q_LENDIAN, BN254_R_LENDIAN, + E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, store_element, structure_from_ty_arg, }; @@ -65,11 +66,46 @@ pub fn zero_internal( one, ALGEBRA_ARK_BLS12_381_FQ12_ONE ), + Some(Structure::BN254(s)) => zero_internal_bn254(context, s), _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), } } +pub fn zero_internal_bn254( + context: &mut SafeNativeContext, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr => { + ark_constant_op_internal!(context, ark_bn254::Fr, zero, ALGEBRA_ARK_BN254_FR_ZERO) + }, + BN254Structure::BN254Fq => { + ark_constant_op_internal!(context, ark_bn254::Fq, zero, ALGEBRA_ARK_BN254_FQ_ZERO) + }, + BN254Structure::BN254Fq2 => { + ark_constant_op_internal!(context, ark_bn254::Fq2, zero, ALGEBRA_ARK_BN254_FQ2_ZERO) + }, + BN254Structure::BN254Fq12 => { + ark_constant_op_internal!(context, ark_bn254::Fq12, zero, ALGEBRA_ARK_BN254_FQ12_ZERO) + }, + BN254Structure::BN254G1 => ark_constant_op_internal!( + context, + ark_bn254::G1Projective, + zero, + ALGEBRA_ARK_BN254_G1_PROJ_INFINITY + ), + BN254Structure::BN254G2 => ark_constant_op_internal!( + context, + ark_bn254::G2Projective, + zero, + ALGEBRA_ARK_BN254_G2_PROJ_INFINITY + ), + BN254Structure::BN254Gt => { + ark_constant_op_internal!(context, ark_bn254::Fq12, one, ALGEBRA_ARK_BN254_FQ12_ONE) + }, + } +} pub fn one_internal( context: &mut SafeNativeContext, @@ -109,11 +145,49 @@ pub fn one_internal( let handle = store_element!(context, element)?; Ok(smallvec![Value::u64(handle as u64)]) }, + Some(Structure::BN254(s)) => one_internal_bn254(context, s), _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), } } +fn one_internal_bn254( + context: &mut SafeNativeContext, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr => { + ark_constant_op_internal!(context, ark_bn254::Fr, one, ALGEBRA_ARK_BLS12_381_FR_ONE) + }, + BN254Structure::BN254Fq => { + ark_constant_op_internal!(context, ark_bn254::Fq, one, ALGEBRA_ARK_BN254_FQ_ONE) + }, + BN254Structure::BN254Fq2 => { + ark_constant_op_internal!(context, ark_bn254::Fq2, one, ALGEBRA_ARK_BN254_FQ2_ONE) + }, + BN254Structure::BN254Fq12 => { + ark_constant_op_internal!(context, ark_bn254::Fq12, one, ALGEBRA_ARK_BN254_FQ12_ONE) + }, + BN254Structure::BN254G1 => ark_constant_op_internal!( + context, + ark_bn254::G1Projective, + generator, + ALGEBRA_ARK_BN254_G1_PROJ_GENERATOR + ), + BN254Structure::BN254G2 => ark_constant_op_internal!( + context, + ark_bn254::G2Projective, + generator, + ALGEBRA_ARK_BN254_G2_PROJ_GENERATOR + ), + BN254Structure::BN254Gt => { + context.charge(ALGEBRA_ARK_BN254_FQ12_CLONE)?; + let element = *Lazy::force(&BN254_GT_GENERATOR); + let handle = store_element!(context, element)?; + Ok(smallvec![Value::u64(handle as u64)]) + }, + } +} pub fn order_internal( context: &mut SafeNativeContext, @@ -133,8 +207,22 @@ pub fn order_internal( Some(Structure::BLS12381Fq12) => { Ok(smallvec![Value::vector_u8(BLS12381_Q12_LENDIAN.clone())]) }, + Some(Structure::BN254(s)) => order_internal_bn254(s), _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), } } + +#[inline] +fn order_internal_bn254(structure: BN254Structure) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr + | BN254Structure::BN254Gt + | BN254Structure::BN254G1 + | BN254Structure::BN254G2 => Ok(smallvec![Value::vector_u8(BN254_R_LENDIAN.clone())]), + BN254Structure::BN254Fq => Ok(smallvec![Value::vector_u8(BN254_Q_LENDIAN.clone())]), + BN254Structure::BN254Fq2 => Ok(smallvec![Value::vector_u8(BN254_Q2_LENDIAN.clone())]), + BN254Structure::BN254Fq12 => Ok(smallvec![Value::vector_u8(BN254_Q12_LENDIAN.clone())]), + } +} diff --git a/aptos-move/framework/src/natives/cryptography/algebra/eq.rs b/aptos-move/framework/src/natives/cryptography/algebra/eq.rs index 8e94fb0a2efb1..4b7bbdb1c717e 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/eq.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/eq.rs @@ -3,8 +3,8 @@ use crate::{ abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled, natives::cryptography::algebra::{ - abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure, - MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure, + Structure, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, safe_borrow_element, structure_from_ty_arg, }; @@ -67,8 +67,51 @@ pub fn eq_internal( ark_bls12_381::Fq12, ALGEBRA_ARK_BLS12_381_FQ12_EQ ), + Some(Structure::BN254(bn254_structure)) => { + eq_internal_bn254(context, args, bn254_structure) + }, _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), } } + +fn eq_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr => { + ark_eq_internal!(context, args, ark_bn254::Fr, ALGEBRA_ARK_BN254_FR_EQ) + }, + BN254Structure::BN254Fq => { + ark_eq_internal!(context, args, ark_bn254::Fq, ALGEBRA_ARK_BN254_FQ_EQ) + }, + BN254Structure::BN254Fq2 => { + ark_eq_internal!(context, args, ark_bn254::Fq2, ALGEBRA_ARK_BN254_FQ2_EQ) + }, + BN254Structure::BN254Fq12 => { + ark_eq_internal!(context, args, ark_bn254::Fq12, ALGEBRA_ARK_BN254_FQ12_EQ) + }, + BN254Structure::BN254G1 => { + ark_eq_internal!( + context, + args, + ark_bn254::G1Projective, + ALGEBRA_ARK_BN254_G1_PROJ_EQ + ) + }, + BN254Structure::BN254G2 => { + ark_eq_internal!( + context, + args, + ark_bn254::G2Projective, + ALGEBRA_ARK_BN254_G2_PROJ_EQ + ) + }, + BN254Structure::BN254Gt => { + ark_eq_internal!(context, args, ark_bn254::Fq12, ALGEBRA_ARK_BN254_FQ12_EQ) + }, + } +} diff --git a/aptos-move/framework/src/natives/cryptography/algebra/mod.rs b/aptos-move/framework/src/natives/cryptography/algebra/mod.rs index fd100020dd5e2..83c9ccf46fb68 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/mod.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/mod.rs @@ -25,6 +25,8 @@ use arithmetics::{ inv::inv_internal, scalar_mul::{multi_scalar_mul_internal, scalar_mul_internal}, }; +use ark_ec::{pairing::Pairing, AffineRepr}; +use ark_ff::{BigInteger, PrimeField}; use ark_serialize::CanonicalDeserialize; use better_any::{Tid, TidAble}; use move_binary_format::errors::PartialVMError; @@ -58,6 +60,33 @@ pub enum Structure { BLS12381G2, BLS12381Gt, BLS12381Fr, + BN254(BN254Structure), +} +#[derive(Copy, Clone, Eq, Hash, PartialEq)] +pub enum BN254Structure { + BN254Fr, + BN254Fq, + BN254Fq2, + BN254Fq12, + BN254G1, + BN254G2, + BN254Gt, +} +impl TryFrom for BN254Structure { + type Error = (); + + fn try_from(value: TypeTag) -> Result { + match value.to_string().as_str() { + "0x1::bn254_algebra::Fr" => Ok(Self::BN254Fr), + "0x1::bn254_algebra::Fq" => Ok(Self::BN254Fq), + "0x1::bn254_algebra::Fq2" => Ok(Self::BN254Fq2), + "0x1::bn254_algebra::Fq12" => Ok(Self::BN254Fq12), + "0x1::bn254_algebra::G1" => Ok(Self::BN254G1), + "0x1::bn254_algebra::G2" => Ok(Self::BN254G2), + "0x1::bn254_algebra::Gt" => Ok(Self::BN254Gt), + _ => Err(()), + } + } } impl TryFrom for Structure { @@ -70,7 +99,8 @@ impl TryFrom for Structure { "0x1::bls12381_algebra::G1" => Ok(Structure::BLS12381G1), "0x1::bls12381_algebra::G2" => Ok(Structure::BLS12381G2), "0x1::bls12381_algebra::Gt" => Ok(Structure::BLS12381Gt), - _ => Err(()), + + _ => Ok(Structure::BN254(BN254Structure::try_from(value)?)), } } } @@ -94,6 +124,44 @@ pub enum SerializationFormat { BLS12381Gt, BLS12381FrLsb, BLS12381FrMsb, + + BN254(BN254SerializationFormat), +} + +#[derive(Copy, Clone, Eq, Hash, PartialEq)] +pub enum BN254SerializationFormat { + BN254G1Compressed, + BN254G1Uncompressed, + BN254G2Compressed, + BN254G2Uncompressed, + BN254Gt, + BN254FrLsb, + BN254FrMsb, + BN254FqLsb, + BN254FqMsb, + BN254Fq2LscLsb, + BN254Fq12LscLsb, +} + +impl TryFrom for BN254SerializationFormat { + type Error = (); + + fn try_from(value: TypeTag) -> Result { + match value.to_string().as_str() { + "0x1::bn254_algebra::FormatG1Uncompr" => Ok(Self::BN254G1Uncompressed), + "0x1::bn254_algebra::FormatG1Compr" => Ok(Self::BN254G1Compressed), + "0x1::bn254_algebra::FormatG2Uncompr" => Ok(Self::BN254G2Uncompressed), + "0x1::bn254_algebra::FormatG2Compr" => Ok(Self::BN254G2Compressed), + "0x1::bn254_algebra::FormatGt" => Ok(Self::BN254Gt), + "0x1::bn254_algebra::FormatFrLsb" => Ok(Self::BN254FrLsb), + "0x1::bn254_algebra::FormatFrMsb" => Ok(Self::BN254FrMsb), + "0x1::bn254_algebra::FormatFqLsb" => Ok(Self::BN254FqLsb), + "0x1::bn254_algebra::FormatFqMsb" => Ok(Self::BN254FqMsb), + "0x1::bn254_algebra::FormatFq2LscLsb" => Ok(Self::BN254Fq2LscLsb), + "0x1::bn254_algebra::FormatFq12LscLsb" => Ok(Self::BN254Fq12LscLsb), + _ => Err(()), + } + } } impl TryFrom for SerializationFormat { @@ -115,7 +183,10 @@ impl TryFrom for SerializationFormat { "0x1::bls12381_algebra::FormatGt" => Ok(SerializationFormat::BLS12381Gt), "0x1::bls12381_algebra::FormatFrLsb" => Ok(SerializationFormat::BLS12381FrLsb), "0x1::bls12381_algebra::FormatFrMsb" => Ok(SerializationFormat::BLS12381FrMsb), - _ => Err(()), + + _ => Ok(SerializationFormat::BN254( + BN254SerializationFormat::try_from(value)?, + )), } } } @@ -209,6 +280,7 @@ fn feature_flag_from_structure(structure_opt: Option) -> Option Some(FeatureFlag::BLS12_381_STRUCTURES), + Some(Structure::BN254(_)) => Some(FeatureFlag::BN254_STRUCTURES), _ => None, } } @@ -259,6 +331,29 @@ static BLS12381_Q12_LENDIAN: Lazy> = Lazy::new(|| { hex::decode("1175f55da544c7625f8ccb1360e2b1d3ca40747811c8f5ed04440afe232b476c0215676aec05f2a44ac2da6b6d1b7cff075e7b2a587e0aab601a8d3db4f0d29906e5e4d0d78119f396d5a59f0f8d1ca8bca62540be6ab9c12d0ca00de1f311f106278d000e55a393c9766a74e0d08a298450f60d7e666575e3354bf14b8731f4e721c0c180a5ed55c2f8f51f815baecbf96b5fc717eb58ac161a27d1d5f2bdc1a079609b9d6449165b2466b32a01eac7992a1ea0cac2f223cde1d56f9bbccc67afe44621daf858df3fc0eb837818f3e42ab3e131ce4e492efa63c108e6ef91c29ed63b3045baebcb0ab8d203c7f558beaffccba31b12aca7f54b58d0c28340e4fdb3c7c94fe9c4fef9d640ff2fcff02f1748416cbed0981fbff49f0e39eaf8a30273e67ed851944d33d6a593ef5ddcd62da84568822a6045b633bf6a513b3cfe8f9de13e76f8dcbd915980dec205eab6a5c0c72dcebd9afff1d25509ddbf33f8e24131fbd74cda93336514340cf8036b66b09ed9e6a6ac37e22fb3ac407e321beae8cd9fe74c8aaeb4edaa9a7272848fc623f6fe835a2e647379f547fc5ec6371318a85bfa60009cb20ccbb8a467492988a87633c14c0324ba0d0c3e1798ed29c8494cea35023746da05e35d184b4a301d5b2238d665495c6318b5af8653758008952d06cb9e62487b196d64383c73c06d6e1cccdf9b3ce8f95679e7050d949004a55f4ccf95b2552880ae36d1f7e09504d2338316d87d14a064511a295d768113e301bdf9d4383a8be32192d3f2f3b2de14181c73839a7cb4af5301").unwrap() }); +/// Gt = e(G1, G2) +static BN254_GT_GENERATOR: Lazy = Lazy::new(|| { + ark_bn254::Bn254::pairing( + ark_bn254::G1Affine::generator(), + ark_bn254::G2Affine::generator(), + ) + .0 +}); +static BN254_R_LENDIAN: Lazy> = Lazy::new(|| BN254_R_SCALAR.to_bytes_le()); +const BN254_R_SCALAR: ark_ff::BigInteger256 = ark_bn254::Fr::MODULUS; +static BN254_Q_LENDIAN: Lazy> = Lazy::new(|| BN254_Q_SCALAR.to_bytes_le()); +const BN254_Q_SCALAR: ark_ff::BigInteger256 = ark_bn254::Fq::MODULUS; + +/// generated by: ark_bn254::Fq::MODULUS.pow(2) +static BN254_Q2_LENDIAN: Lazy> = Lazy::new(|| { + hex::decode("b1695d27a258543b01c1ea092d0702a6dcca966d9c18504ac842127a959e68048db3c6345cfaed260656371651850bb01cd248037c6f9a599cbf3c76b8c42509").unwrap() +}); + +/// generated by: ark_bn254::Fq::MODULUS.pow(12) +static BN254_Q12_LENDIAN: Lazy> = Lazy::new(|| { + hex::decode("21f186cad2e2d4c1dbaf8a066b0ebf41f734e3f859b1c523a6c1f4d457413fdbe3cd44add090135d3ae519acc30ee3bdb6bfac6573b767e975b18a77d53cdcddebf3672c74da9d1409d51b2b2db7ff000d59e3aa7cf09220159f925c86b65459ca6558c4eaa703bf45d85030ff85cc6a879c7e2c4034f7045faf20e4d3dcfffac5eb6634c3e7b939b69b2be70bdf6b9a4680297839b4e3a48cd746bd4d0ea82749ffb7e71bd9b3fb10aa684d71e6adab1250b1d8604d91b51c76c256a50b60ddba2f52b6cc853ac926c6ea86d09d400b2f2330e5c8e92e38905ba50a50c9e11cd979c284bf1327ccdc051a6da1a4a7eac5cec16757a27a1a2311bedd108a9b21ac0814269e7523a5dd3a1f5f4767ffe504a6cb3994fb0ec98d5cd5da00b9cb1188a85f2aa871ecb8a0f9d64141f1ccd2699c138e0ef9ac4d8d6a692b29db0f38b60eb08426ab46109fbab9a5221bb44dd338aafebcc4e6c10dd933597f3ff44ba41d04e82871447f3a759cfa9397c22c0c77f13618dfb65adc8aacf008").unwrap() +}); + pub fn make_all( builder: &SafeNativeBuilder, ) -> impl Iterator + '_ { diff --git a/aptos-move/framework/src/natives/cryptography/algebra/new.rs b/aptos-move/framework/src/natives/cryptography/algebra/new.rs index 7584cf14eaebb..5e332aaa2073a 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/new.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/new.rs @@ -3,8 +3,8 @@ use crate::{ abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled, natives::cryptography::algebra::{ - feature_flag_from_structure, AlgebraContext, Structure, E_TOO_MUCH_MEMORY_USED, - MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, + feature_flag_from_structure, AlgebraContext, BN254Structure, Structure, + E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, store_element, structure_from_ty_arg, }; @@ -47,6 +47,37 @@ pub fn from_u64_internal( ark_bls12_381::Fq12, ALGEBRA_ARK_BLS12_381_FQ12_FROM_U64 ), + Some(Structure::BN254(s)) => from_u64_internal_bn254(context, args, s), + _ => Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, + }), + } +} + +fn from_u64_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr => { + from_u64_internal!(context, args, ark_bn254::Fr, ALGEBRA_ARK_BN254_FR_FROM_U64) + }, + BN254Structure::BN254Fq => { + from_u64_internal!(context, args, ark_bn254::Fq, ALGEBRA_ARK_BN254_FQ_FROM_U64) + }, + BN254Structure::BN254Fq2 => from_u64_internal!( + context, + args, + ark_bn254::Fq2, + ALGEBRA_ARK_BN254_FQ2_FROM_U64 + ), + BN254Structure::BN254Fq12 => from_u64_internal!( + context, + args, + ark_bn254::Fq12, + ALGEBRA_ARK_BN254_FQ12_FROM_U64 + ), _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), diff --git a/aptos-move/framework/src/natives/cryptography/algebra/pairing.rs b/aptos-move/framework/src/natives/cryptography/algebra/pairing.rs index 5af6f56addf38..278975fa93b24 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/pairing.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/pairing.rs @@ -3,9 +3,9 @@ use crate::{ abort_unless_feature_flag_enabled, natives::cryptography::algebra::{ - abort_invariant_violated, AlgebraContext, Structure, E_TOO_MUCH_MEMORY_USED, - MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_INPUT_VECTOR_SIZES_NOT_MATCHING, - MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, AlgebraContext, BN254Structure, Structure, + E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, + MOVE_ABORT_CODE_INPUT_VECTOR_SIZES_NOT_MATCHING, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, safe_borrow_element, store_element, structure_from_ty_arg, }; @@ -30,6 +30,11 @@ fn feature_flag_of_pairing( (Some(Structure::BLS12381G1), Some(Structure::BLS12381G2), Some(Structure::BLS12381Gt)) => { Some(FeatureFlag::BLS12_381_STRUCTURES) }, + ( + Some(Structure::BN254(BN254Structure::BN254G1)), + Some(Structure::BN254(BN254Structure::BN254G2)), + Some(Structure::BN254(BN254Structure::BN254Gt)), + ) => Some(FeatureFlag::BN254_STRUCTURES), _ => None, } } @@ -104,6 +109,74 @@ pub fn multi_pairing_internal( let new_handle = store_element!(context, new_element)?; Ok(smallvec![Value::u64(new_handle as u64)]) }, + (Some(Structure::BN254(g1)), Some(Structure::BN254(g2)), Some(Structure::BN254(gt))) => { + multi_pairing_internal_bn254(context, args, g1, g2, gt) + }, + _ => Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, + }), + } +} + +fn multi_pairing_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + g1: BN254Structure, + g2: BN254Structure, + gt: BN254Structure, +) -> SafeNativeResult> { + match (g1, g2, gt) { + (BN254Structure::BN254G1, BN254Structure::BN254G2, BN254Structure::BN254Gt) => { + let g2_element_handles = safely_pop_arg!(args, Vec); + let g1_element_handles = safely_pop_arg!(args, Vec); + let num_entries = g1_element_handles.len(); + if num_entries != g2_element_handles.len() { + return Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_INPUT_VECTOR_SIZES_NOT_MATCHING, + }); + } + + context.charge( + ALGEBRA_ARK_BN254_G1_PROJ_TO_AFFINE.per::() + * NumArgs::from(num_entries as u64), + )?; + let mut g1_elements_affine = Vec::with_capacity(num_entries); + for handle in g1_element_handles { + safe_borrow_element!( + context, + handle as usize, + ark_bn254::G1Projective, + ptr, + element + ); + g1_elements_affine.push(element.into_affine()); + } + + context.charge( + ALGEBRA_ARK_BN254_G2_PROJ_TO_AFFINE.per::() + * NumArgs::from(num_entries as u64), + )?; + let mut g2_elements_affine = Vec::with_capacity(num_entries); + for handle in g2_element_handles { + safe_borrow_element!( + context, + handle as usize, + ark_bn254::G2Projective, + ptr, + element + ); + g2_elements_affine.push(element.into_affine()); + } + + context.charge( + ALGEBRA_ARK_BN254_MULTI_PAIRING_BASE + + ALGEBRA_ARK_BN254_MULTI_PAIRING_PER_PAIR * NumArgs::from(num_entries as u64), + )?; + let new_element = + ark_bn254::Bn254::multi_pairing(g1_elements_affine, g2_elements_affine).0; + let new_handle = store_element!(context, new_element)?; + Ok(smallvec![Value::u64(new_handle as u64)]) + }, _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), @@ -148,6 +221,50 @@ pub fn pairing_internal( let new_handle = store_element!(context, new_element)?; Ok(smallvec![Value::u64(new_handle as u64)]) }, + (Some(Structure::BN254(g1)), Some(Structure::BN254(g2)), Some(Structure::BN254(gt))) => { + pairing_internal_bn254(context, args, g1, g2, gt) + }, + + _ => Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, + }), + } +} + +fn pairing_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + g1: BN254Structure, + g2: BN254Structure, + gt: BN254Structure, +) -> SafeNativeResult> { + match (g1, g2, gt) { + (BN254Structure::BN254G1, BN254Structure::BN254G2, BN254Structure::BN254Gt) => { + let g2_element_handle = safely_pop_arg!(args, u64) as usize; + let g1_element_handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!( + context, + g1_element_handle, + ark_bn254::G1Projective, + g1_element_ptr, + g1_element + ); + context.charge(ALGEBRA_ARK_BN254_G1_PROJ_TO_AFFINE)?; + let g1_element_affine = g1_element.into_affine(); + safe_borrow_element!( + context, + g2_element_handle, + ark_bn254::G2Projective, + g2_element_ptr, + g2_element + ); + context.charge(ALGEBRA_ARK_BN254_G2_PROJ_TO_AFFINE)?; + let g2_element_affine = g2_element.into_affine(); + context.charge(ALGEBRA_ARK_BN254_PAIRING)?; + let new_element = ark_bn254::Bn254::pairing(g1_element_affine, g2_element_affine).0; + let new_handle = store_element!(context, new_element)?; + Ok(smallvec![Value::u64(new_handle as u64)]) + }, _ => Err(SafeNativeError::Abort { abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, }), diff --git a/aptos-move/framework/src/natives/cryptography/algebra/rand.rs b/aptos-move/framework/src/natives/cryptography/algebra/rand.rs index 52489a4a4123a..682d3ff2c17c1 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/rand.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/rand.rs @@ -3,8 +3,8 @@ #[cfg(feature = "testing")] use crate::{ natives::cryptography::algebra::{ - AlgebraContext, Structure, BLS12381_GT_GENERATOR, E_TOO_MUCH_MEMORY_USED, - MEMORY_LIMIT_IN_BYTES, + AlgebraContext, BN254Structure, Structure, BLS12381_GT_GENERATOR, BN254_GT_GENERATOR, + E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, }, structure_from_ty_arg, }; @@ -77,6 +77,43 @@ pub fn rand_insecure_internal( Err(abort_code) => Err(SafeNativeError::Abort { abort_code }), } }, + Some(Structure::BN254(s)) => rand_insecure_internal_bn254(context, s), _ => unreachable!(), } } +#[cfg(feature = "testing")] +#[inline] +fn rand_insecure_internal_bn254( + context: &mut SafeNativeContext, + structure: BN254Structure, +) -> SafeNativeResult> { + match structure { + BN254Structure::BN254Fr => { + ark_rand_internal!(context, ark_bn254::Fr) + }, + BN254Structure::BN254Fq => { + ark_rand_internal!(context, ark_bn254::Fq) + }, + BN254Structure::BN254Fq2 => { + ark_rand_internal!(context, ark_bn254::Fq2) + }, + BN254Structure::BN254Fq12 => { + ark_rand_internal!(context, ark_bn254::Fq12) + }, + BN254Structure::BN254G1 => { + ark_rand_internal!(context, ark_bn254::G1Projective) + }, + BN254Structure::BN254G2 => { + ark_rand_internal!(context, ark_bn254::G2Projective) + }, + BN254Structure::BN254Gt => { + let k = ark_bn254::Fr::rand(&mut test_rng()); + let k_bigint: ark_ff::BigInteger256 = k.into(); + let element = BN254_GT_GENERATOR.pow(k_bigint); + match store_element!(context, element) { + Ok(handle) => Ok(smallvec![Value::u64(handle as u64)]), + Err(abort_code) => Err(SafeNativeError::Abort { abort_code }), + } + }, + } +} diff --git a/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs b/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs index aff3819078bb8..6e3f1ac36b46c 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs @@ -3,9 +3,9 @@ use crate::{ abort_unless_feature_flag_enabled, natives::cryptography::algebra::{ - abort_invariant_violated, AlgebraContext, SerializationFormat, Structure, - BLS12381_R_SCALAR, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, - MOVE_ABORT_CODE_NOT_IMPLEMENTED, + abort_invariant_violated, AlgebraContext, BN254SerializationFormat, BN254Structure, + SerializationFormat, Structure, BLS12381_R_SCALAR, BN254_R_SCALAR, E_TOO_MUCH_MEMORY_USED, + MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED, }, safe_borrow_element, store_element, structure_from_ty_arg, }; @@ -37,6 +37,7 @@ pub fn feature_flag_of_serialization_format( | Some(SerializationFormat::BLS12381G2Uncompressed) | Some(SerializationFormat::BLS12381G2Compressed) | Some(SerializationFormat::BLS12381Gt) => Some(FeatureFlag::BLS12_381_STRUCTURES), + Some(SerializationFormat::BN254(_)) => Some(FeatureFlag::BN254_STRUCTURES), _ => None, } } @@ -65,6 +66,10 @@ pub fn serialize_internal( let format_opt = format_from_ty_arg!(context, &ty_args[1]); abort_unless_serialization_format_enabled!(context, format_opt); match (structure_opt, format_opt) { + ( + Some(Structure::BN254(bn254_structure)), + Some(SerializationFormat::BN254(bn254_format)), + ) => serialize_internal_bn254(context, args, bn254_structure, bn254_format), (Some(Structure::BLS12381Fr), Some(SerializationFormat::BLS12381FrLsb)) => { let handle = safely_pop_arg!(args, u64) as usize; safe_borrow_element!(context, handle, ark_bls12_381::Fr, element_ptr, element); @@ -180,6 +185,161 @@ pub fn serialize_internal( } } +fn serialize_internal_bn254( + context: &mut SafeNativeContext, + mut args: VecDeque, + structure: BN254Structure, + format: BN254SerializationFormat, +) -> SafeNativeResult> { + match (structure, format) { + (BN254Structure::BN254Fr, BN254SerializationFormat::BN254FrLsb) => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!(context, handle, ark_bn254::Fr, element_ptr, element); + let mut buf = vec![]; + context.charge(ALGEBRA_ARK_BN254_FR_SERIALIZE)?; + element + .serialize_uncompressed(&mut buf) + .map_err(|_e| abort_invariant_violated())?; + Ok(smallvec![Value::vector_u8(buf)]) + }, + (BN254Structure::BN254Fr, BN254SerializationFormat::BN254FrMsb) => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!(context, handle, ark_bn254::Fr, element_ptr, element); + let mut buf = vec![]; + context.charge(ALGEBRA_ARK_BN254_FR_SERIALIZE)?; + element + .serialize_uncompressed(&mut buf) + .map_err(|_e| abort_invariant_violated())?; + buf.reverse(); + Ok(smallvec![Value::vector_u8(buf)]) + }, + (BN254Structure::BN254Fq, BN254SerializationFormat::BN254FrLsb) => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!(context, handle, ark_bn254::Fq, element_ptr, element); + let mut buf = vec![]; + context.charge(ALGEBRA_ARK_BN254_FQ_SERIALIZE)?; + element + .serialize_uncompressed(&mut buf) + .map_err(|_e| abort_invariant_violated())?; + Ok(smallvec![Value::vector_u8(buf)]) + }, + (BN254Structure::BN254Fq, BN254SerializationFormat::BN254FqMsb) => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!(context, handle, ark_bn254::Fq, element_ptr, element); + let mut buf = vec![]; + context.charge(ALGEBRA_ARK_BN254_FQ_SERIALIZE)?; + element + .serialize_uncompressed(&mut buf) + .map_err(|_e| abort_invariant_violated())?; + buf.reverse(); + Ok(smallvec![Value::vector_u8(buf)]) + }, + (BN254Structure::BN254Fq2, BN254SerializationFormat::BN254Fq2LscLsb) => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!(context, handle, ark_bn254::Fq2, element_ptr, element); + let mut buf = vec![]; + context.charge(ALGEBRA_ARK_BN254_FQ2_SERIALIZE)?; + element + .serialize_uncompressed(&mut buf) + .map_err(|_e| abort_invariant_violated())?; + buf.reverse(); + Ok(smallvec![Value::vector_u8(buf)]) + }, + (BN254Structure::BN254Fq12, BN254SerializationFormat::BN254Fq12LscLsb) => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!(context, handle, ark_bn254::Fq12, element_ptr, element); + let mut buf = vec![]; + context.charge(ALGEBRA_ARK_BN254_FQ12_SERIALIZE)?; + element + .serialize_uncompressed(&mut buf) + .map_err(|_e| abort_invariant_violated())?; + buf.reverse(); + Ok(smallvec![Value::vector_u8(buf)]) + }, + (BN254Structure::BN254G1, BN254SerializationFormat::BN254G1Uncompressed) => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!( + context, + handle, + ark_bn254::G1Projective, + element_ptr, + element + ); + let element_affine = element.into_affine(); + let mut buf = Vec::new(); + context.charge(ALGEBRA_ARK_BN254_G1_AFFINE_SERIALIZE_UNCOMP)?; + element_affine + .serialize_uncompressed(&mut buf) + .map_err(|_e| abort_invariant_violated())?; + Ok(smallvec![Value::vector_u8(buf)]) + }, + (BN254Structure::BN254G1, BN254SerializationFormat::BN254G1Compressed) => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!( + context, + handle, + ark_bn254::G1Projective, + element_ptr, + element + ); + let element_affine = element.into_affine(); + let mut buf = Vec::new(); + context.charge(ALGEBRA_ARK_BN254_G1_AFFINE_SERIALIZE_COMP)?; + element_affine + .serialize_compressed(&mut buf) + .map_err(|_e| abort_invariant_violated())?; + Ok(smallvec![Value::vector_u8(buf)]) + }, + (BN254Structure::BN254G2, BN254SerializationFormat::BN254G2Uncompressed) => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!( + context, + handle, + ark_bn254::G2Projective, + element_ptr, + element + ); + let element_affine = element.into_affine(); + let mut buf = Vec::new(); + context.charge(ALGEBRA_ARK_BN254_G2_AFFINE_SERIALIZE_UNCOMP)?; + element_affine + .serialize_uncompressed(&mut buf) + .map_err(|_e| abort_invariant_violated())?; + Ok(smallvec![Value::vector_u8(buf)]) + }, + (BN254Structure::BN254G2, BN254SerializationFormat::BN254G2Compressed) => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!( + context, + handle, + ark_bn254::G2Projective, + element_ptr, + element + ); + let element_affine = element.into_affine(); + let mut buf = Vec::new(); + context.charge(ALGEBRA_ARK_BN254_G2_AFFINE_SERIALIZE_COMP)?; + element_affine + .serialize_compressed(&mut buf) + .map_err(|_e| abort_invariant_violated())?; + Ok(smallvec![Value::vector_u8(buf)]) + }, + (BN254Structure::BN254Gt, BN254SerializationFormat::BN254Gt) => { + let handle = safely_pop_arg!(args, u64) as usize; + safe_borrow_element!(context, handle, ark_bn254::Fq12, element_ptr, element); + let mut buf = vec![]; + context.charge(ALGEBRA_ARK_BN254_FQ12_SERIALIZE)?; + element + .serialize_uncompressed(&mut buf) + .map_err(|_e| abort_invariant_violated())?; + Ok(smallvec![Value::vector_u8(buf)]) + }, + _ => Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, + }), + } +} + /// Macros that implements `deserialize_internal()` using arkworks libraries. macro_rules! ark_deserialize_internal { ($context:expr, $bytes:expr, $ark_typ:ty, $ark_deser_func:ident, $gas:expr) => {{ @@ -233,6 +393,10 @@ pub fn deserialize_internal( let bytes_ref = vector_ref.as_bytes_ref(); let bytes = bytes_ref.as_slice(); match (structure_opt, format_opt) { + ( + Some(Structure::BN254(bn254_structure)), + Some(SerializationFormat::BN254(bn254_format)), + ) => deserialize_internal_bn254(context, bn254_structure, bn254_format, bytes), (Some(Structure::BLS12381Fr), Some(SerializationFormat::BLS12381FrLsb)) => { // Valid BLS12381FrLsb serialization should be 32-byte. // NOTE: Arkworks deserialization cost grows as the input size grows. @@ -355,3 +519,167 @@ pub fn deserialize_internal( }), } } + +pub fn deserialize_internal_bn254( + context: &mut SafeNativeContext, + structure: BN254Structure, + format: BN254SerializationFormat, + bytes: &[u8], +) -> SafeNativeResult> { + match (structure, format) { + (BN254Structure::BN254Fr, BN254SerializationFormat::BN254FrLsb) => { + if bytes.len() != 32 { + return Ok(smallvec![Value::bool(false), Value::u64(0)]); + } + ark_deserialize_internal!( + context, + bytes, + ark_bn254::Fr, + deserialize_uncompressed, + ALGEBRA_ARK_BN254_FR_DESER + ) + }, + (BN254Structure::BN254Fr, BN254SerializationFormat::BN254FrMsb) => { + if bytes.len() != 32 { + return Ok(smallvec![Value::bool(false), Value::u64(0)]); + } + let mut bytes_copy: Vec = bytes.to_vec(); + bytes_copy.reverse(); + let bytes = bytes_copy.as_slice(); + ark_deserialize_internal!( + context, + bytes, + ark_bn254::Fr, + deserialize_uncompressed, + ALGEBRA_ARK_BN254_FR_DESER + ) + }, + (BN254Structure::BN254Fq, BN254SerializationFormat::BN254FqLsb) => { + if bytes.len() != 32 { + return Ok(smallvec![Value::bool(false), Value::u64(0)]); + } + ark_deserialize_internal!( + context, + bytes, + ark_bn254::Fq, + deserialize_uncompressed, + ALGEBRA_ARK_BN254_FQ_DESER + ) + }, + (BN254Structure::BN254Fq, BN254SerializationFormat::BN254FqMsb) => { + if bytes.len() != 32 { + return Ok(smallvec![Value::bool(false), Value::u64(0)]); + } + let mut bytes_copy: Vec = bytes.to_vec(); + bytes_copy.reverse(); + let bytes = bytes_copy.as_slice(); + ark_deserialize_internal!( + context, + bytes, + ark_bn254::Fq, + deserialize_uncompressed, + ALGEBRA_ARK_BN254_FQ_DESER + ) + }, + (BN254Structure::BN254Fq2, BN254SerializationFormat::BN254Fq2LscLsb) => { + // Valid BN254Fq2LscLsb serialization should be 32*2 = 64-byte. + if bytes.len() != 64 { + return Ok(smallvec![Value::bool(false), Value::u64(0)]); + } + ark_deserialize_internal!( + context, + bytes, + ark_bn254::Fq2, + deserialize_uncompressed, + ALGEBRA_ARK_BN254_FQ2_DESER + ) + }, + (BN254Structure::BN254Fq12, BN254SerializationFormat::BN254Fq12LscLsb) => { + // Valid BN254Fq12LscLsb serialization should be 32*12 = 64-byte. + if bytes.len() != 384 { + return Ok(smallvec![Value::bool(false), Value::u64(0)]); + } + ark_deserialize_internal!( + context, + bytes, + ark_bn254::Fq12, + deserialize_uncompressed, + ALGEBRA_ARK_BN254_FQ12_DESER + ) + }, + (BN254Structure::BN254G1, BN254SerializationFormat::BN254G1Uncompressed) => { + // Valid BN254G1AffineUncompressed serialization should be 64-byte. + if bytes.len() != 64 { + return Ok(smallvec![Value::bool(false), Value::u64(0)]); + } + ark_ec_point_deserialize_internal!( + context, + bytes, + ark_bn254::G1Affine, + deserialize_uncompressed, + ALGEBRA_ARK_BN254_G1_AFFINE_DESER_UNCOMP + ) + }, + (BN254Structure::BN254G1, BN254SerializationFormat::BN254G1Compressed) => { + // Valid BN254G1AffineCompressed serialization should be 32-byte. + if bytes.len() != 32 { + return Ok(smallvec![Value::bool(false), Value::u64(0)]); + } + ark_ec_point_deserialize_internal!( + context, + bytes, + ark_bn254::G1Affine, + deserialize_compressed, + ALGEBRA_ARK_BN254_G1_AFFINE_DESER_COMP + ) + }, + (BN254Structure::BN254G2, BN254SerializationFormat::BN254G2Uncompressed) => { + // Valid BN254G2AffineUncompressed serialization should be 128-byte. + if bytes.len() != 128 { + return Ok(smallvec![Value::bool(false), Value::u64(0)]); + } + ark_ec_point_deserialize_internal!( + context, + bytes, + ark_bn254::G2Affine, + deserialize_uncompressed, + ALGEBRA_ARK_BN254_G2_AFFINE_DESER_UNCOMP + ) + }, + (BN254Structure::BN254G2, BN254SerializationFormat::BN254G2Compressed) => { + // Valid BN254G2AffineCompressed serialization should be 64-byte. + if bytes.len() != 64 { + return Ok(smallvec![Value::bool(false), Value::u64(0)]); + } + ark_ec_point_deserialize_internal!( + context, + bytes, + ark_bn254::G2Affine, + deserialize_compressed, + ALGEBRA_ARK_BN254_G2_AFFINE_DESER_COMP + ) + }, + (BN254Structure::BN254Gt, BN254SerializationFormat::BN254Gt) => { + // Valid BN254Gt serialization should be 32*12=384-byte. + if bytes.len() != 384 { + return Ok(smallvec![Value::bool(false), Value::u64(0)]); + } + context.charge(ALGEBRA_ARK_BN254_FQ12_DESER)?; + match ::deserialize_uncompressed(bytes) { + Ok(element) => { + context.charge(ALGEBRA_ARK_BN254_FQ12_POW_U256 + ALGEBRA_ARK_BN254_FQ12_EQ)?; + if element.pow(BN254_R_SCALAR.0) == ark_bn254::Fq12::one() { + let handle = store_element!(context, element)?; + Ok(smallvec![Value::bool(true), Value::u64(handle as u64)]) + } else { + Ok(smallvec![Value::bool(false), Value::u64(0)]) + } + }, + _ => Ok(smallvec![Value::bool(false), Value::u64(0)]), + } + }, + _ => Err(SafeNativeError::Abort { + abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED, + }), + } +} diff --git a/aptos-move/vm-genesis/src/lib.rs b/aptos-move/vm-genesis/src/lib.rs index c5a5309c84755..457bd2c9e6e11 100644 --- a/aptos-move/vm-genesis/src/lib.rs +++ b/aptos-move/vm-genesis/src/lib.rs @@ -436,6 +436,7 @@ pub fn default_features() -> Vec { FeatureFlag::FEE_PAYER_ACCOUNT_OPTIONAL, FeatureFlag::LIMIT_MAX_IDENTIFIER_LENGTH, FeatureFlag::OPERATOR_BENEFICIARY_CHANGE, + FeatureFlag::BN254_STRUCTURES, ] } diff --git a/types/src/on_chain_config/aptos_features.rs b/types/src/on_chain_config/aptos_features.rs index d7ca037407609..90bb8710f9f09 100644 --- a/types/src/on_chain_config/aptos_features.rs +++ b/types/src/on_chain_config/aptos_features.rs @@ -50,6 +50,7 @@ pub enum FeatureFlag { VM_BINARY_FORMAT_V7 = 40, RESOURCE_GROUPS_CHARGE_AS_SIZE_SUM = 41, COMMISSION_CHANGE_DELEGATION_POOL = 42, + BN254_STRUCTURES = 43, } /// Representation of features on chain as a bitset. From 71c74ab45b485717d6a1922c282681fb9f13b6bc Mon Sep 17 00:00:00 2001 From: caojiafeng Date: Thu, 30 Nov 2023 15:04:04 +0800 Subject: [PATCH 02/21] scripts: fix update_algebra_gas_params.py Signed-off-by: caojiafeng --- scripts/algebra-gas/update_algebra_gas_params.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/algebra-gas/update_algebra_gas_params.py b/scripts/algebra-gas/update_algebra_gas_params.py index 2eb69aa21cfb4..06f3855cfaa03 100755 --- a/scripts/algebra-gas/update_algebra_gas_params.py +++ b/scripts/algebra-gas/update_algebra_gas_params.py @@ -96,17 +96,19 @@ def get_algebra_lines(gas_per_ns): return lines def main(gas_per_ns): - path = Path('aptos-move/aptos-gas/src/aptos_framework.rs') + path = Path(PATH_STR) lines = path.read_text().split('\n') - line_id_begin = lines.index(' // Algebra gas parameters begin.') - line_id_end = lines.index(' // Algebra gas parameters end.') + striped_lines = [line.strip() for line in lines] + line_id_begin = striped_lines.index('// Algebra gas parameters begin.') + line_id_end = striped_lines.index('// Algebra gas parameters end.') generator_note_line = f' // Generated at time {time()} by `scripts/algebra-gas/update_algebra_gas_params.py` with gas_per_ns={gas_per_ns}.' new_lines = lines[:line_id_begin+1] + [generator_note_line] + get_algebra_lines(gas_per_ns) + lines[line_id_end:] path.write_text('\n'.join(new_lines)) +PATH_STR = 'aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs' if __name__=='__main__': parser = argparse.ArgumentParser( - description='Generate gas parameters for algebra module in `aptos-move/aptos-gas/src/aptos_framework.rs`.') + description=f'Generate gas parameters for algebra module in `{PATH_STR}`.') parser.add_argument('--gas_per_ns', required=True, type=float) args = parser.parse_args() main(args.gas_per_ns) From eeedf1144cadada479530d9115358fc02992e4d6 Mon Sep 17 00:00:00 2001 From: caojiafeng Date: Thu, 30 Nov 2023 18:33:28 +0800 Subject: [PATCH 03/21] add bn254 to default features to make unit test pass --- types/src/on_chain_config/aptos_features.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/src/on_chain_config/aptos_features.rs b/types/src/on_chain_config/aptos_features.rs index 90bb8710f9f09..f0913fcecf5c3 100644 --- a/types/src/on_chain_config/aptos_features.rs +++ b/types/src/on_chain_config/aptos_features.rs @@ -74,7 +74,7 @@ impl Default for Features { features.enable(APTOS_UNIQUE_IDENTIFIERS); features.enable(SIGNATURE_CHECKER_V2_SCRIPT_FIX); features.enable(AGGREGATOR_V2_API); - + features.enable(BN254_STRUCTURES); features } } From 1570e312833c28806575d956f6f1803a5cd3898a Mon Sep 17 00:00:00 2001 From: caojiafeng Date: Fri, 1 Dec 2023 09:41:05 +0800 Subject: [PATCH 04/21] fix a bug mentioned in the comments --- .../framework/src/natives/cryptography/algebra/serialization.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs b/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs index 6e3f1ac36b46c..c31c44fb664d9 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs @@ -242,7 +242,6 @@ fn serialize_internal_bn254( element .serialize_uncompressed(&mut buf) .map_err(|_e| abort_invariant_violated())?; - buf.reverse(); Ok(smallvec![Value::vector_u8(buf)]) }, (BN254Structure::BN254Fq12, BN254SerializationFormat::BN254Fq12LscLsb) => { @@ -253,7 +252,6 @@ fn serialize_internal_bn254( element .serialize_uncompressed(&mut buf) .map_err(|_e| abort_invariant_violated())?; - buf.reverse(); Ok(smallvec![Value::vector_u8(buf)]) }, (BN254Structure::BN254G1, BN254SerializationFormat::BN254G1Uncompressed) => { From 0e637ae7807b3ca5549377924c764c12901a5d70 Mon Sep 17 00:00:00 2001 From: caojiafeng Date: Sat, 2 Dec 2023 12:18:17 +0800 Subject: [PATCH 05/21] add test for bn254 --- .../sources/cryptography/bn254_algebra.move | 566 ++++++++++++++++++ 1 file changed, 566 insertions(+) diff --git a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move index 3a28c9c271858..ff72d51ee9224 100644 --- a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move +++ b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move @@ -22,4 +22,570 @@ module std::bn254_algebra { struct Gt {} struct FormatGt {} + + + #[test_only] + const FQ12_VAL_0_SERIALIZED: vector = x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const FQ12_VAL_1_SERIALIZED: vector = x"010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const FQ12_VAL_7_SERIALIZED: vector = x"070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const FQ12_VAL_7_NEG_SERIALIZED: vector = x"a4aafffffffffeb9ffff53b1feffab1e24f6b0f6a0d23067bf1285f3844b7764d7ac4b43b6a71b4b9ae67f39ea11011a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const Q12_SERIALIZED: vector = x"21f186cad2e2d4c1dbaf8a066b0ebf41f734e3f859b1c523a6c1f4d457413fdbe3cd44add090135d3ae519acc30ee3bdb6bfac6573b767e975b18a77d53cdcddebf3672c74da9d1409d51b2b2db7ff000d59e3aa7cf09220159f925c86b65459ca6558c4eaa703bf45d85030ff85cc6a879c7e2c4034f7045faf20e4d3dcfffac5eb6634c3e7b939b69b2be70bdf6b9a4680297839b4e3a48cd746bd4d0ea82749ffb7e71bd9b3fb10aa684d71e6adab1250b1d8604d91b51c76c256a50b60ddba2f52b6cc853ac926c6ea86d09d400b2f2330e5c8e92e38905ba50a50c9e11cd979c284bf1327ccdc051a6da1a4a7eac5cec16757a27a1a2311bedd108a9b21ac0814269e7523a5dd3a1f5f4767ffe504a6cb3994fb0ec98d5cd5da00b9cb1188a85f2aa871ecb8a0f9d64141f1ccd2699c138e0ef9ac4d8d6a692b29db0f38b60eb08426ab46109fbab9a5221bb44dd338aafebcc4e6c10dd933597f3ff44ba41d04e82871447f3a759cfa9397c22c0c77f13618dfb65adc8aacf008"; + + #[test_only] + fun rand_vector(num: u64): vector> { + let elements = vector[]; + while (num > 0) { + std::vector::push_back(&mut elements, rand_insecure()); + num = num - 1; + }; + elements + } + + #[test(fx = @std)] + fun test_fq12(fx: signer) { + enable_cryptography_algebra_natives(&fx); + + // Constants. + assert!(Q12_SERIALIZED == order(), 1); + + // Serialization/deserialization. + let val_0 = zero(); + let val_1 = one(); + assert!(FQ12_VAL_0_SERIALIZED == serialize(&val_0), 1); + assert!(FQ12_VAL_1_SERIALIZED == serialize(&val_1), 1); + let val_7 = from_u64(7); + let val_7_another = std::option::extract(&mut deserialize(&FQ12_VAL_7_SERIALIZED)); + assert!(eq(&val_7, &val_7_another), 1); + assert!(FQ12_VAL_7_SERIALIZED == serialize(&val_7), 1); + assert!(std::option::is_none(&deserialize(&x"ffff")), 1); + + // Negation. + let val_minus_7 = neg(&val_7); + assert!(FQ12_VAL_7_NEG_SERIALIZED == serialize(&val_minus_7), 1); + + // Addition. + let val_9 = from_u64(9); + let val_2 = from_u64(2); + assert!(eq(&val_2, &add(&val_minus_7, &val_9)), 1); + + // Subtraction. + assert!(eq(&val_9, &sub(&val_2, &val_minus_7)), 1); + + // Multiplication. + let val_63 = from_u64(63); + assert!(eq(&val_63, &mul(&val_7, &val_9)), 1); + + // division. + let val_0 = from_u64(0); + assert!(eq(&val_7, &std::option::extract(&mut div(&val_63, &val_9))), 1); + assert!(std::option::is_none(&div(&val_63, &val_0)), 1); + + // Inversion. + assert!(eq(&val_minus_7, &neg(&val_7)), 1); + assert!(std::option::is_none(&inv(&val_0)), 1); + + // Squaring. + let val_x = rand_insecure(); + assert!(eq(&mul(&val_x, &val_x), &sqr(&val_x)), 1); + + // Downcasting. + assert!(eq(&zero(), &std::option::extract(&mut downcast(&val_1))), 1); + } + + #[test_only] + const R_SERIALIZED: vector = x"01000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73"; + #[test_only] + const G1_INF_SERIALIZED_COMP: vector = x"c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const G1_INF_SERIALIZED_UNCOMP: vector = x"400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const G1_GENERATOR_SERIALIZED_COMP: vector = x"97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"; + #[test_only] + const G1_GENERATOR_SERIALIZED_UNCOMP: vector = x"17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1"; + #[test_only] + const G1_GENERATOR_MUL_BY_7_SERIALIZED_COMP: vector = x"b928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7"; + #[test_only] + const G1_GENERATOR_MUL_BY_7_SERIALIZED_UNCOMP: vector = x"1928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7108dadbaa4b636445639d5ae3089b3c43a8a1d47818edd1839d7383959a41c10fdc66849cfa1b08c5a11ec7e28981a1c"; + #[test_only] + const G1_GENERATOR_MUL_BY_7_NEG_SERIALIZED_COMP: vector = x"9928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7"; + #[test_only] + const G1_GENERATOR_MUL_BY_7_NEG_SERIALIZED_UNCOMP: vector = x"1928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb70973642f94c9b055f4e1d20812c1f91329ed2e3d71f635a72d599a679d0cda1320e597b4e1b24f735fed1381d767908f"; + + #[test(fx = @std)] + fun test_g1affine(fx: signer) { + enable_cryptography_algebra_natives(&fx); + + // Constants. + assert!(R_SERIALIZED == order(), 1); + let point_at_infinity = zero(); + let generator = one(); + + // Serialization/deserialization. + assert!(G1_GENERATOR_SERIALIZED_UNCOMP == serialize(&generator), 1); + assert!(G1_GENERATOR_SERIALIZED_COMP == serialize(&generator), 1); + let generator_from_comp = std::option::extract(&mut deserialize(&G1_GENERATOR_SERIALIZED_COMP + )); + let generator_from_uncomp = std::option::extract(&mut deserialize(&G1_GENERATOR_SERIALIZED_UNCOMP + )); + assert!(eq(&generator, &generator_from_comp), 1); + assert!(eq(&generator, &generator_from_uncomp), 1); + + // Deserialization should fail if given a byte array of correct size but the value is not a member. + assert!(std::option::is_none(&deserialize(&x"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")), 1); + + // Deserialization should fail if given a byte array of wrong size. + assert!(std::option::is_none(&deserialize(&x"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")), 1); + + assert!( + G1_INF_SERIALIZED_UNCOMP == serialize(&point_at_infinity), 1); + assert!(G1_INF_SERIALIZED_COMP == serialize(&point_at_infinity), 1); + let inf_from_uncomp = std::option::extract(&mut deserialize(&G1_INF_SERIALIZED_UNCOMP + )); + let inf_from_comp = std::option::extract(&mut deserialize(&G1_INF_SERIALIZED_COMP + )); + assert!(eq(&point_at_infinity, &inf_from_comp), 1); + assert!(eq(&point_at_infinity, &inf_from_uncomp), 1); + + let point_7g_from_uncomp = std::option::extract(&mut deserialize(&G1_GENERATOR_MUL_BY_7_SERIALIZED_UNCOMP + )); + let point_7g_from_comp = std::option::extract(&mut deserialize(&G1_GENERATOR_MUL_BY_7_SERIALIZED_COMP + )); + assert!(eq(&point_7g_from_comp, &point_7g_from_uncomp), 1); + + // Deserialization should fail if given a point on the curve but off its prime-order subgroup, e.g., `(0,2)`. + assert!(std::option::is_none(&deserialize(&x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002")), 1); + assert!(std::option::is_none(&deserialize(&x"800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")), 1); + + // Deserialization should fail if given a valid point in (Fq,Fq) but not on the curve. + assert!(std::option::is_none(&deserialize(&x"8959e137e0719bf872abb08411010f437a8955bd42f5ba20fca64361af58ce188b1adb96ef229698bb7860b79e24ba12000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")), 1); + + // Deserialization should fail if given an invalid point (x not in Fq). + assert!(std::option::is_none(&deserialize(&x"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa76e9853b35f5c9b2002d9e5833fd8f9ab4cd3934a4722a06f6055bfca720c91629811e2ecae7f0cf301b6d07898a90f")), 1); + assert!(std::option::is_none(&deserialize(&x"9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")), 1); + + // Deserialization should fail if given a byte array of wrong size. + assert!(std::option::is_none(&deserialize(&x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab")), 1); + assert!(std::option::is_none(&deserialize(&x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab")), 1); + + // Scalar multiplication. + let scalar_7 = from_u64(7); + let point_7g_calc = scalar_mul(&generator, &scalar_7); + assert!(eq(&point_7g_calc, &point_7g_from_comp), 1); + assert!(G1_GENERATOR_MUL_BY_7_SERIALIZED_UNCOMP == serialize(&point_7g_calc), 1); + assert!(G1_GENERATOR_MUL_BY_7_SERIALIZED_COMP == serialize( &point_7g_calc), 1); + + // Multi-scalar multiplication. + let num_entries = 1; + while (num_entries < 10) { + let scalars = rand_vector(num_entries); + let elements = rand_vector(num_entries); + + let expected = zero(); + let i = 0; + while (i < num_entries) { + let element = std::vector::borrow(&elements, i); + let scalar = std::vector::borrow(&scalars, i); + expected = add(&expected, &scalar_mul(element, scalar)); + i = i + 1; + }; + + let actual = multi_scalar_mul(&elements, &scalars); + assert!(eq(&expected, &actual), 1); + + num_entries = num_entries + 1; + }; + + // Doubling. + let scalar_2 = from_u64(2); + let point_2g = scalar_mul(&generator, &scalar_2); + let point_double_g = double(&generator); + assert!(eq(&point_2g, &point_double_g), 1); + + // Negation. + let point_minus_7g_calc = neg(&point_7g_calc); + assert!(G1_GENERATOR_MUL_BY_7_NEG_SERIALIZED_COMP == serialize(&point_minus_7g_calc), 1); + assert!(G1_GENERATOR_MUL_BY_7_NEG_SERIALIZED_UNCOMP == serialize(&point_minus_7g_calc), 1); + + // Addition. + let scalar_9 = from_u64(9); + let point_9g = scalar_mul(&generator, &scalar_9); + let point_2g = scalar_mul(&generator, &scalar_2); + let point_2g_calc = add(&point_minus_7g_calc, &point_9g); + assert!(eq(&point_2g, &point_2g_calc), 1); + + // Subtraction. + assert!(eq(&point_9g, &sub(&point_2g, &point_minus_7g_calc)), 1); + + // Hash-to-group using suite `BLS12381G1_XMD:SHA-256_SSWU_RO_`. + // Test vectors source: https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-bls12381g1_xmdsha-256_sswu_ + let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_", &b""); + let expected = std::option::extract(&mut deserialize(&x"052926add2207b76ca4fa57a8734416c8dc95e24501772c814278700eed6d1e4e8cf62d9c09db0fac349612b759e79a108ba738453bfed09cb546dbb0783dbb3a5f1f566ed67bb6be0e8c67e2e81a4cc68ee29813bb7994998f3eae0c9c6a265")); + assert!(eq(&expected, &actual), 1); + let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_", &b"abcdef0123456789"); + let expected = std::option::extract(&mut deserialize(&x"11e0b079dea29a68f0383ee94fed1b940995272407e3bb916bbf268c263ddd57a6a27200a784cbc248e84f357ce82d9803a87ae2caf14e8ee52e51fa2ed8eefe80f02457004ba4d486d6aa1f517c0889501dc7413753f9599b099ebcbbd2d709")); + assert!(eq(&expected, &actual), 1); + } + + #[test_only] + const G2_INF_SERIALIZED_UNCOMP: vector = x"400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const G2_INF_SERIALIZED_COMP: vector = x"c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const G2_GENERATOR_SERIALIZED_UNCOMP: vector = x"13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801"; + #[test_only] + const G2_GENERATOR_SERIALIZED_COMP: vector = x"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8"; + #[test_only] + const G2_GENERATOR_MUL_BY_7_SERIALIZED_UNCOMP: vector = x"0d0273f6bf31ed37c3b8d68083ec3d8e20b5f2cc170fa24b9b5be35b34ed013f9a921f1cad1644d4bdb14674247234c8049cd1dbb2d2c3581e54c088135fef36505a6823d61b859437bfc79b617030dc8b40e32bad1fa85b9c0f368af6d38d3c05ecf93654b7a1885695aaeeb7caf41b0239dc45e1022be55d37111af2aecef87799638bec572de86a7437898efa702008b7ae4dbf802c17a6648842922c9467e460a71c88d393ee7af356da123a2f3619e80c3bdcc8e2b1da52f8cd9913ccdd"; + #[test_only] + const G2_GENERATOR_MUL_BY_7_SERIALIZED_COMP: vector = x"8d0273f6bf31ed37c3b8d68083ec3d8e20b5f2cc170fa24b9b5be35b34ed013f9a921f1cad1644d4bdb14674247234c8049cd1dbb2d2c3581e54c088135fef36505a6823d61b859437bfc79b617030dc8b40e32bad1fa85b9c0f368af6d38d3c"; + #[test_only] + const G2_GENERATOR_MUL_BY_7_NEG_SERIALIZED_UNCOMP: vector = x"0d0273f6bf31ed37c3b8d68083ec3d8e20b5f2cc170fa24b9b5be35b34ed013f9a921f1cad1644d4bdb14674247234c8049cd1dbb2d2c3581e54c088135fef36505a6823d61b859437bfc79b617030dc8b40e32bad1fa85b9c0f368af6d38d3c141418b3e4c84511f485fcc78b80b8bc623d6f3f1282e6da09f9c1860402272ba7129c72c4fcd2174f8ac87671053a8b1149639c79ffba82a4b71f73b11f186f8016a4686ab17ed0ec3d7bc6e476c6ee04c3f3c2d48b1d4ddfac073266ebddce"; + #[test_only] + const G2_GENERATOR_MUL_BY_7_NEG_SERIALIZED_COMP: vector = x"ad0273f6bf31ed37c3b8d68083ec3d8e20b5f2cc170fa24b9b5be35b34ed013f9a921f1cad1644d4bdb14674247234c8049cd1dbb2d2c3581e54c088135fef36505a6823d61b859437bfc79b617030dc8b40e32bad1fa85b9c0f368af6d38d3c"; + + #[test(fx = @std)] + fun test_g2affine(fx: signer) { + enable_cryptography_algebra_natives(&fx); + + // Special constants. + assert!(R_SERIALIZED == order(), 1); + let point_at_infinity = zero(); + let generator = one(); + + // Serialization/deserialization. + assert!(G2_GENERATOR_SERIALIZED_COMP == serialize(&generator), 1); + assert!(G2_GENERATOR_SERIALIZED_UNCOMP == serialize(&generator), 1); + let generator_from_uncomp = std::option::extract(&mut deserialize(&G2_GENERATOR_SERIALIZED_UNCOMP + )); + let generator_from_comp = std::option::extract(&mut deserialize(&G2_GENERATOR_SERIALIZED_COMP + )); + assert!(eq(&generator, &generator_from_comp), 1); + assert!(eq(&generator, &generator_from_uncomp), 1); + assert!(G2_INF_SERIALIZED_UNCOMP == serialize(&point_at_infinity), 1); + assert!(G2_INF_SERIALIZED_COMP == serialize(&point_at_infinity), 1); + let inf_from_uncomp = std::option::extract(&mut deserialize(&G2_INF_SERIALIZED_UNCOMP)); + let inf_from_comp = std::option::extract(&mut deserialize(&G2_INF_SERIALIZED_COMP)); + assert!(eq(&point_at_infinity, &inf_from_comp), 1); + assert!(eq(&point_at_infinity, &inf_from_uncomp), 1); + let point_7g_from_uncomp = std::option::extract(&mut deserialize(&G2_GENERATOR_MUL_BY_7_SERIALIZED_UNCOMP + )); + let point_7g_from_comp = std::option::extract(&mut deserialize(&G2_GENERATOR_MUL_BY_7_SERIALIZED_COMP + )); + assert!(eq(&point_7g_from_comp, &point_7g_from_uncomp), 1); + + // Deserialization should fail if given a point on the curve but not in the prime-order subgroup. + assert!(std::option::is_none(&deserialize(&x"f037d4ccd5ee751eba1c1fd4c7edbb76d2b04c3a1f3f554827cf37c3acbc2dbb7cdb320a2727c2462d6c55ca1f637707b96eeebc622c1dbe7c56c34f93887c8751b42bd04f29253a82251c192ef27ece373993b663f4360505299c5bd18c890ddd862a6308796bf47e2265073c1f7d81afd69f9497fc1403e2e97a866129b43b672295229c21116d4a99f3e5c2ae720a31f181dbed8a93e15f909c20cf69d11a8879adbbe6890740def19814e6d4ed23fb0dcbd79291655caf48b466ac9cae04")), 1); + assert!(std::option::is_none(&deserialize(&x"f037d4ccd5ee751eba1c1fd4c7edbb76d2b04c3a1f3f554827cf37c3acbc2dbb7cdb320a2727c2462d6c55ca1f637707b96eeebc622c1dbe7c56c34f93887c8751b42bd04f29253a82251c192ef27ece373993b663f4360505299c5bd18c890d")), 1); + + // Deserialization should fail if given a valid point in (Fq2,Fq2) but not on the curve. + assert!(std::option::is_none(&deserialize(&x"f037d4ccd5ee751eba1c1fd4c7edbb76d2b04c3a1f3f554827cf37c3acbc2dbb7cdb320a2727c2462d6c55ca1f637707b96eeebc622c1dbe7c56c34f93887c8751b42bd04f29253a82251c192ef27ece373993b663f4360505299c5bd18c890d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")), 1); + + // Deserialization should fail if given an invalid point (x not in Fq2). + assert!(std::option::is_none(&deserialize(&x"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdd862a6308796bf47e2265073c1f7d81afd69f9497fc1403e2e97a866129b43b672295229c21116d4a99f3e5c2ae720a31f181dbed8a93e15f909c20cf69d11a8879adbbe6890740def19814e6d4ed23fb0dcbd79291655caf48b466ac9cae04")), 1); + assert!(std::option::is_none(&deserialize(&x"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")), 1); + + // Deserialization should fail if given a byte array of wrong size. + assert!(std::option::is_none(&deserialize(&x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab")), 1); + assert!(std::option::is_none(&deserialize(&x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab")), 1); + + // Scalar multiplication. + let scalar_7 = from_u64(7); + let point_7g_calc = scalar_mul(&generator, &scalar_7); + assert!(eq(&point_7g_calc, &point_7g_from_comp), 1); + assert!(G2_GENERATOR_MUL_BY_7_SERIALIZED_UNCOMP == serialize(&point_7g_calc), 1); + assert!(G2_GENERATOR_MUL_BY_7_SERIALIZED_COMP == serialize(&point_7g_calc), 1); + + // Multi-scalar multiplication. + let num_entries = 1; + while (num_entries < 10) { + let scalars = rand_vector(num_entries); + let elements = rand_vector(num_entries); + + let expected = zero(); + let i = 0; + while (i < num_entries) { + let element = std::vector::borrow(&elements, i); + let scalar = std::vector::borrow(&scalars, i); + expected = add(&expected, &scalar_mul(element, scalar)); + i = i + 1; + }; + + let actual = multi_scalar_mul(&elements, &scalars); + assert!(eq(&expected, &actual), 1); + + num_entries = num_entries + 1; + }; + + // Doubling. + let scalar_2 = from_u64(2); + let point_2g = scalar_mul(&generator, &scalar_2); + let point_double_g = double(&generator); + assert!(eq(&point_2g, &point_double_g), 1); + + // Negation. + let point_minus_7g_calc = neg(&point_7g_calc); + assert!(G2_GENERATOR_MUL_BY_7_NEG_SERIALIZED_COMP == serialize(&point_minus_7g_calc), 1); + assert!(G2_GENERATOR_MUL_BY_7_NEG_SERIALIZED_UNCOMP == serialize(&point_minus_7g_calc), 1); + + // Addition. + let scalar_9 = from_u64(9); + let point_9g = scalar_mul(&generator, &scalar_9); + let point_2g = scalar_mul(&generator, &scalar_2); + let point_2g_calc = add(&point_minus_7g_calc, &point_9g); + assert!(eq(&point_2g, &point_2g_calc), 1); + + // Subtraction. + assert!(eq(&point_9g, &sub(&point_2g, &point_minus_7g_calc)), 1); + + // Hash-to-group using suite `BLS12381G2_XMD:SHA-256_SSWU_RO_`. + // Test vectors source: https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-bls12381g2_xmdsha-256_sswu_ + let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_", &b""); + let expected = std::option::extract(&mut deserialize(&x"05cb8437535e20ecffaef7752baddf98034139c38452458baeefab379ba13dff5bf5dd71b72418717047f5b0f37da03d0141ebfbdca40eb85b87142e130ab689c673cf60f1a3e98d69335266f30d9b8d4ac44c1038e9dcdd5393faf5c41fb78a12424ac32561493f3fe3c260708a12b7c620e7be00099a974e259ddc7d1f6395c3c811cdd19f1e8dbf3e9ecfdcbab8d60503921d7f6a12805e72940b963c0cf3471c7b2a524950ca195d11062ee75ec076daf2d4bc358c4b190c0c98064fdd92")); + assert!(eq(&expected, &actual), 1); + let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_", &b"abcdef0123456789"); + let expected = std::option::extract(&mut deserialize(&x"190d119345b94fbd15497bcba94ecf7db2cbfd1e1fe7da034d26cbba169fb3968288b3fafb265f9ebd380512a71c3f2c121982811d2491fde9ba7ed31ef9ca474f0e1501297f68c298e9f4c0028add35aea8bb83d53c08cfc007c1e005723cd00bb5e7572275c567462d91807de765611490205a941a5a6af3b1691bfe596c31225d3aabdf15faff860cb4ef17c7c3be05571a0f8d3c08d094576981f4a3b8eda0a8e771fcdcc8ecceaf1356a6acf17574518acb506e435b639353c2e14827c8")); + assert!(eq(&expected, &actual), 1); + } + + #[test_only] + const FQ12_ONE_SERIALIZED: vector = x"010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const GT_GENERATOR_SERIALIZED: vector = x"b68917caaa0543a808c53908f694d1b6e7b38de90ce9d83d505ca1ef1b442d2727d7d06831d8b2a7920afc71d8eb50120f17a0ea982a88591d9f43503e94a8f1abaf2e4589f65aafb7923c484540a868883432a5c60e75860b11e5465b1c9a08873ec29e844c1c888cb396933057ffdd541b03a5220eda16b2b3a6728ea678034ce39c6839f20397202d7c5c44bb68134f93193cec215031b17399577a1de5ff1f5b0666bdd8907c61a7651e4e79e0372951505a07fa73c25788db6eb8023519a5aa97b51f1cad1d43d8aabbff4dc319c79a58cafc035218747c2f75daf8f2fb7c00c44da85b129113173d4722f5b201b6b4454062e9ea8ba78c5ca3cadaf7238b47bace5ce561804ae16b8f4b63da4645b8457a93793cbd64a7254f150781019de87ee42682940f3e70a88683d512bb2c3fb7b2434da5dedbb2d0b3fb8487c84da0d5c315bdd69c46fb05d23763f2191aabd5d5c2e12a10b8f002ff681bfd1b2ee0bf619d80d2a795eb22f2aa7b85d5ffb671a70c94809f0dafc5b73ea2fb0657bae23373b4931bc9fa321e8848ef78894e987bff150d7d671aee30b3931ac8c50e0b3b0868effc38bf48cd24b4b811a2995ac2a09122bed9fd9fa0c510a87b10290836ad06c8203397b56a78e9a0c61c77e56ccb4f1bc3d3fcaea7550f3503efe30f2d24f00891cb45620605fcfaa4292687b3a7db7c1c0554a93579e889a121fd8f72649b2402996a084d2381c5043166673b3849e4fd1e7ee4af24aa8ed443f56dfd6b68ffde4435a92cd7a4ac3bc77e1ad0cb728606cf08bf6386e5410f"; + #[test_only] + const GT_GENERATOR_MUL_BY_7_SERIALIZED: vector = x"2041ea7b66c19680e2c0bb23245a71918753220b31f88a925aa9b1e192e7c188a0b365cb994b3ec5e809206117c6411242b940b10caa37ce734496b3b7c63578a0e3c076f9b31a7ca13a716262e0e4cda4ac994efb9e19893cbfe4d464b9210d099d808a08b3c4c3846e7529984899478639c4e6c46152ef49a04af9c8e6ff442d286c4613a3dac6a4bee4b40e1f6b030f2871dabe4223b250c3181ecd3bc6819004745aeb6bac567407f2b9c7d1978c45ee6712ae46930bc00638383f6696158bad488cbe7663d681c96c035481dbcf78e7a7fbaec3799163aa6914cef3365156bdc3e533a7c883d5974e3462ac6f19e3f9ce26800ae248a45c5f0dd3a48a185969224e6cd6af9a048241bdcac9800d94aeee970e08488fb961e36a769b6c185d185b4605dc9808517196bba9d00a3e37bca466c19187486db104ee03962d39fe473e276355618e44c965f05082bb027a7baa4bcc6d8c0775c1e8a481e77df36ddad91e75a982302937f543a11fe71922dcd4f46fe8f951f91cde412b359507f2b3b6df0374bfe55c9a126ad31ce254e67d64194d32d7955ec791c9555ea5a917fc47aba319e909de82da946eb36e12aff936708402228295db2712f2fc807c95092a86afd71220699df13e2d2fdf2857976cb1e605f72f1b2edabadba3ff05501221fe81333c13917c85d725ce92791e115eb0289a5d0b3330901bb8b0ed146abeb81381b7331f1c508fb14e057b05d8b0190a9e74a3d046dcd24e7ab747049945b3d8a120c4f6d88e67661b55573aa9b361367488a1ef7dffd967d64a1518"; + #[test_only] + const GT_GENERATOR_MUL_BY_7_NEG_SERIALIZED: vector = x"2041ea7b66c19680e2c0bb23245a71918753220b31f88a925aa9b1e192e7c188a0b365cb994b3ec5e809206117c6411242b940b10caa37ce734496b3b7c63578a0e3c076f9b31a7ca13a716262e0e4cda4ac994efb9e19893cbfe4d464b9210d099d808a08b3c4c3846e7529984899478639c4e6c46152ef49a04af9c8e6ff442d286c4613a3dac6a4bee4b40e1f6b030f2871dabe4223b250c3181ecd3bc6819004745aeb6bac567407f2b9c7d1978c45ee6712ae46930bc00638383f6696158bad488cbe7663d681c96c035481dbcf78e7a7fbaec3799163aa6914cef3365156bdc3e533a7c883d5974e3462ac6f19e3f9ce26800ae248a45c5f0dd3a48a185969224e6cd6af9a048241bdcac9800d94aeee970e08488fb961e36a769b6c184e92a4b9fa2366b1ae8ebdf5542fa1e0ec390c90df40a91e5261800581b5492bd9640d1c5352babc551d1a49998f4517312f55b4339272b28a3e6b0c7d182e2bb61bd7d72b29ae3696db8fafe32b904ab5d0764e46bf21f9a0c9a1f7bedc6b12b9f64820fc8b3fd4a26541472be3c9c93d784cdd53a059d1604bf3292fedd1babfb00398128e3241bc63a5a47b5e9207fcb0c88f7bfddc376a242c9f0c032ba28eec8670f1fa1d47567593b4571c983b8015df91cfa1241b7fb8a57e0e6e01145b98de017eccc2a66e83ced9d83119a505e552467838d35b8ce2f4d7cc9a894f6dee922f35f0e72b7e96f0879b0c8614d3f9e5f5618b5be9b82381628448641a8bb0fd1dffb16c70e6831d8d69f61f2a2ef9e90c421f7a5b1ce7a5d113c7eb01"; + + #[test(fx = @std)] + fun test_gt(fx: signer) { + enable_cryptography_algebra_natives(&fx); + + // Special constants. + assert!(R_SERIALIZED == order(), 1); + let identity = zero(); + let generator = one(); + + // Serialization/deserialization. + assert!(GT_GENERATOR_SERIALIZED == serialize(&generator), 1); + let generator_from_deser = std::option::extract(&mut deserialize(>_GENERATOR_SERIALIZED)); + assert!(eq(&generator, &generator_from_deser), 1); + assert!(FQ12_ONE_SERIALIZED == serialize(&identity), 1); + let identity_from_deser = std::option::extract(&mut deserialize(&FQ12_ONE_SERIALIZED)); + assert!(eq(&identity, &identity_from_deser), 1); + let element_7g_from_deser = std::option::extract(&mut deserialize(>_GENERATOR_MUL_BY_7_SERIALIZED + )); + assert!(std::option::is_none(&deserialize(&x"ffff")), 1); + + // Deserialization should fail if given an element in Fq12 but not in the prime-order subgroup. + assert!(std::option::is_none(&deserialize(&x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")), 1); + + // Deserialization should fail if given a byte array of wrong size. + assert!(std::option::is_none(&deserialize(&x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ab")), 1); + + // Element scalar multiplication. + let scalar_7 = from_u64(7); + let element_7g_calc = scalar_mul(&generator, &scalar_7); + assert!(eq(&element_7g_calc, &element_7g_from_deser), 1); + assert!(GT_GENERATOR_MUL_BY_7_SERIALIZED == serialize(&element_7g_calc), 1); + + // Element negation. + let element_minus_7g_calc = neg(&element_7g_calc); + assert!(GT_GENERATOR_MUL_BY_7_NEG_SERIALIZED == serialize(&element_minus_7g_calc), 1); + + // Element addition. + let scalar_9 = from_u64(9); + let element_9g = scalar_mul(&generator, &scalar_9); + let scalar_2 = from_u64(2); + let element_2g = scalar_mul(&generator, &scalar_2); + let element_2g_calc = add(&element_minus_7g_calc, &element_9g); + assert!(eq(&element_2g, &element_2g_calc), 1); + + // Subtraction. + assert!(eq(&element_9g, &sub(&element_2g, &element_minus_7g_calc)), 1); + + // Upcasting to Fq12. + assert!(eq(&one(), &upcast(&identity)), 1); + } + + #[test_only] + use aptos_std::crypto_algebra::{zero, one, from_u64, eq, deserialize, serialize, neg, add, sub, mul, div, inv, rand_insecure, sqr, order, scalar_mul, multi_scalar_mul, double, hash_to, upcast, enable_cryptography_algebra_natives, pairing, multi_pairing, downcast, Element}; + + #[test_only] + const FR_VAL_0_SERIALIZED_LSB: vector = x"0000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const FR_VAL_1_SERIALIZED_LSB: vector = x"0100000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const FR_VAL_7_SERIALIZED_LSB: vector = x"0700000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const FR_VAL_7_SERIALIZED_MSB: vector = x"0000000000000000000000000000000000000000000000000000000000000007"; + #[test_only] + const FR_VAL_7_NEG_SERIALIZED_LSB: vector = x"fafffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73"; + + #[test(fx = @std)] + fun test_fr(fx: signer) { + enable_cryptography_algebra_natives(&fx); + + // Constants. + assert!(R_SERIALIZED == order(), 1); + + // Serialization/deserialization. + let val_0 = zero(); + let val_1 = one(); + assert!(FR_VAL_0_SERIALIZED_LSB == serialize(&val_0), 1); + assert!(FR_VAL_1_SERIALIZED_LSB == serialize(&val_1), 1); + let val_7 = from_u64(7); + let val_7_2nd = std::option::extract(&mut deserialize(&FR_VAL_7_SERIALIZED_LSB)); + let val_7_3rd = std::option::extract(&mut deserialize(&FR_VAL_7_SERIALIZED_MSB)); + assert!(eq(&val_7, &val_7_2nd), 1); + assert!(eq(&val_7, &val_7_3rd), 1); + assert!(FR_VAL_7_SERIALIZED_LSB == serialize(&val_7), 1); + assert!(FR_VAL_7_SERIALIZED_MSB == serialize(&val_7), 1); + + // Deserialization should fail if given a byte array of right size but the value is not a member. + assert!(std::option::is_none(&deserialize(&x"01000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73")), 1); + assert!(std::option::is_none(&deserialize(&x"73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001")), 1); + + // Deserialization should fail if given a byte array of wrong size. + assert!(std::option::is_none(&deserialize(&x"01000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed7300")), 1); + assert!(std::option::is_none(&deserialize(&x"0073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001")), 1); + assert!(std::option::is_none(&deserialize(&x"ffff")), 1); + assert!(std::option::is_none(&deserialize(&x"ffff")), 1); + + // Negation. + let val_minus_7 = neg(&val_7); + assert!(FR_VAL_7_NEG_SERIALIZED_LSB == serialize(&val_minus_7), 1); + + // Addition. + let val_9 = from_u64(9); + let val_2 = from_u64(2); + assert!(eq(&val_2, &add(&val_minus_7, &val_9)), 1); + + // Subtraction. + assert!(eq(&val_9, &sub(&val_2, &val_minus_7)), 1); + + // Multiplication. + let val_63 = from_u64(63); + assert!(eq(&val_63, &mul(&val_7, &val_9)), 1); + + // division. + let val_0 = from_u64(0); + assert!(eq(&val_7, &std::option::extract(&mut div(&val_63, &val_9))), 1); + assert!(std::option::is_none(&div(&val_63, &val_0)), 1); + + // Inversion. + assert!(eq(&val_minus_7, &neg(&val_7)), 1); + assert!(std::option::is_none(&inv(&val_0)), 1); + + // Squaring. + let val_x = rand_insecure(); + assert!(eq(&mul(&val_x, &val_x), &sqr(&val_x)), 1); + } + + #[test(fx = @std)] + fun test_pairing(fx: signer) { + enable_cryptography_algebra_natives(&fx); + + // pairing(a*P,b*Q) == (a*b)*pairing(P,Q) + let element_p = rand_insecure(); + let element_q = rand_insecure(); + let a = rand_insecure(); + let b = rand_insecure(); + let gt_element = pairing(&scalar_mul(&element_p, &a), &scalar_mul(&element_q, &b)); + let gt_element_another = scalar_mul(&pairing(&element_p, &element_q), &mul(&a, &b)); + assert!(eq(>_element, >_element_another), 1); + } + + #[test(fx = @std)] + fun test_multi_pairing(fx: signer) { + enable_cryptography_algebra_natives(&fx); + + // Will compute e(a0*P0,b0*Q0)+e(a1*P1,b1*Q1)+e(a2*P2,b2*Q2). + let a0 = rand_insecure(); + let a1 = rand_insecure(); + let a2 = rand_insecure(); + let element_p0 = rand_insecure(); + let element_p1 = rand_insecure(); + let element_p2 = rand_insecure(); + let p0_a0 = scalar_mul(&element_p0, &a0); + let p1_a1 = scalar_mul(&element_p1, &a1); + let p2_a2 = scalar_mul(&element_p2, &a2); + let b0 = rand_insecure(); + let b1 = rand_insecure(); + let b2 = rand_insecure(); + let element_q0 = rand_insecure(); + let element_q1 = rand_insecure(); + let element_q2 = rand_insecure(); + let q0_b0 = scalar_mul(&element_q0, &b0); + let q1_b1 = scalar_mul(&element_q1, &b1); + let q2_b2 = scalar_mul(&element_q2, &b2); + + // Naive method. + let n0 = pairing(&p0_a0, &q0_b0); + let n1 = pairing(&p1_a1, &q1_b1); + let n2 = pairing(&p2_a2, &q2_b2); + let n = zero(); + n = add(&n, &n0); + n = add(&n, &n1); + n = add(&n, &n2); + + // Efficient API. + let m = multi_pairing(&vector[p0_a0, p1_a1, p2_a2], &vector[q0_b0, q1_b1, q2_b2]); + assert!(eq(&n, &m), 1); + } + + #[test(fx = @std)] + #[expected_failure(abort_code = 0x010002, location = aptos_std::crypto_algebra)] + fun test_multi_pairing_should_abort_when_sizes_mismatch(fx: signer) { + enable_cryptography_algebra_natives(&fx); + let g1_elements = vector[rand_insecure()]; + let g2_elements = vector[rand_insecure(), rand_insecure()]; + multi_pairing(&g1_elements, &g2_elements); + } + + #[test(fx = @std)] + #[expected_failure(abort_code = 0x010002, location = aptos_std::crypto_algebra)] + fun test_multi_scalar_mul_should_abort_when_sizes_mismatch(fx: signer) { + enable_cryptography_algebra_natives(&fx); + let elements = vector[rand_insecure()]; + let scalars = vector[rand_insecure(), rand_insecure()]; + multi_scalar_mul(&elements, &scalars); + } + + #[test_only] + /// The maximum number of `G1` elements that can be created in a transaction, + /// calculated by the current memory limit (1MB) and the in-mem G1 representation size (144 bytes per element). + const G1_NUM_MAX_NUMERATOR: u64 = 1048576; // TODO(#9330) + + #[test_only] + const G1_NUM_MAX_DENOMINATOR: u64 = 144; // TODO(#9330) + + #[test(fx = @std)] + fun test_memory_limit(fx: signer) { + enable_cryptography_algebra_natives(&fx); + let remaining = G1_NUM_MAX_NUMERATOR / G1_NUM_MAX_DENOMINATOR; + while (remaining > 0) { + zero(); + remaining = remaining - 1; + } + } + + #[test(fx = @std)] + #[expected_failure(abort_code = 0x090003, location = std::crypto_algebra)] + fun test_memory_limit_exceeded_with_g1(fx: signer) { + enable_cryptography_algebra_natives(&fx); + let remaining = G1_NUM_MAX_NUMERATOR / G1_NUM_MAX_DENOMINATOR + 1; + while (remaining > 0) { + zero(); + remaining = remaining - 1; + } + } + + // + // (Tests end here.) + // + } From b429d5c2bc3984d08331342a3768c0b82c5ae7b3 Mon Sep 17 00:00:00 2001 From: caojiafeng Date: Sat, 2 Dec 2023 19:32:06 +0800 Subject: [PATCH 06/21] bn254: add test and doc --- .../aptos-stdlib/doc/bn254_algebra.md | 13 + .../sources/cryptography/bn254_algebra.move | 442 ++++++++++++++++-- .../cryptography/algebra/serialization.rs | 2 +- 3 files changed, 406 insertions(+), 51 deletions(-) diff --git a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md index eb5e6803d86ae..66a276d695917 100644 --- a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md +++ b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md @@ -23,6 +23,7 @@ - [Struct `FormatG2Compr`](#0x1_bn254_algebra_FormatG2Compr) - [Struct `Gt`](#0x1_bn254_algebra_Gt) - [Struct `FormatGt`](#0x1_bn254_algebra_FormatGt) +- [Constants](#@Constants_0)
@@ -515,5 +516,17 @@ + + +## Constants + + + + + + +
const FQ_R_SERIALIZED: vector<u8> = [71, 253, 124, 216, 22, 140, 32, 60, 141, 202, 113, 104, 145, 106, 129, 151, 93, 88, 129, 129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48];
+
+ [move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move index ff72d51ee9224..a0757ffca0d01 100644 --- a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move +++ b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move @@ -1,39 +1,247 @@ +/// This module defines marker types, constants and test cases for working with BN254 curves using the generic API defined in `algebra.move`. +/// BN254 was sampled as part of the [\[BCTV14\]](https://eprint.iacr.org/2013/879.pdf) paper . +/// The name denotes that it is a Barreto--Naehrig curve of embedding degree 12, +/// defined over a 254-bit (prime) field. The scalar field is highly 2-adic. +/// +/// This curve is also implemented in [libff](https://github.com/scipr-lab/libff/tree/master/libff/algebra/curves/alt_bn128) under the name `bn128`. +/// It is the same as the `bn256` curve used in Ethereum (eg: [go-ethereum](https://github.com/ethereum/go-ethereum/tree/master/crypto/bn254/cloudflare)). +/// +/// #CAUTION +/// **This curve does not satisfy the 128-bit security level anymore.** +/// +/// +/// Curve information: +/// * Base field: q = +/// 21888242871839275222246405745257275088696311157297823662689037894645226208583 +/// * Scalar field: r = +/// 21888242871839275222246405745257275088548364400416034343698204186575808495617 +/// * valuation(q - 1, 2) = 1 +/// * valuation(r - 1, 2) = 28 +/// * G1 curve equation: y^2 = x^3 + 3 +/// * G2 curve equation: y^2 = x^3 + B, where +/// * B = 3/(u+9) where Fq2 is represented as Fq\[u\]/(u^2+1) = +/// Fq2(19485874751759354771024239261021720505790618469301721065564631296452457478373, +/// 266929791119991161246907387137283842545076965332900288569378510910307636690) +/// +/// +/// Currently-supported BN254 structures include `Fq12`, `Fr`, `Fq`, `Fq2`, `G1`, `G2` and `Gt`, +/// along with their widely-used serialization formats, +/// the pairing between `G1`, `G2` and `Gt`. +/// +/// Other unimplemented BN254 structures and serialization formats are also listed here, +/// as they help define some of the currently supported structures. +/// Their implementation may also be added in the future. +/// +/// `Fq6`: the finite field $F_{q^6}$ used in BN254 curves, +/// which is an extension field of `Fq2`, constructed as $F_{q^6}=F_{q^2}[v]/(v^3-u-9)$. +/// +/// `FormatFq6LscLsb`: a serialization scheme for `Fq6` elements, +/// where an element in the form $(c_0+c_1\cdot v+c_2\cdot v^2)$ is represented by a byte array `b[]` of size 192, +/// which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first: +/// - `b[0..64]` is $c_0$ serialized using `FormatFq2LscLsb`. +/// - `b[64..128]` is $c_1$ serialized using `FormatFq2LscLsb`. +/// - `b[128..192]` is $c_2$ serialized using `FormatFq2LscLsb`. +/// +/// `G1Full`: a group constructed by the points on the BN254 curve $E(F_q): y^2=x^3+3$ and the point at infinity, +/// under the elliptic curve point addition. +/// It contains the prime-order subgroup $G_1$ used in pairing. +/// +/// `G2Full`: a group constructed by the points on a curve $E'(F_{q^2}): y^2=x^3+3/(u+9)$ and the point at infinity, +/// under the elliptic curve point addition. +/// It contains the prime-order subgroup $G_2$ used in pairing. module std::bn254_algebra { + // + // Marker types + serialization formats begin. + // + + /// The finite field $F_r$ that can be used as the scalar fields + /// associated with the groups $G_1$, $G_2$, $G_t$ in BN254-based pairing. struct Fr {} + + /// A serialization format for `Fr` elements, + /// where an element is represented by a byte array `b[]` of size 32 with the least significant byte (LSB) coming first. + /// + /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatFrLsb {} + + /// A serialization scheme for `Fr` elements, + /// where an element is represented by a byte array `b[]` of size 32 with the most significant byte (MSB) coming first. + /// + /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatFrMsb {} + /// The finite field $F_q$ that can be used as the base field of $G_1$ struct Fq {} + + /// A serialization format for `Fq` elements, + /// where an element is represented by a byte array `b[]` of size 32 with the least significant byte (LSB) coming first. + /// + /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatFqLsb {} + + /// A serialization scheme for `Fq` elements, + /// where an element is represented by a byte array `b[]` of size 32 with the most significant byte (MSB) coming first. + /// + /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatFqMsb {} + /// The finite field $F_q2$ that can be used as the base field of $G_2$ + /// which is an extension field of `Fq`, constructed as $F_{q^2}=F_{q}[u]/(u^2+1)$. struct Fq2 {} + + /// A serialization scheme for `Fq2` elements, + /// where an element $(c_0+c_1\cdot w)$ is represented by a byte array `b[]` of size N=64, + /// which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first. + /// - `b[0..N]` is $c_0$ serialized using `FormatFqLscLsb`. + /// - `b[N..384]` is $c_1$ serialized using `FormatFqLscLsb`. + /// + /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatFq2LscLsb {} + /// The finite field $F_{q^12}$ used in BN254 curves, + /// which is an extension field of `Fq6` (defined in the module documentation), constructed as $F_{q^12}=F_{q^6}[w]/(w^2-v)$. struct Fq12 {} + /// A serialization scheme for `Fq12` elements, + /// where an element $(c_0+c_1\cdot w)$ is represented by a byte array `b[]` of size 384, + /// which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first. + /// - `b[0..192]` is $c_0$ serialized using `FormatFq6LscLsb` (defined in the module documentation). + /// - `b[192..384]` is $c_1$ serialized using `FormatFq6LscLsb`. + /// + /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatFq12LscLsb {} + /// The group $G_1$ in BN254-based pairing $G_1 \times G_2 \rightarrow G_t$. + /// It is a subgroup of `G1Full` (defined in the module documentation) with a prime order $r$ + /// equal to 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001. + /// (so `Fr` is the associated scalar field). struct G1 {} + + /// A serialization scheme for `G1` elements derived from arkworks.rs. + /// + /// Below is the serialization procedure that takes a `G2` element `p` and outputs a byte array of size N=64. + /// 1. Let `(x,y)` be the coordinates of `p` if `p` is on the curve, or `(0,0)` otherwise. + /// 1. Serialize `x` and `y` into `b_x[]` and `b_y[]` respectively using `FormatFqLsb` (defined in the module documentation). + /// 1. Concatenate `b_x[]` and `b_y[]` into `b[]`. + /// 1. If `p` is the point at infinity, set the infinity bit: `b[N-1]: = b[N-1] | 0b0100_0000`. + /// 1. If `y`is negative, set the negative bit: `b[N-1]: = b[N-1] | 0b1000_0000`. + /// 1. Return `b[]`. + /// + /// Below is the deserialization procedure that takes a byte array `b[]` and outputs either a `G1` element or none. + /// 1. If the size of `b[]` is not N, return none. + /// 1. Compute the infinity flag as `b[N-1] & 0b0100_0000 != 0`. + /// 1. If the infinity flag is set, return the point at infinity. + /// 1. Deserialize `[b[0], b[1], ..., b[N/2-1]]` to `x` using `FormatFqLsb`. If `x` is none, return none. + /// 1. Deserialize `[b[N/2], ..., b[N] & 0b0011_1111]` to `y` using `FormatFqLsb`. If `y` is none, return none. + /// 1. Check if `(x,y)` is on curve `E`. If not, return none. + /// 1. Check if `(x,y)` is in the subgroup of order `r`. If not, return none. + /// 1. Return `(x,y)`. + /// + /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatG1Uncompr {} + + /// A serialization scheme for `G1` elements derived from arkworks.rs + /// + /// Below is the serialization procedure that takes a `G1` element `p` and outputs a byte array of size N=32. + /// 1. Let `(x,y)` be the coordinates of `p` if `p` is on the curve, or `(0,0)` otherwise. + /// 1. Serialize `x` into `b[]` using `FormatFqLsb` (defined in the module documentation). + /// 1. If `p` is the point at infinity, set the infinity bit: `b[N-1]: = b[N-1] | 0b0100_0000`. + /// 1. If `y > -y`, set the lexicographical flag: `b[N-1] := b[N-1] | 0x1000_0000`. + /// 1. Return `b[]`. + /// + /// Below is the deserialization procedure that takes a byte array `b[]` and outputs either a `G1` element or none. + /// 1. If the size of `b[]` is not N, return none. + /// 1. Compute the infinity flag as `b[N-1] & 0b0100_0000 != 0`. + /// 1. If the infinity flag is set, return the point at infinity. + /// 1. Compute the lexicographical flag as `b[N-1] & 0b1000_0000 != 0`. + /// 1. Deserialize `[b[0], b[1], ..., b[N/2-1] & 0b0011_1111]` to `x` using `FormatFqLsb`. If `x` is none, return none. + /// 1. Solve the curve equation with `x` for `y`. If no such `y` exists, return none. + /// 1. Let `y'` be `max(y,-y)` if the lexicographical flag is set, or `min(y,-y)` otherwise. + /// 1. Check if `(x,y')` is in the subgroup of order `r`. If not, return none. + /// 1. Return `(x,y')`. + /// + /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatG1Compr {} + + /// The group $G_2$ in BN254-based pairing $G_1 \times G_2 \rightarrow G_t$. + /// It is a subgroup of `G2Full` (defined in the module documentation) with a prime order $r$ equal to + /// 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001. + /// (so `Fr` is the scalar field). struct G2 {} + + /// A serialization scheme for `G2` elements derived from arkworks.rs. + /// + /// Below is the serialization procedure that takes a `G2` element `p` and outputs a byte array of size N=128. + /// 1. Let `(x,y)` be the coordinates of `p` if `p` is on the curve, or `(0,0)` otherwise. + /// 1. Serialize `x` and `y` into `b_x[]` and `b_y[]` respectively using `FormatFq2Lsb` (defined in the module documentation). + /// 1. Concatenate `b_x[]` and `b_y[]` into `b[]`. + /// 1. If `p` is the point at infinity, set the infinity bit: `b[N-1]: = b[N-1] | 0b0100_0000`. + /// 1. If `y`is negative, set the negative bit: `b[N-1]: = b[N-1] | 0b1000_0000`. + /// 1. Return `b[]`. + /// + /// Below is the deserialization procedure that takes a byte array `b[]` and outputs either a `G1` element or none. + /// 1. If the size of `b[]` is not N, return none. + /// 1. Compute the infinity flag as `b[N-1] & 0b0100_0000 != 0`. + /// 1. If the infinity flag is set, return the point at infinity. + /// 1. Deserialize `[b[0], b[1], ..., b[N/2-1]]` to `x` using `FormatFq2Lsb`. If `x` is none, return none. + /// 1. Deserialize `[b[N/2], ..., b[N] & 0b0011_1111]` to `y` using `FormatFq2Lsb`. If `y` is none, return none. + /// 1. Check if `(x,y)` is on curve `E`. If not, return none. + /// 1. Check if `(x,y)` is in the subgroup of order `r`. If not, return none. + /// 1. Return `(x,y)`. + /// + /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatG2Uncompr {} + + /// A serialization scheme for `G1` elements derived from arkworks.rs + /// + /// Below is the serialization procedure that takes a `G1` element `p` and outputs a byte array of size N=64. + /// 1. Let `(x,y)` be the coordinates of `p` if `p` is on the curve, or `(0,0)` otherwise. + /// 1. Serialize `x` into `b[]` using `FormatFq2Lsb` (defined in the module documentation). + /// 1. If `p` is the point at infinity, set the infinity bit: `b[N-1]: = b[N-1] | 0b0100_0000`. + /// 1. If `y > -y`, set the lexicographical flag: `b[N-1] := b[N-1] | 0x1000_0000`. + /// 1. Return `b[]`. + /// + /// Below is the deserialization procedure that takes a byte array `b[]` and outputs either a `G1` element or none. + /// 1. If the size of `b[]` is not N, return none. + /// 1. Compute the infinity flag as `b[N-1] & 0b0100_0000 != 0`. + /// 1. If the infinity flag is set, return the point at infinity. + /// 1. Compute the lexicographical flag as `b[N-1] & 0b1000_0000 != 0`. + /// 1. Deserialize `[b[0], b[1], ..., b[N/2-1] & 0b0011_1111]` to `x` using `FormatFq2Lsb`. If `x` is none, return none. + /// 1. Solve the curve equation with `x` for `y`. If no such `y` exists, return none. + /// 1. Let `y'` be `max(y,-y)` if the lexicographical flag is set, or `min(y,-y)` otherwise. + /// 1. Check if `(x,y')` is in the subgroup of order `r`. If not, return none. + /// 1. Return `(x,y')`. + /// + /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatG2Compr {} + /// The group $G_t$ in BN254-based pairing $G_1 \times G_2 \rightarrow G_t$. + /// It is a multiplicative subgroup of `Fq12`, + /// with a prime order $r$ equal to 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001. + /// (so `Fr` is the scalar field). + /// The identity of `Gt` is 1. struct Gt {} + + /// A serialization scheme for `Gt` elements. + /// + /// To serialize, it treats a `Gt` element `p` as an `Fq12` element and serialize it using `FormatFq12LscLsb`. + /// + /// To deserialize, it uses `FormatFq12LscLsb` to try deserializing to an `Fq12` element then test the membership in `Gt`. + /// + /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatGt {} + // Tests begin. #[test_only] - const FQ12_VAL_0_SERIALIZED: vector = x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + const FQ2_VAL_0_SERIALIZED: vector = x"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; #[test_only] - const FQ12_VAL_1_SERIALIZED: vector = x"010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + const FQ2_VAL_1_SERIALIZED: vector = x"01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; #[test_only] - const FQ12_VAL_7_SERIALIZED: vector = x"070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + const FQ2_VAL_7_SERIALIZED: vector = x"07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; #[test_only] - const FQ12_VAL_7_NEG_SERIALIZED: vector = x"a4aafffffffffeb9ffff53b1feffab1e24f6b0f6a0d23067bf1285f3844b7764d7ac4b43b6a71b4b9ae67f39ea11011a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + const FQ2_VAL_7_NEG_SERIALIZED: vector = x"40fd7cd8168c203c8dca7168916a81975d588181b64550b829a031e1724e64300000000000000000000000000000000000000000000000000000000000000000"; #[test_only] - const Q12_SERIALIZED: vector = x"21f186cad2e2d4c1dbaf8a066b0ebf41f734e3f859b1c523a6c1f4d457413fdbe3cd44add090135d3ae519acc30ee3bdb6bfac6573b767e975b18a77d53cdcddebf3672c74da9d1409d51b2b2db7ff000d59e3aa7cf09220159f925c86b65459ca6558c4eaa703bf45d85030ff85cc6a879c7e2c4034f7045faf20e4d3dcfffac5eb6634c3e7b939b69b2be70bdf6b9a4680297839b4e3a48cd746bd4d0ea82749ffb7e71bd9b3fb10aa684d71e6adab1250b1d8604d91b51c76c256a50b60ddba2f52b6cc853ac926c6ea86d09d400b2f2330e5c8e92e38905ba50a50c9e11cd979c284bf1327ccdc051a6da1a4a7eac5cec16757a27a1a2311bedd108a9b21ac0814269e7523a5dd3a1f5f4767ffe504a6cb3994fb0ec98d5cd5da00b9cb1188a85f2aa871ecb8a0f9d64141f1ccd2699c138e0ef9ac4d8d6a692b29db0f38b60eb08426ab46109fbab9a5221bb44dd338aafebcc4e6c10dd933597f3ff44ba41d04e82871447f3a759cfa9397c22c0c77f13618dfb65adc8aacf008"; + const Q2_SERIALIZED: vector = x"b1695d27a258543b01c1ea092d0702a6dcca966d9c18504ac842127a959e68048db3c6345cfaed260656371651850bb01cd248037c6f9a599cbf3c76b8c42509"; #[test_only] fun rand_vector(num: u64): vector> { @@ -45,6 +253,67 @@ module std::bn254_algebra { elements } + #[test(fx = @std)] + fun test_fq2(fx: signer) { + enable_cryptography_algebra_natives(&fx); + + // Constants. + assert!(Q2_SERIALIZED == order(), 1); + + // Serialization/deserialization. + let val_0 = zero(); + let val_1 = one(); + assert!(FQ2_VAL_0_SERIALIZED == serialize(&val_0), 1); + assert!(FQ2_VAL_1_SERIALIZED == serialize(&val_1), 1); + let val_7 = from_u64(7); + let val_7_another = std::option::extract(&mut deserialize(&FQ2_VAL_7_SERIALIZED)); + assert!(eq(&val_7, &val_7_another), 1); + assert!(FQ2_VAL_7_SERIALIZED == serialize(&val_7), 1); + assert!(std::option::is_none(&deserialize(&x"ffff")), 1); + + // Negation. + let val_minus_7 = neg(&val_7); + assert!(FQ2_VAL_7_NEG_SERIALIZED == serialize(&val_minus_7), 1); + + // Addition. + let val_9 = from_u64(9); + let val_2 = from_u64(2); + assert!(eq(&val_2, &add(&val_minus_7, &val_9)), 1); + + // Subtraction. + assert!(eq(&val_9, &sub(&val_2, &val_minus_7)), 1); + + // Multiplication. + let val_63 = from_u64(63); + assert!(eq(&val_63, &mul(&val_7, &val_9)), 1); + + // division. + let val_0 = from_u64(0); + assert!(eq(&val_7, &std::option::extract(&mut div(&val_63, &val_9))), 1); + assert!(std::option::is_none(&div(&val_63, &val_0)), 1); + + // Inversion. + assert!(eq(&val_minus_7, &neg(&val_7)), 1); + assert!(std::option::is_none(&inv(&val_0)), 1); + + // Squaring. + let val_x = rand_insecure(); + assert!(eq(&mul(&val_x, &val_x), &sqr(&val_x)), 1); + } + + + #[test_only] + const FQ12_VAL_0_SERIALIZED: vector = x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const FQ12_VAL_1_SERIALIZED: vector = x"010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const FQ12_VAL_7_SERIALIZED: vector = x"070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const FQ12_VAL_7_NEG_SERIALIZED: vector = x"40fd7cd8168c203c8dca7168916a81975d588181b64550b829a031e1724e643000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const Q12_SERIALIZED: vector = x"21f186cad2e2d4c1dbaf8a066b0ebf41f734e3f859b1c523a6c1f4d457413fdbe3cd44add090135d3ae519acc30ee3bdb6bfac6573b767e975b18a77d53cdcddebf3672c74da9d1409d51b2b2db7ff000d59e3aa7cf09220159f925c86b65459ca6558c4eaa703bf45d85030ff85cc6a879c7e2c4034f7045faf20e4d3dcfffac5eb6634c3e7b939b69b2be70bdf6b9a4680297839b4e3a48cd746bd4d0ea82749ffb7e71bd9b3fb10aa684d71e6adab1250b1d8604d91b51c76c256a50b60ddba2f52b6cc853ac926c6ea86d09d400b2f2330e5c8e92e38905ba50a50c9e11cd979c284bf1327ccdc051a6da1a4a7eac5cec16757a27a1a2311bedd108a9b21ac0814269e7523a5dd3a1f5f4767ffe504a6cb3994fb0ec98d5cd5da00b9cb1188a85f2aa871ecb8a0f9d64141f1ccd2699c138e0ef9ac4d8d6a692b29db0f38b60eb08426ab46109fbab9a5221bb44dd338aafebcc4e6c10dd933597f3ff44ba41d04e82871447f3a759cfa9397c22c0c77f13618dfb65adc8aacf008"; + + #[test(fx = @std)] fun test_fq12(fx: signer) { enable_cryptography_algebra_natives(&fx); @@ -94,26 +363,28 @@ module std::bn254_algebra { // Downcasting. assert!(eq(&zero(), &std::option::extract(&mut downcast(&val_1))), 1); + // upcasting + assert!(eq(&val_1, &upcast(&zero())), 1); } #[test_only] - const R_SERIALIZED: vector = x"01000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73"; + const R_SERIALIZED: vector = x"010000f093f5e1439170b97948e833285d588181b64550b829a031e1724e6430"; #[test_only] - const G1_INF_SERIALIZED_COMP: vector = x"c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + const G1_INF_SERIALIZED_COMP: vector = x"0000000000000000000000000000000000000000000000000000000000000040"; #[test_only] - const G1_INF_SERIALIZED_UNCOMP: vector = x"400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + const G1_INF_SERIALIZED_UNCOMP: vector = x"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040"; #[test_only] - const G1_GENERATOR_SERIALIZED_COMP: vector = x"97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"; + const G1_GENERATOR_SERIALIZED_COMP: vector = x"0100000000000000000000000000000000000000000000000000000000000000"; #[test_only] - const G1_GENERATOR_SERIALIZED_UNCOMP: vector = x"17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1"; + const G1_GENERATOR_SERIALIZED_UNCOMP: vector = x"01000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000"; #[test_only] - const G1_GENERATOR_MUL_BY_7_SERIALIZED_COMP: vector = x"b928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7"; + const G1_GENERATOR_MUL_BY_7_SERIALIZED_COMP: vector = x"78e0ffab866b3a9876bd01b8ecc66fcb86936277f425539a758dbbd32e2b0717"; #[test_only] - const G1_GENERATOR_MUL_BY_7_SERIALIZED_UNCOMP: vector = x"1928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7108dadbaa4b636445639d5ae3089b3c43a8a1d47818edd1839d7383959a41c10fdc66849cfa1b08c5a11ec7e28981a1c"; + const G1_GENERATOR_MUL_BY_7_SERIALIZED_UNCOMP: vector = x"78e0ffab866b3a9876bd01b8ecc66fcb86936277f425539a758dbbd32e2b07179eafd4607f9f80771bf4185df03bfead7a3719fa4bb57b0152dd30d16cda8a16"; #[test_only] - const G1_GENERATOR_MUL_BY_7_NEG_SERIALIZED_COMP: vector = x"9928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7"; + const G1_GENERATOR_MUL_BY_7_NEG_SERIALIZED_COMP: vector = x"78e0ffab866b3a9876bd01b8ecc66fcb86936277f425539a758dbbd32e2b0797"; #[test_only] - const G1_GENERATOR_MUL_BY_7_NEG_SERIALIZED_UNCOMP: vector = x"1928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb70973642f94c9b055f4e1d20812c1f91329ed2e3d71f635a72d599a679d0cda1320e597b4e1b24f735fed1381d767908f"; + const G1_GENERATOR_MUL_BY_7_NEG_SERIALIZED_UNCOMP: vector = x"78e0ffab866b3a9876bd01b8ecc66fcb86936277f425539a758dbbd32e2b0717a94da87797ec9fc471d6580ba12e83e9e22068876a90d4b6d7c200100674d999"; #[test(fx = @std)] fun test_g1affine(fx: signer) { @@ -127,10 +398,8 @@ module std::bn254_algebra { // Serialization/deserialization. assert!(G1_GENERATOR_SERIALIZED_UNCOMP == serialize(&generator), 1); assert!(G1_GENERATOR_SERIALIZED_COMP == serialize(&generator), 1); - let generator_from_comp = std::option::extract(&mut deserialize(&G1_GENERATOR_SERIALIZED_COMP - )); - let generator_from_uncomp = std::option::extract(&mut deserialize(&G1_GENERATOR_SERIALIZED_UNCOMP - )); + let generator_from_comp = std::option::extract(&mut deserialize(&G1_GENERATOR_SERIALIZED_COMP)); + let generator_from_uncomp = std::option::extract(&mut deserialize(&G1_GENERATOR_SERIALIZED_UNCOMP)); assert!(eq(&generator, &generator_from_comp), 1); assert!(eq(&generator, &generator_from_uncomp), 1); @@ -220,32 +489,32 @@ module std::bn254_algebra { // Subtraction. assert!(eq(&point_9g, &sub(&point_2g, &point_minus_7g_calc)), 1); - // Hash-to-group using suite `BLS12381G1_XMD:SHA-256_SSWU_RO_`. - // Test vectors source: https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-bls12381g1_xmdsha-256_sswu_ - let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_", &b""); - let expected = std::option::extract(&mut deserialize(&x"052926add2207b76ca4fa57a8734416c8dc95e24501772c814278700eed6d1e4e8cf62d9c09db0fac349612b759e79a108ba738453bfed09cb546dbb0783dbb3a5f1f566ed67bb6be0e8c67e2e81a4cc68ee29813bb7994998f3eae0c9c6a265")); - assert!(eq(&expected, &actual), 1); - let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_", &b"abcdef0123456789"); - let expected = std::option::extract(&mut deserialize(&x"11e0b079dea29a68f0383ee94fed1b940995272407e3bb916bbf268c263ddd57a6a27200a784cbc248e84f357ce82d9803a87ae2caf14e8ee52e51fa2ed8eefe80f02457004ba4d486d6aa1f517c0889501dc7413753f9599b099ebcbbd2d709")); - assert!(eq(&expected, &actual), 1); + // // Hash-to-group using suite `BLS12381G1_XMD:SHA-256_SSWU_RO_`. + // // Test vectors source: https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-bls12381g1_xmdsha-256_sswu_ + // let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_", &b""); + // let expected = std::option::extract(&mut deserialize(&x"052926add2207b76ca4fa57a8734416c8dc95e24501772c814278700eed6d1e4e8cf62d9c09db0fac349612b759e79a108ba738453bfed09cb546dbb0783dbb3a5f1f566ed67bb6be0e8c67e2e81a4cc68ee29813bb7994998f3eae0c9c6a265")); + // assert!(eq(&expected, &actual), 1); + // let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_", &b"abcdef0123456789"); + // let expected = std::option::extract(&mut deserialize(&x"11e0b079dea29a68f0383ee94fed1b940995272407e3bb916bbf268c263ddd57a6a27200a784cbc248e84f357ce82d9803a87ae2caf14e8ee52e51fa2ed8eefe80f02457004ba4d486d6aa1f517c0889501dc7413753f9599b099ebcbbd2d709")); + // assert!(eq(&expected, &actual), 1); } #[test_only] - const G2_INF_SERIALIZED_UNCOMP: vector = x"400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + const G2_INF_SERIALIZED_COMP: vector = x"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040"; #[test_only] - const G2_INF_SERIALIZED_COMP: vector = x"c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + const G2_INF_SERIALIZED_UNCOMP: vector = x"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040"; #[test_only] - const G2_GENERATOR_SERIALIZED_UNCOMP: vector = x"13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801"; + const G2_GENERATOR_SERIALIZED_COMP: vector = x"edf692d95cbdde46ddda5ef7d422436779445c5e66006a42761e1f12efde0018c212f3aeb785e49712e7a9353349aaf1255dfb31b7bf60723a480d9293938e19"; #[test_only] - const G2_GENERATOR_SERIALIZED_COMP: vector = x"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8"; + const G2_GENERATOR_SERIALIZED_UNCOMP: vector = x"edf692d95cbdde46ddda5ef7d422436779445c5e66006a42761e1f12efde0018c212f3aeb785e49712e7a9353349aaf1255dfb31b7bf60723a480d9293938e19aa7dfa6601cce64c7bd3430c69e7d1e38f40cb8d8071ab4aeb6d8cdba55ec8125b9722d1dcdaac55f38eb37033314bbc95330c69ad999eec75f05f58d0890609"; #[test_only] - const G2_GENERATOR_MUL_BY_7_SERIALIZED_UNCOMP: vector = x"0d0273f6bf31ed37c3b8d68083ec3d8e20b5f2cc170fa24b9b5be35b34ed013f9a921f1cad1644d4bdb14674247234c8049cd1dbb2d2c3581e54c088135fef36505a6823d61b859437bfc79b617030dc8b40e32bad1fa85b9c0f368af6d38d3c05ecf93654b7a1885695aaeeb7caf41b0239dc45e1022be55d37111af2aecef87799638bec572de86a7437898efa702008b7ae4dbf802c17a6648842922c9467e460a71c88d393ee7af356da123a2f3619e80c3bdcc8e2b1da52f8cd9913ccdd"; + const G2_GENERATOR_MUL_BY_7_SERIALIZED_UNCOMP: vector = x"08b328aa2a1490c3892ae375ba53a257162f1cde012e70edf8fc27435ddc4b2255243646bade3e596dee466e51d40fbe631e55841e085d6ae2bd9a5a01ba03293f23144105e8212ed8df28ca0e8031d47b7a7de372b3ccee1750262af5ff921dd8e03503be1eedbaadf7e6c4a1be3670d14a46da5fafee7adbdeb2a6cdb7c803"; #[test_only] - const G2_GENERATOR_MUL_BY_7_SERIALIZED_COMP: vector = x"8d0273f6bf31ed37c3b8d68083ec3d8e20b5f2cc170fa24b9b5be35b34ed013f9a921f1cad1644d4bdb14674247234c8049cd1dbb2d2c3581e54c088135fef36505a6823d61b859437bfc79b617030dc8b40e32bad1fa85b9c0f368af6d38d3c"; + const G2_GENERATOR_MUL_BY_7_SERIALIZED_COMP: vector = x"08b328aa2a1490c3892ae375ba53a257162f1cde012e70edf8fc27435ddc4b2255243646bade3e596dee466e51d40fbe631e55841e085d6ae2bd9a5a01ba0329"; #[test_only] - const G2_GENERATOR_MUL_BY_7_NEG_SERIALIZED_UNCOMP: vector = x"0d0273f6bf31ed37c3b8d68083ec3d8e20b5f2cc170fa24b9b5be35b34ed013f9a921f1cad1644d4bdb14674247234c8049cd1dbb2d2c3581e54c088135fef36505a6823d61b859437bfc79b617030dc8b40e32bad1fa85b9c0f368af6d38d3c141418b3e4c84511f485fcc78b80b8bc623d6f3f1282e6da09f9c1860402272ba7129c72c4fcd2174f8ac87671053a8b1149639c79ffba82a4b71f73b11f186f8016a4686ab17ed0ec3d7bc6e476c6ee04c3f3c2d48b1d4ddfac073266ebddce"; + const G2_GENERATOR_MUL_BY_7_NEG_SERIALIZED_UNCOMP: vector = x"08b328aa2a1490c3892ae375ba53a257162f1cde012e70edf8fc27435ddc4b2255243646bade3e596dee466e51d40fbe631e55841e085d6ae2bd9a5a01ba032908da689711a4fe0db5ea489e82ea4fc3e1dd039e439283c911500bb77d4ed1126f1c47d5586d3381dfd28aa3efab4a278c0d3ba75696613d4ec17e3aa5969bac"; #[test_only] - const G2_GENERATOR_MUL_BY_7_NEG_SERIALIZED_COMP: vector = x"ad0273f6bf31ed37c3b8d68083ec3d8e20b5f2cc170fa24b9b5be35b34ed013f9a921f1cad1644d4bdb14674247234c8049cd1dbb2d2c3581e54c088135fef36505a6823d61b859437bfc79b617030dc8b40e32bad1fa85b9c0f368af6d38d3c"; + const G2_GENERATOR_MUL_BY_7_NEG_SERIALIZED_COMP: vector = x"08b328aa2a1490c3892ae375ba53a257162f1cde012e70edf8fc27435ddc4b2255243646bade3e596dee466e51d40fbe631e55841e085d6ae2bd9a5a01ba03a9"; #[test(fx = @std)] fun test_g2affine(fx: signer) { @@ -341,24 +610,25 @@ module std::bn254_algebra { // Subtraction. assert!(eq(&point_9g, &sub(&point_2g, &point_minus_7g_calc)), 1); - // Hash-to-group using suite `BLS12381G2_XMD:SHA-256_SSWU_RO_`. - // Test vectors source: https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-bls12381g2_xmdsha-256_sswu_ - let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_", &b""); - let expected = std::option::extract(&mut deserialize(&x"05cb8437535e20ecffaef7752baddf98034139c38452458baeefab379ba13dff5bf5dd71b72418717047f5b0f37da03d0141ebfbdca40eb85b87142e130ab689c673cf60f1a3e98d69335266f30d9b8d4ac44c1038e9dcdd5393faf5c41fb78a12424ac32561493f3fe3c260708a12b7c620e7be00099a974e259ddc7d1f6395c3c811cdd19f1e8dbf3e9ecfdcbab8d60503921d7f6a12805e72940b963c0cf3471c7b2a524950ca195d11062ee75ec076daf2d4bc358c4b190c0c98064fdd92")); - assert!(eq(&expected, &actual), 1); - let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_", &b"abcdef0123456789"); - let expected = std::option::extract(&mut deserialize(&x"190d119345b94fbd15497bcba94ecf7db2cbfd1e1fe7da034d26cbba169fb3968288b3fafb265f9ebd380512a71c3f2c121982811d2491fde9ba7ed31ef9ca474f0e1501297f68c298e9f4c0028add35aea8bb83d53c08cfc007c1e005723cd00bb5e7572275c567462d91807de765611490205a941a5a6af3b1691bfe596c31225d3aabdf15faff860cb4ef17c7c3be05571a0f8d3c08d094576981f4a3b8eda0a8e771fcdcc8ecceaf1356a6acf17574518acb506e435b639353c2e14827c8")); - assert!(eq(&expected, &actual), 1); + // // Hash-to-group using suite `BLS12381G2_XMD:SHA-256_SSWU_RO_`. + // // Test vectors source: https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-bls12381g2_xmdsha-256_sswu_ + // let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_", &b""); + // let expected = std::option::extract(&mut deserialize(&x"05cb8437535e20ecffaef7752baddf98034139c38452458baeefab379ba13dff5bf5dd71b72418717047f5b0f37da03d0141ebfbdca40eb85b87142e130ab689c673cf60f1a3e98d69335266f30d9b8d4ac44c1038e9dcdd5393faf5c41fb78a12424ac32561493f3fe3c260708a12b7c620e7be00099a974e259ddc7d1f6395c3c811cdd19f1e8dbf3e9ecfdcbab8d60503921d7f6a12805e72940b963c0cf3471c7b2a524950ca195d11062ee75ec076daf2d4bc358c4b190c0c98064fdd92")); + // assert!(eq(&expected, &actual), 1); + // let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_", &b"abcdef0123456789"); + // let expected = std::option::extract(&mut deserialize(&x"190d119345b94fbd15497bcba94ecf7db2cbfd1e1fe7da034d26cbba169fb3968288b3fafb265f9ebd380512a71c3f2c121982811d2491fde9ba7ed31ef9ca474f0e1501297f68c298e9f4c0028add35aea8bb83d53c08cfc007c1e005723cd00bb5e7572275c567462d91807de765611490205a941a5a6af3b1691bfe596c31225d3aabdf15faff860cb4ef17c7c3be05571a0f8d3c08d094576981f4a3b8eda0a8e771fcdcc8ecceaf1356a6acf17574518acb506e435b639353c2e14827c8")); + // assert!(eq(&expected, &actual), 1); } #[test_only] - const FQ12_ONE_SERIALIZED: vector = x"010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + const FQ12_ONE_SERIALIZED: vector = x"010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; #[test_only] - const GT_GENERATOR_SERIALIZED: vector = x"b68917caaa0543a808c53908f694d1b6e7b38de90ce9d83d505ca1ef1b442d2727d7d06831d8b2a7920afc71d8eb50120f17a0ea982a88591d9f43503e94a8f1abaf2e4589f65aafb7923c484540a868883432a5c60e75860b11e5465b1c9a08873ec29e844c1c888cb396933057ffdd541b03a5220eda16b2b3a6728ea678034ce39c6839f20397202d7c5c44bb68134f93193cec215031b17399577a1de5ff1f5b0666bdd8907c61a7651e4e79e0372951505a07fa73c25788db6eb8023519a5aa97b51f1cad1d43d8aabbff4dc319c79a58cafc035218747c2f75daf8f2fb7c00c44da85b129113173d4722f5b201b6b4454062e9ea8ba78c5ca3cadaf7238b47bace5ce561804ae16b8f4b63da4645b8457a93793cbd64a7254f150781019de87ee42682940f3e70a88683d512bb2c3fb7b2434da5dedbb2d0b3fb8487c84da0d5c315bdd69c46fb05d23763f2191aabd5d5c2e12a10b8f002ff681bfd1b2ee0bf619d80d2a795eb22f2aa7b85d5ffb671a70c94809f0dafc5b73ea2fb0657bae23373b4931bc9fa321e8848ef78894e987bff150d7d671aee30b3931ac8c50e0b3b0868effc38bf48cd24b4b811a2995ac2a09122bed9fd9fa0c510a87b10290836ad06c8203397b56a78e9a0c61c77e56ccb4f1bc3d3fcaea7550f3503efe30f2d24f00891cb45620605fcfaa4292687b3a7db7c1c0554a93579e889a121fd8f72649b2402996a084d2381c5043166673b3849e4fd1e7ee4af24aa8ed443f56dfd6b68ffde4435a92cd7a4ac3bc77e1ad0cb728606cf08bf6386e5410f"; + const GT_GENERATOR_SERIALIZED: vector = x"950e879d73631f5eb5788589eb5f7ef8d63e0a28de1ba00dfe4ca9ed3f252b264a8afb8eb4349db466ed1809ea4d7c39bdab7938821f1b0a00a295c72c2de002e01dbdfd0254134efcb1ec877395d25f937719b344adb1a58d129be2d6f2a9132b16a16e8ab030b130e69c69bd20b4c45986e6744a98314b5c1a0f50faa90b04dbaf9ef8aeeee3f50be31c210b598f4752f073987f9d35be8f6770d83f2ffc0af0d18dd9d2dbcdf943825acc12a7a9ddca45e629d962c6bd64908c3930a5541cfe2924dcc5580d5cef7a4bfdec90a91b59926f850d4a7923c01a5a5dbf0f5c094a2b9fb9d415820fa6b40c59bb9eade9c953407b0fc11da350a9d872cad6d3142974ca385854afdf5f583c04231adc5957c8914b6b20dc89660ed7c3bbe7c01d972be2d53ecdb27a1bcc16ac610db95aa7d237c8ff55a898cb88645a0e32530b23d7ebf5dafdd79b0f9c2ac4ba07ce18d3d16cf36e47916c4cae5d08d3afa813972c769e8514533e380c9443b3e1ee5c96fa3a0a73f301b626454721527bf900"; #[test_only] - const GT_GENERATOR_MUL_BY_7_SERIALIZED: vector = x"2041ea7b66c19680e2c0bb23245a71918753220b31f88a925aa9b1e192e7c188a0b365cb994b3ec5e809206117c6411242b940b10caa37ce734496b3b7c63578a0e3c076f9b31a7ca13a716262e0e4cda4ac994efb9e19893cbfe4d464b9210d099d808a08b3c4c3846e7529984899478639c4e6c46152ef49a04af9c8e6ff442d286c4613a3dac6a4bee4b40e1f6b030f2871dabe4223b250c3181ecd3bc6819004745aeb6bac567407f2b9c7d1978c45ee6712ae46930bc00638383f6696158bad488cbe7663d681c96c035481dbcf78e7a7fbaec3799163aa6914cef3365156bdc3e533a7c883d5974e3462ac6f19e3f9ce26800ae248a45c5f0dd3a48a185969224e6cd6af9a048241bdcac9800d94aeee970e08488fb961e36a769b6c185d185b4605dc9808517196bba9d00a3e37bca466c19187486db104ee03962d39fe473e276355618e44c965f05082bb027a7baa4bcc6d8c0775c1e8a481e77df36ddad91e75a982302937f543a11fe71922dcd4f46fe8f951f91cde412b359507f2b3b6df0374bfe55c9a126ad31ce254e67d64194d32d7955ec791c9555ea5a917fc47aba319e909de82da946eb36e12aff936708402228295db2712f2fc807c95092a86afd71220699df13e2d2fdf2857976cb1e605f72f1b2edabadba3ff05501221fe81333c13917c85d725ce92791e115eb0289a5d0b3330901bb8b0ed146abeb81381b7331f1c508fb14e057b05d8b0190a9e74a3d046dcd24e7ab747049945b3d8a120c4f6d88e67661b55573aa9b361367488a1ef7dffd967d64a1518"; + const GT_GENERATOR_MUL_BY_7_SERIALIZED: vector = x"533a587534641b568125fb273eac723c789a347eba9fcfd58d93742b3a0b782fd61bbf6202e04b8a33b6c60150fc62a071cb9ac9749a79031fd0dbb6dd8a1f2bcf1eb450bdf58fd3d124b2e0aaf878d11e96af3051631145a4bf0530b5d19d08bfe2d515530b9059525b2826587f7bf1f146bfd0e91e84411c7722abb7a8c418b20b1660b41e6949beff93b2b36303e74804df3335ab5bd85bfd7959d6fd3101d0bf6f681eb809c9a6c3544db7f81444e5c4fbdd0a31e920616ae08a2ab5f51ebf064c4906c7b29521e8fda3d704830a9a6ef5d455a85ae09216f55fd0e74d0aaf83ad81ba50218f08024910184c9ddab42a28f51912c779556c41c61aba2d075cfc020b61a18a9366c9f71658f00b44369bd86929725cf867a0b8fda694a7134a2790ebf19cbea1f972eedfd51787683f98d80895f630ff0bd513edebd5a217c00e231869178bd41cf47a7c0125379a3926353e5310a578066dfbb974424802b942a8b4f6338d7f9d8b9c4031dc46163a59c58ff503eca69b642398b5a1212b"; #[test_only] - const GT_GENERATOR_MUL_BY_7_NEG_SERIALIZED: vector = x"2041ea7b66c19680e2c0bb23245a71918753220b31f88a925aa9b1e192e7c188a0b365cb994b3ec5e809206117c6411242b940b10caa37ce734496b3b7c63578a0e3c076f9b31a7ca13a716262e0e4cda4ac994efb9e19893cbfe4d464b9210d099d808a08b3c4c3846e7529984899478639c4e6c46152ef49a04af9c8e6ff442d286c4613a3dac6a4bee4b40e1f6b030f2871dabe4223b250c3181ecd3bc6819004745aeb6bac567407f2b9c7d1978c45ee6712ae46930bc00638383f6696158bad488cbe7663d681c96c035481dbcf78e7a7fbaec3799163aa6914cef3365156bdc3e533a7c883d5974e3462ac6f19e3f9ce26800ae248a45c5f0dd3a48a185969224e6cd6af9a048241bdcac9800d94aeee970e08488fb961e36a769b6c184e92a4b9fa2366b1ae8ebdf5542fa1e0ec390c90df40a91e5261800581b5492bd9640d1c5352babc551d1a49998f4517312f55b4339272b28a3e6b0c7d182e2bb61bd7d72b29ae3696db8fafe32b904ab5d0764e46bf21f9a0c9a1f7bedc6b12b9f64820fc8b3fd4a26541472be3c9c93d784cdd53a059d1604bf3292fedd1babfb00398128e3241bc63a5a47b5e9207fcb0c88f7bfddc376a242c9f0c032ba28eec8670f1fa1d47567593b4571c983b8015df91cfa1241b7fb8a57e0e6e01145b98de017eccc2a66e83ced9d83119a505e552467838d35b8ce2f4d7cc9a894f6dee922f35f0e72b7e96f0879b0c8614d3f9e5f5618b5be9b82381628448641a8bb0fd1dffb16c70e6831d8d69f61f2a2ef9e90c421f7a5b1ce7a5d113c7eb01"; + const GT_GENERATOR_MUL_BY_7_NEG_SERIALIZED: vector = x"533a587534641b568125fb273eac723c789a347eba9fcfd58d93742b3a0b782fd61bbf6202e04b8a33b6c60150fc62a071cb9ac9749a79031fd0dbb6dd8a1f2bcf1eb450bdf58fd3d124b2e0aaf878d11e96af3051631145a4bf0530b5d19d08bfe2d515530b9059525b2826587f7bf1f146bfd0e91e84411c7722abb7a8c418b20b1660b41e6949beff93b2b36303e74804df3335ab5bd85bfd7959d6fd3101d0bf6f681eb809c9a6c3544db7f81444e5c4fbdd0a31e920616ae08a2ab5f51e88f6308f10c56da66be273c4b965fe8cc3e98bac609df5d796893c81a26616269879cf565c3bffac84c82858791ee4bca82d598c9c33893ed433f01a58943629eb007acdb5ea95a826017a51397a755327bda8178dd3f3bfc1ff78e3cbb9bc1cfdd5ecec24ef619a93578388bb52fa2e1ec0a878214f1fb91dcb1df48678c11887ee59c0ad74956770d6f6eb8f454afd23324c436335ab3f23333627fe0b1c2e8ebad423205893bcef3ed527608e3a8123ffbbf1c04164118e3b0e49bdac4205"; + #[test(fx = @std)] fun test_gt(fx: signer) { @@ -412,7 +682,7 @@ module std::bn254_algebra { } #[test_only] - use aptos_std::crypto_algebra::{zero, one, from_u64, eq, deserialize, serialize, neg, add, sub, mul, div, inv, rand_insecure, sqr, order, scalar_mul, multi_scalar_mul, double, hash_to, upcast, enable_cryptography_algebra_natives, pairing, multi_pairing, downcast, Element}; + use aptos_std::crypto_algebra::{zero, one, from_u64, eq, deserialize, serialize, neg, add, sub, mul, div, inv, rand_insecure, sqr, order, scalar_mul, multi_scalar_mul, double, upcast, enable_cryptography_algebra_natives, pairing, multi_pairing, downcast, Element}; #[test_only] const FR_VAL_0_SERIALIZED_LSB: vector = x"0000000000000000000000000000000000000000000000000000000000000000"; @@ -423,7 +693,7 @@ module std::bn254_algebra { #[test_only] const FR_VAL_7_SERIALIZED_MSB: vector = x"0000000000000000000000000000000000000000000000000000000000000007"; #[test_only] - const FR_VAL_7_NEG_SERIALIZED_LSB: vector = x"fafffffffefffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73"; + const FR_VAL_7_NEG_SERIALIZED_LSB: vector = x"faffffef93f5e1439170b97948e833285d588181b64550b829a031e1724e6430"; #[test(fx = @std)] fun test_fr(fx: signer) { @@ -485,6 +755,78 @@ module std::bn254_algebra { assert!(eq(&mul(&val_x, &val_x), &sqr(&val_x)), 1); } + const FQ_R_SERIALIZED: vector = x"47fd7cd8168c203c8dca7168916a81975d588181b64550b829a031e1724e6430"; + #[test_only] + const FQ_VAL_0_SERIALIZED_LSB: vector = x"0000000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const FQ_VAL_1_SERIALIZED_LSB: vector = x"0100000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const FQ_VAL_7_SERIALIZED_LSB: vector = x"0700000000000000000000000000000000000000000000000000000000000000"; + #[test_only] + const FQ_VAL_7_SERIALIZED_MSB: vector = x"0000000000000000000000000000000000000000000000000000000000000007"; + #[test_only] + const FQ_VAL_7_NEG_SERIALIZED_LSB: vector = x"40fd7cd8168c203c8dca7168916a81975d588181b64550b829a031e1724e6430"; + + #[test(fx = @std)] + fun test_fq(fx: signer) { + enable_cryptography_algebra_natives(&fx); + + // Constants. + assert!(FQ_R_SERIALIZED == order(), 1); + + // Serialization/deserialization. + let val_0 = zero(); + let val_1 = one(); + assert!(FQ_VAL_0_SERIALIZED_LSB == serialize(&val_0), 1); + assert!(FQ_VAL_1_SERIALIZED_LSB == serialize(&val_1), 1); + let val_7 = from_u64(7); + let val_7_2nd = std::option::extract(&mut deserialize(&FQ_VAL_7_SERIALIZED_LSB)); + let val_7_3rd = std::option::extract(&mut deserialize(&FQ_VAL_7_SERIALIZED_MSB)); + assert!(eq(&val_7, &val_7_2nd), 1); + assert!(eq(&val_7, &val_7_3rd), 1); + assert!(FQ_VAL_7_SERIALIZED_LSB == serialize(&val_7), 1); + assert!(FQ_VAL_7_SERIALIZED_MSB == serialize(&val_7), 1); + + // Deserialization should fail if given a byte array of right size but the value is not a member. + assert!(std::option::is_none(&deserialize(&x"01000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73")), 1); + assert!(std::option::is_none(&deserialize(&x"73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001")), 1); + + // Deserialization should fail if given a byte array of wrong size. + assert!(std::option::is_none(&deserialize(&x"01000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed7300")), 1); + assert!(std::option::is_none(&deserialize(&x"0073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001")), 1); + assert!(std::option::is_none(&deserialize(&x"ffff")), 1); + assert!(std::option::is_none(&deserialize(&x"ffff")), 1); + + // Negation. + let val_minus_7 = neg(&val_7); + assert!(FQ_VAL_7_NEG_SERIALIZED_LSB == serialize(&val_minus_7), 1); + + // Addition. + let val_9 = from_u64(9); + let val_2 = from_u64(2); + assert!(eq(&val_2, &add(&val_minus_7, &val_9)), 1); + + // Subtraction. + assert!(eq(&val_9, &sub(&val_2, &val_minus_7)), 1); + + // Multiplication. + let val_63 = from_u64(63); + assert!(eq(&val_63, &mul(&val_7, &val_9)), 1); + + // division. + let val_0 = from_u64(0); + assert!(eq(&val_7, &std::option::extract(&mut div(&val_63, &val_9))), 1); + assert!(std::option::is_none(&div(&val_63, &val_0)), 1); + + // Inversion. + assert!(eq(&val_minus_7, &neg(&val_7)), 1); + assert!(std::option::is_none(&inv(&val_0)), 1); + + // Squaring. + let val_x = rand_insecure(); + assert!(eq(&mul(&val_x, &val_x), &sqr(&val_x)), 1); + } + #[test(fx = @std)] fun test_pairing(fx: signer) { enable_cryptography_algebra_natives(&fx); @@ -557,11 +899,11 @@ module std::bn254_algebra { #[test_only] /// The maximum number of `G1` elements that can be created in a transaction, - /// calculated by the current memory limit (1MB) and the in-mem G1 representation size (144 bytes per element). + /// calculated by the current memory limit (1MB) and the in-mem G1 representation size (32*3 bytes per element). const G1_NUM_MAX_NUMERATOR: u64 = 1048576; // TODO(#9330) #[test_only] - const G1_NUM_MAX_DENOMINATOR: u64 = 144; // TODO(#9330) + const G1_NUM_MAX_DENOMINATOR: u64 = 96; // TODO(#9330) #[test(fx = @std)] fun test_memory_limit(fx: signer) { diff --git a/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs b/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs index c31c44fb664d9..ee928543752ab 100644 --- a/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs +++ b/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs @@ -213,7 +213,7 @@ fn serialize_internal_bn254( buf.reverse(); Ok(smallvec![Value::vector_u8(buf)]) }, - (BN254Structure::BN254Fq, BN254SerializationFormat::BN254FrLsb) => { + (BN254Structure::BN254Fq, BN254SerializationFormat::BN254FqLsb) => { let handle = safely_pop_arg!(args, u64) as usize; safe_borrow_element!(context, handle, ark_bn254::Fq, element_ptr, element); let mut buf = vec![]; From 9aaa4292d439fd3e2e884ae360eb8434f0eb85a1 Mon Sep 17 00:00:00 2001 From: zhoujunma Date: Sun, 3 Dec 2023 19:17:30 -0800 Subject: [PATCH 07/21] ark_bn254 benches and derived gas parameters (#2) * [feat][aptos-stdlib] crypto algebra bn254 Signed-off-by: caojiafeng * scripts: fix update_algebra_gas_params.py Signed-off-by: caojiafeng * add bn254 to default features to make unit test pass * fix a bug mentioned in the comments * initial * update * initial gas param * benches for fq and fq2 * it compiles * gas script now also specifies quantity types * update scripts --------- Signed-off-by: caojiafeng Co-authored-by: caojiafeng --- Cargo.lock | 1 + .../src/gas_schedule/aptos_framework.rs | 181 +++--- crates/aptos-crypto/Cargo.toml | 5 + crates/aptos-crypto/benches/ark_bn254.rs | 532 ++++++++++++++++++ crates/aptos-crypto/benches/bench_utils.rs | 178 ++++++ ... => update_bls12381_algebra_gas_params.py} | 19 +- .../update_bn254_algebra_gas_params.py | 147 +++++ 7 files changed, 969 insertions(+), 94 deletions(-) create mode 100644 crates/aptos-crypto/benches/ark_bn254.rs create mode 100644 crates/aptos-crypto/benches/bench_utils.rs rename scripts/algebra-gas/{update_algebra_gas_params.py => update_bls12381_algebra_gas_params.py} (89%) create mode 100755 scripts/algebra-gas/update_bn254_algebra_gas_params.py diff --git a/Cargo.lock b/Cargo.lock index 3b1cce5b82500..79701f6ba7e8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -926,6 +926,7 @@ dependencies = [ "anyhow", "aptos-crypto-derive", "ark-bls12-381", + "ark-bn254", "ark-ec", "ark-ff", "ark-serialize", diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs index 24dcb7b9a452b..cc315caf46f7e 100644 --- a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs +++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs @@ -16,93 +16,98 @@ crate::gas_schedule::macros::define_gas_parameters!( [account_create_address_base: InternalGas, "account.create_address.base", 6000], [account_create_signer_base: InternalGas, "account.create_signer.base", 6000], - [algebra_ark_bn254_fq2_add: InternalGas, { 12.. => "algebra.ark_bn254_fq2_add" }, 36380], - [algebra_ark_bn254_fq2_clone: InternalGas, { 12.. => "algebra.ark_bn254_fq2_clone" }, 4220], - [algebra_ark_bn254_fq2_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq2_deser" }, 223600], - [algebra_ark_bn254_fq2_div: InternalGas, { 12.. => "algebra.ark_bn254_fq2_div" }, 5016260], - [algebra_ark_bn254_fq2_eq: InternalGas, { 12.. => "algebra.ark_bn254_fq2_eq" }, 14520], - [algebra_ark_bn254_fq2_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fq2_from_u64" }, 18020], - [algebra_ark_bn254_fq2_inv: InternalGas, { 12.. => "algebra.ark_bn254_fq2_inv" }, 4010460], - [algebra_ark_bn254_fq2_mul: InternalGas, { 12.. => "algebra.ark_bn254_fq2_mul" }, 997720], - [algebra_ark_bn254_fq2_neg: InternalGas, { 12.. => "algebra.ark_bn254_fq2_neg" }, 23620], - [algebra_ark_bn254_fq2_one: InternalGas, { 12.. => "algebra.ark_bn254_fq2_one" }, 220], - [algebra_ark_bn254_fq2_pow_u256: InternalGas, { 12.. => "algebra.ark_bn254_fq2_pow_u256" }, 293284140], - [algebra_ark_bn254_fq2_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fq2_serialize" }, 161560], - [algebra_ark_bn254_fq2_square: InternalGas, { 12.. => "algebra.ark_bn254_fq2_square" }, 702900], - [algebra_ark_bn254_fq2_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq2_sub" }, 35160], - [algebra_ark_bn254_fq2_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq2_zero" }, 4220], - [algebra_ark_bn254_fq12_add: InternalGas, { 12.. => "algebra.ark_bn254_fq12_add" }, 36380], - [algebra_ark_bn254_fq12_clone: InternalGas, { 12.. => "algebra.ark_bn254_fq12_clone" }, 4220], - [algebra_ark_bn254_fq12_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq12_deser" }, 223600], - [algebra_ark_bn254_fq12_div: InternalGas, { 12.. => "algebra.ark_bn254_fq12_div" }, 5016260], - [algebra_ark_bn254_fq12_eq: InternalGas, { 12.. => "algebra.ark_bn254_fq12_eq" }, 14520], - [algebra_ark_bn254_fq12_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fq12_from_u64" }, 18020], - [algebra_ark_bn254_fq12_inv: InternalGas, { 12.. => "algebra.ark_bn254_fq12_inv" }, 4010460], - [algebra_ark_bn254_fq12_mul: InternalGas, { 12.. => "algebra.ark_bn254_fq12_mul" }, 997720], - [algebra_ark_bn254_fq12_neg: InternalGas, { 12.. => "algebra.ark_bn254_fq12_neg" }, 23620], - [algebra_ark_bn254_fq12_one: InternalGas, { 12.. => "algebra.ark_bn254_fq12_one" }, 220], - [algebra_ark_bn254_fq12_pow_u256: InternalGas, { 12.. => "algebra.ark_bn254_fq12_pow_u256" }, 293284140], - [algebra_ark_bn254_fq12_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fq12_serialize" }, 161560], - [algebra_ark_bn254_fq12_square: InternalGas, { 12.. => "algebra.ark_bn254_fq12_square" }, 702900], - [algebra_ark_bn254_fq12_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq12_sub" }, 35160], - [algebra_ark_bn254_fq12_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq12_zero" }, 4220], - [algebra_ark_bn254_fr_add: InternalGas, { 12.. => "algebra.ark_bn254_fr_add" }, 4220], - [algebra_ark_bn254_fr_deser: InternalGas, { 12.. => "algebra.ark_bn254_fr_deser" }, 15040], - [algebra_ark_bn254_fr_div: InternalGas, { 12.. => "algebra.ark_bn254_fr_div" }, 1188800], - [algebra_ark_bn254_fr_eq: InternalGas, { 12.. => "algebra.ark_bn254_fr_eq" }, 4240], - [algebra_ark_bn254_fr_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fr_from_u64" }, 9880], - [algebra_ark_bn254_fr_inv: InternalGas, { 12.. => "algebra.ark_bn254_fr_inv" }, 1172200], - [algebra_ark_bn254_fr_mul: InternalGas, { 12.. => "algebra.ark_bn254_fr_mul" }, 10040], - [algebra_ark_bn254_fr_neg: InternalGas, { 12.. => "algebra.ark_bn254_fr_neg" }, 4260], - [algebra_ark_bn254_fr_one: InternalGas, { 12.. => "algebra.ark_bn254_fr_one" }, 4220], - [algebra_ark_bn254_fr_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fr_serialize" }, 22060], - [algebra_ark_bn254_fr_square: InternalGas, { 12.. => "algebra.ark_bn254_fr_square" }, 9500], - [algebra_ark_bn254_fr_sub: InternalGas, { 12.. => "algebra.ark_bn254_fr_sub" }, 5800], - [algebra_ark_bn254_fr_zero: InternalGas, { 12.. => "algebra.ark_bn254_fr_zero" }, 4220], - [algebra_ark_bn254_fq_add: InternalGas, { 12.. => "algebra.ark_bn254_fq_add" }, 4220], - [algebra_ark_bn254_fq_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq_deser" }, 15040], - [algebra_ark_bn254_fq_div: InternalGas, { 12.. => "algebra.ark_bn254_fq_div" }, 1188800], - [algebra_ark_bn254_fq_eq: InternalGas, { 12.. => "algebra.ark_bn254_fq_eq" }, 4240], - [algebra_ark_bn254_fq_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fq_from_u64" }, 9880], - [algebra_ark_bn254_fq_inv: InternalGas, { 12.. => "algebra.ark_bn254_fq_inv" }, 1172200], - [algebra_ark_bn254_fq_mul: InternalGas, { 12.. => "algebra.ark_bn254_fq_mul" }, 10040], - [algebra_ark_bn254_fq_neg: InternalGas, { 12.. => "algebra.ark_bn254_fq_neg" }, 4260], - [algebra_ark_bn254_fq_one: InternalGas, { 12.. => "algebra.ark_bn254_fq_one" }, 4220], - [algebra_ark_bn254_fq_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fq_serialize" }, 22060], - [algebra_ark_bn254_fq_square: InternalGas, { 12.. => "algebra.ark_bn254_fq_square" }, 9500], - [algebra_ark_bn254_fq_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq_sub" }, 5800], - [algebra_ark_bn254_fq_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq_zero" }, 4220], - [algebra_ark_bn254_g1_affine_deser_comp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_deser_comp" }, 20591980], - [algebra_ark_bn254_g1_affine_deser_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_deser_uncomp" }, 14412760], - [algebra_ark_bn254_g1_affine_serialize_comp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_serialize_comp" }, 40280], - [algebra_ark_bn254_g1_affine_serialize_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_serialize_uncomp" }, 48660], - [algebra_ark_bn254_g1_proj_add: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_add" }, 216120], - [algebra_ark_bn254_g1_proj_double: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_double" }, 105280], - [algebra_ark_bn254_g1_proj_eq: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_eq" }, 100700], - [algebra_ark_bn254_g1_proj_generator: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_generator" }, 220], - [algebra_ark_bn254_g1_proj_infinity: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_infinity" }, 220], - [algebra_ark_bn254_g1_proj_neg: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_neg" }, 220], - [algebra_ark_bn254_g1_proj_scalar_mul: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_scalar_mul" }, 50470420], - [algebra_ark_bn254_g1_proj_sub: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_sub" }, 222940], - [algebra_ark_bn254_g1_proj_to_affine: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_to_affine" }, 2420700], - [algebra_ark_bn254_g2_affine_deser_comp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_deser_comp" }, 41201360], - [algebra_ark_bn254_g2_affine_deser_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_deser_uncomp" }, 20359580], - [algebra_ark_bn254_g2_affine_serialize_comp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_serialize_comp" }, 67560], - [algebra_ark_bn254_g2_affine_serialize_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_serialize_uncomp" }, 84340], - [algebra_ark_bn254_g2_proj_add: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_add" }, 648020], - [algebra_ark_bn254_g2_proj_double: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_double" }, 296780], - [algebra_ark_bn254_g2_proj_eq: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_eq" }, 303100], - [algebra_ark_bn254_g2_proj_generator: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_generator" }, 220], - [algebra_ark_bn254_g2_proj_infinity: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_infinity" }, 220], - [algebra_ark_bn254_g2_proj_neg: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_neg" }, 220], - [algebra_ark_bn254_g2_proj_scalar_mul: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_scalar_mul" }, 150530160], - [algebra_ark_bn254_g2_proj_sub: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_sub" }, 657380], - [algebra_ark_bn254_g2_proj_to_affine: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_to_affine" }, 2577140], - [algebra_ark_bn254_multi_pairing_base: InternalGas, { 12.. => "algebra.ark_bn254_multi_pairing_base" }, 179972980], - [algebra_ark_bn254_multi_pairing_per_pair: InternalGasPerArg, { 12.. => "algebra.ark_bn254_multi_pairing_per_pair" }, 92052840], - [algebra_ark_bn254_pairing: InternalGas, { 12.. => "algebra.ark_bn254_pairing" }, 296644400], - - // Algebra gas parameters begin. + // BN254 algebra gas parameters begin. + // Generated at time 1701559125.5498126 by `scripts/algebra-gas/update_bn254_algebra_gas_params.py` with gas_per_ns=209.10511688369482. + [algebra_ark_bn254_fq12_add: InternalGas, { 12.. => "algebra.ark_bn254_fq12_add" }, 4_406], + [algebra_ark_bn254_fq12_clone: InternalGas, { 12.. => "algebra.ark_bn254_fq12_clone" }, 4_392], + [algebra_ark_bn254_fq12_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq12_deser" }, 129_063], + [algebra_ark_bn254_fq12_div: InternalGas, { 12.. => "algebra.ark_bn254_fq12_div" }, 2_813_602], + [algebra_ark_bn254_fq12_eq: InternalGas, { 12.. => "algebra.ark_bn254_fq12_eq" }, 12_142], + [algebra_ark_bn254_fq12_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fq12_from_u64" }, 14_463], + [algebra_ark_bn254_fq12_inv: InternalGas, { 12.. => "algebra.ark_bn254_fq12_inv" }, 2_168_418], + [algebra_ark_bn254_fq12_mul: InternalGas, { 12.. => "algebra.ark_bn254_fq12_mul" }, 643_914], + [algebra_ark_bn254_fq12_neg: InternalGas, { 12.. => "algebra.ark_bn254_fq12_neg" }, 13_311], + [algebra_ark_bn254_fq12_one: InternalGas, { 12.. => "algebra.ark_bn254_fq12_one" }, 209], + [algebra_ark_bn254_fq12_pow_u256: InternalGas, { 12.. => "algebra.ark_bn254_fq12_pow_u256" }, 192_871_746], + [algebra_ark_bn254_fq12_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fq12_serialize" }, 117_336], + [algebra_ark_bn254_fq12_square: InternalGas, { 12.. => "algebra.ark_bn254_fq12_square" }, 468_955], + [algebra_ark_bn254_fq12_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq12_sub" }, 30_497], + [algebra_ark_bn254_fq12_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq12_zero" }, 209], + [algebra_ark_bn254_fq2_add: InternalGas, { 12.. => "algebra.ark_bn254_fq2_add" }, 4_417], + [algebra_ark_bn254_fq2_clone: InternalGas, { 12.. => "algebra.ark_bn254_fq2_clone" }, 4_318], + [algebra_ark_bn254_fq2_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq2_deser" }, 25_524], + [algebra_ark_bn254_fq2_div: InternalGas, { 12.. => "algebra.ark_bn254_fq2_div" }, 1_183_329], + [algebra_ark_bn254_fq2_eq: InternalGas, { 12.. => "algebra.ark_bn254_fq2_eq" }, 4_393], + [algebra_ark_bn254_fq2_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fq2_from_u64" }, 14_227], + [algebra_ark_bn254_fq2_inv: InternalGas, { 12.. => "algebra.ark_bn254_fq2_inv" }, 1_161_471], + [algebra_ark_bn254_fq2_mul: InternalGas, { 12.. => "algebra.ark_bn254_fq2_mul" }, 22_085], + [algebra_ark_bn254_fq2_neg: InternalGas, { 12.. => "algebra.ark_bn254_fq2_neg" }, 4_319], + [algebra_ark_bn254_fq2_one: InternalGas, { 12.. => "algebra.ark_bn254_fq2_one" }, 209], + [algebra_ark_bn254_fq2_pow_u256: InternalGas, { 12.. => "algebra.ark_bn254_fq2_pow_u256" }, 6_265_467], + [algebra_ark_bn254_fq2_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fq2_serialize" }, 44_735], + [algebra_ark_bn254_fq2_square: InternalGas, { 12.. => "algebra.ark_bn254_fq2_square" }, 23_962], + [algebra_ark_bn254_fq2_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq2_sub" }, 8_116], + [algebra_ark_bn254_fq2_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq2_zero" }, 209], + [algebra_ark_bn254_fq_add: InternalGas, { 12.. => "algebra.ark_bn254_fq_add" }, 4_373], + [algebra_ark_bn254_fq_clone: InternalGas, { 12.. => "algebra.ark_bn254_fq_clone" }, 4_313], + [algebra_ark_bn254_fq_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq_deser" }, 17_588], + [algebra_ark_bn254_fq_div: InternalGas, { 12.. => "algebra.ark_bn254_fq_div" }, 1_140_544], + [algebra_ark_bn254_fq_eq: InternalGas, { 12.. => "algebra.ark_bn254_fq_eq" }, 4_373], + [algebra_ark_bn254_fq_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fq_from_u64" }, 14_137], + [algebra_ark_bn254_fq_inv: InternalGas, { 12.. => "algebra.ark_bn254_fq_inv" }, 1_136_577], + [algebra_ark_bn254_fq_mul: InternalGas, { 12.. => "algebra.ark_bn254_fq_mul" }, 10_050], + [algebra_ark_bn254_fq_neg: InternalGas, { 12.. => "algebra.ark_bn254_fq_neg" }, 4_314], + [algebra_ark_bn254_fq_one: InternalGas, { 12.. => "algebra.ark_bn254_fq_one" }, 209], + [algebra_ark_bn254_fq_pow_u256: InternalGas, { 12.. => "algebra.ark_bn254_fq_pow_u256" }, 2_081_451], + [algebra_ark_bn254_fq_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fq_serialize" }, 25_938], + [algebra_ark_bn254_fq_square: InternalGas, { 12.. => "algebra.ark_bn254_fq_square" }, 4_314], + [algebra_ark_bn254_fq_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq_sub" }, 6_148], + [algebra_ark_bn254_fq_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq_zero" }, 209], + [algebra_ark_bn254_fr_add: InternalGas, { 12.. => "algebra.ark_bn254_fr_add" }, 4_377], + [algebra_ark_bn254_fr_deser: InternalGas, { 12.. => "algebra.ark_bn254_fr_deser" }, 16_722], + [algebra_ark_bn254_fr_div: InternalGas, { 12.. => "algebra.ark_bn254_fr_div" }, 1_217_943], + [algebra_ark_bn254_fr_eq: InternalGas, { 12.. => "algebra.ark_bn254_fr_eq" }, 4_396], + [algebra_ark_bn254_fr_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fr_from_u64" }, 13_485], + [algebra_ark_bn254_fr_inv: InternalGas, { 12.. => "algebra.ark_bn254_fr_inv" }, 1_209_015], + [algebra_ark_bn254_fr_mul: InternalGas, { 12.. => "algebra.ark_bn254_fr_mul" }, 9_867], + [algebra_ark_bn254_fr_neg: InternalGas, { 12.. => "algebra.ark_bn254_fr_neg" }, 4_314], + [algebra_ark_bn254_fr_one: InternalGas, { 12.. => "algebra.ark_bn254_fr_one" }, 0], + [algebra_ark_bn254_fr_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fr_serialize" }, 25_749], + [algebra_ark_bn254_fr_square: InternalGas, { 12.. => "algebra.ark_bn254_fr_square" }, 4_311], + [algebra_ark_bn254_fr_sub: InternalGas, { 12.. => "algebra.ark_bn254_fr_sub" }, 10_370], + [algebra_ark_bn254_fr_zero: InternalGas, { 12.. => "algebra.ark_bn254_fr_zero" }, 209], + [algebra_ark_bn254_g1_affine_deser_comp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_deser_comp" }, 23_497_333], + [algebra_ark_bn254_g1_affine_deser_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_deser_uncomp" }, 21_528_706], + [algebra_ark_bn254_g1_affine_serialize_comp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_serialize_comp" }, 44_924], + [algebra_ark_bn254_g1_affine_serialize_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_serialize_uncomp" }, 58_820], + [algebra_ark_bn254_g1_proj_add: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_add" }, 106_501], + [algebra_ark_bn254_g1_proj_double: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_double" }, 63_682], + [algebra_ark_bn254_g1_proj_eq: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_eq" }, 53_021], + [algebra_ark_bn254_g1_proj_generator: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_generator" }, 209], + [algebra_ark_bn254_g1_proj_infinity: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_infinity" }, 209], + [algebra_ark_bn254_g1_proj_neg: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_neg" }, 209], + [algebra_ark_bn254_g1_proj_scalar_mul: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_scalar_mul" }, 26_456_386], + [algebra_ark_bn254_g1_proj_sub: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_sub" }, 106_903], + [algebra_ark_bn254_g1_proj_to_affine: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_to_affine" }, 6_340], + [algebra_ark_bn254_g2_affine_deser_comp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_deser_comp" }, 67_710_223], + [algebra_ark_bn254_g2_affine_deser_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_deser_uncomp" }, 60_677_591], + [algebra_ark_bn254_g2_affine_serialize_comp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_serialize_comp" }, 69_214], + [algebra_ark_bn254_g2_affine_serialize_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_serialize_uncomp" }, 98_505], + [algebra_ark_bn254_g2_proj_add: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_add" }, 318_234], + [algebra_ark_bn254_g2_proj_double: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_double" }, 158_874], + [algebra_ark_bn254_g2_proj_eq: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_eq" }, 141_359], + [algebra_ark_bn254_g2_proj_generator: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_generator" }, 209], + [algebra_ark_bn254_g2_proj_infinity: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_infinity" }, 209], + [algebra_ark_bn254_g2_proj_neg: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_neg" }, 209], + [algebra_ark_bn254_g2_proj_scalar_mul: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_scalar_mul" }, 76_395_801], + [algebra_ark_bn254_g2_proj_sub: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_sub" }, 321_727], + [algebra_ark_bn254_g2_proj_to_affine: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_to_affine" }, 1_251_909], + [algebra_ark_bn254_multi_pairing_base: InternalGas, { 12.. => "algebra.ark_bn254_multi_pairing_base" }, 127_794_596], + [algebra_ark_bn254_multi_pairing_per_pair: InternalGasPerArg, { 12.. => "algebra.ark_bn254_multi_pairing_per_pair" }, 67_624_587], + [algebra_ark_bn254_pairing: InternalGas, { 12.. => "algebra.ark_bn254_pairing" }, 209_703_839], + // BN254 algebra gas parameters end. + + // BLS12-381 algebra gas parameters begin. // Generated at time 1680606720.0709136 by `scripts/algebra-gas/update_algebra_gas_params.py` with gas_per_ns=10.23. [algebra_ark_bls12_381_fq12_add: InternalGas, { 8.. => "algebra.ark_bls12_381_fq12_add" }, 36380], [algebra_ark_bls12_381_fq12_clone: InternalGas, { 8.. => "algebra.ark_bls12_381_fq12_clone" }, 4220], @@ -165,7 +170,7 @@ crate::gas_schedule::macros::define_gas_parameters!( [algebra_ark_h2c_bls12381g1_xmd_sha256_sswu_per_msg_byte: InternalGasPerByte, { 8.. => "algebra.ark_h2c_bls12381g1_xmd_sha256_sswu_per_msg_byte" }, 960], [algebra_ark_h2c_bls12381g2_xmd_sha256_sswu_base: InternalGas, { 8.. => "algebra.ark_h2c_bls12381g2_xmd_sha256_sswu_base" }, 135460040], [algebra_ark_h2c_bls12381g2_xmd_sha256_sswu_per_msg_byte: InternalGasPerByte, { 8.. => "algebra.ark_h2c_bls12381g2_xmd_sha256_sswu_per_msg_byte" }, 960], - // Algebra gas parameters end. + // BLS12-381 algebra gas parameters end. [bls12381_base: InternalGas, "bls12381.base", 3000], diff --git a/crates/aptos-crypto/Cargo.toml b/crates/aptos-crypto/Cargo.toml index ab45c4a24b312..1d86e14fd9725 100644 --- a/crates/aptos-crypto/Cargo.toml +++ b/crates/aptos-crypto/Cargo.toml @@ -54,6 +54,7 @@ x25519-dalek = { workspace = true } [dev-dependencies] ark-bls12-381 = { workspace = true } +ark-bn254 = { workspace = true } ark-serialize = { workspace = true } ark-std = { workspace = true } bitvec = { workspace = true } @@ -81,6 +82,10 @@ harness = false name = "bls12381" harness = false +[[bench]] +name = "ark_bn254" +harness = false + [[bench]] name = "ed25519" harness = false diff --git a/crates/aptos-crypto/benches/ark_bn254.rs b/crates/aptos-crypto/benches/ark_bn254.rs new file mode 100644 index 0000000000000..7a55a72e5aca8 --- /dev/null +++ b/crates/aptos-crypto/benches/ark_bn254.rs @@ -0,0 +1,532 @@ +// Copyright © Aptos Foundation + +// Copyright (c) Aptos +// SPDX-License-Identifier: Apache-2.0 + +#[macro_use] +extern crate criterion; + +use ark_bn254::{Fq, Fq2, Fq12, Fr, G1Affine, G1Projective, G2Affine, G2Projective}; +use ark_ec::{ + pairing::Pairing, short_weierstrass::Projective, AffineRepr, CurveGroup, + Group, +}; +use ark_ff::{Field, One, UniformRand, Zero}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_std::test_rng; +use criterion::{BenchmarkId, Criterion}; +use std::ops::{Add, Div, Mul, Neg}; +use crate::bench_utils::{bench_function_add, bench_function_clone, bench_function_deser_comp, bench_function_deser_uncomp, bench_function_div, bench_function_double, bench_function_eq, bench_function_from_u64, bench_function_inv, bench_function_mul, bench_function_neg, bench_function_pow_u256, bench_function_serialize_uncomp, bench_function_square, bench_function_sub}; + +mod bench_utils; + +fn msm_all_bench_cases() -> Vec { + let series_until_65 = (1..65).step_by(2); + let series_until_129 = (64..129).step_by(4); + let series_until_257 = (129..257).step_by(8); + series_until_65 + .chain(series_until_129) + .chain(series_until_257) + .collect::>() +} + +macro_rules! rand { + ($typ:ty) => {{ + <$typ>::rand(&mut test_rng()) + }}; +} + +macro_rules! serialize { + ($obj:expr, $method:ident) => {{ + let mut buf = vec![]; + $obj.$method(&mut buf).unwrap(); + buf + }}; +} + +fn bench_group(c: &mut Criterion) { + let mut group = c.benchmark_group("ark_bn254"); + + group.bench_function("fr_add", bench_function_add::); + group.bench_function("fr_clone", bench_function_clone::); + group.bench_function("fr_deser", bench_function_deser_uncomp::); + group.bench_function("fr_div", bench_function_div::); + group.bench_function("fr_double", bench_function_double::); + group.bench_function("fr_eq", bench_function_eq::); + group.bench_function("fr_from_u64", bench_function_from_u64::); + group.bench_function("fr_inv", bench_function_inv::); + group.bench_function("fr_mul", bench_function_mul::); + group.bench_function("fr_neg", bench_function_neg::); + group.bench_function("fr_pow_u256", bench_function_pow_u256::); + group.bench_function("fr_serialize", bench_function_serialize_uncomp::); + group.bench_function("fr_square", bench_function_square::); + group.bench_function("fr_sub", bench_function_sub::); + + group.bench_function("fq_add", bench_function_add::); + group.bench_function("fq_clone", bench_function_clone::); + group.bench_function("fq_deser", bench_function_deser_uncomp::); + group.bench_function("fq_div", bench_function_div::); + group.bench_function("fq_double", bench_function_double::); + group.bench_function("fq_eq", bench_function_eq::); + group.bench_function("fq_from_u64", bench_function_from_u64::); + group.bench_function("fq_inv", bench_function_inv::); + group.bench_function("fq_mul", bench_function_mul::); + group.bench_function("fq_neg", bench_function_neg::); + group.bench_function("fq_pow_u256", bench_function_pow_u256::); + group.bench_function("fq_serialize", bench_function_serialize_uncomp::); + group.bench_function("fq_square", bench_function_square::); + group.bench_function("fq_sub", bench_function_sub::); + + group.bench_function("fq2_add", bench_function_add::); + group.bench_function("fq2_clone", bench_function_clone::); + group.bench_function("fq2_deser", bench_function_deser_uncomp::); + group.bench_function("fq2_div", bench_function_div::); + group.bench_function("fq2_double", bench_function_double::); + group.bench_function("fq2_eq", bench_function_eq::); + group.bench_function("fq2_from_u64", bench_function_from_u64::); + group.bench_function("fq2_inv", bench_function_inv::); + group.bench_function("fq2_mul", bench_function_mul::); + group.bench_function("fq2_neg", bench_function_neg::); + group.bench_function("fq2_pow_u256", bench_function_pow_u256::); + group.bench_function("fq2_serialize", bench_function_serialize_uncomp::); + group.bench_function("fq2_square", bench_function_square::); + group.bench_function("fq2_sub", bench_function_sub::); + + + group.bench_function("fq12_add", bench_function_add::); + group.bench_function("fq12_clone", bench_function_clone::); + group.bench_function("fq12_deser", bench_function_deser_uncomp::); + group.bench_function("fq12_div", bench_function_div::); + group.bench_function("fq12_double", bench_function_double::); + group.bench_function("fq12_eq", bench_function_eq::); + group.bench_function("fq12_from_u64", bench_function_from_u64::); + group.bench_function("fq12_inv", bench_function_inv::); + group.bench_function("fq12_mul", bench_function_mul::); + group.bench_function("fq12_neg", bench_function_neg::); + group.bench_function("fq12_pow_u256", bench_function_pow_u256::); + group.bench_function("fq12_serialize", bench_function_serialize_uncomp::); + group.bench_function("fq12_square", bench_function_square::); + group.bench_function("fq12_sub", bench_function_sub::); + + group.bench_function("g1_affine_add", bench_function_add::); + group.bench_function("g1_affine_deser_comp", bench_function_deser_comp::); + group.bench_function("g1_affine_deser_uncomp", bench_function_deser_uncomp::); + group.bench_function("g1_affine_eq", bench_function_eq::); + group.bench_function("g1_affine_generator", move |b| { + b.iter(|| { + let _res = G1Affine::generator(); + }) + }); + + group.bench_function("g1_affine_infinity", move |b| { + b.iter(|| { + let _res = G1Affine::zero(); + }) + }); + + group.bench_function("g1_affine_scalar_mul_to_proj", move |b| { + b.iter_with_setup( + || (rand!(G1Affine), rand!(Fr)), + |(p, k)| { + let _res = p.mul(k); + }, + ) + }); + + group.bench_function("g1_affine_neg", move |b| { + b.iter_with_setup( + || rand!(G1Affine), + |p| { + let _res = p.neg(); + }, + ) + }); + + group.bench_function("g1_affine_serialize_comp", move |b| { + b.iter_with_setup( + || rand!(G1Affine), + |p_affine| { + let _buf = serialize!(p_affine, serialize_compressed); + }, + ) + }); + + group.bench_function("g1_affine_serialize_uncomp", move |b| { + b.iter_with_setup( + || rand!(G1Affine), + |p_affine| { + let _buf = serialize!(p_affine, serialize_uncompressed); + }, + ) + }); + + group.bench_function("g1_affine_to_proj", move |b| { + b.iter_with_setup( + || rand!(G1Affine), + |p_affine| { + let _res = G1Projective::from(p_affine); + }, + ) + }); + + group.bench_function("g1_proj_add", move |b| { + b.iter_with_setup( + || { + let p = rand!(G1Projective); + let q = rand!(G1Projective); + (p, q) + }, + |(p, q)| { + let _res = p + q; + }, + ) + }); + + group.bench_function("g1_proj_double", move |b| { + b.iter_with_setup( + || rand!(G1Projective), + |p| { + let _q = p.double(); + }, + ) + }); + + group.bench_function("g1_proj_eq", move |b| { + b.iter_with_setup( + || { + let p = rand!(G1Projective); + let q = p; + (p, q) + }, + |(p, q)| { + let _res = p == q; + }, + ) + }); + + group.bench_function("g1_proj_generator", move |b| { + b.iter(|| { + let _res = G1Projective::generator(); + }) + }); + + group.bench_function("g1_proj_infinity", move |b| { + b.iter(|| { + let _res = G1Projective::zero(); + }) + }); + + group.bench_function("g1_proj_neg", move |b| { + b.iter_with_setup( + || rand!(G1Projective), + |p| { + let _q = p.neg(); + }, + ) + }); + + group.bench_function("g1_proj_scalar_mul", move |b| { + b.iter_with_setup( + || { + let p = rand!(G1Projective); + let k = rand!(Fr); + (p, k) + }, + |(p, k)| { + let _q = p.mul(k); + }, + ) + }); + + group.bench_function("g1_proj_sub", move |b| { + b.iter_with_setup( + || { + let p = rand!(G1Projective); + let q = rand!(G1Projective); + (p, q) + }, + |(p, q)| { + let _r = p - q; + }, + ) + }); + + group.bench_function("g1_proj_to_affine", move |b| { + b.iter_with_setup( + || rand!(G1Projective), + |p_proj| { + let _ = p_proj.into_affine(); + }, + ) + }); + + group.bench_function("g2_affine_add", move |b| { + b.iter_with_setup( + || (rand!(G2Affine), rand!(G2Affine)), + |(p1, p2)| { + let _p3 = p1 + p2; + }, + ) + }); + + group.bench_function("g2_affine_deser_comp", move |b| { + b.iter_with_setup( + || { + let p = rand!(G2Affine); + serialize!(p, serialize_compressed) + }, + |buf| { + let _p = G2Affine::deserialize_compressed(buf.as_slice()); + }, + ) + }); + + group.bench_function("g2_affine_deser_uncomp", move |b| { + b.iter_with_setup( + || { + let p = rand!(G2Affine); + serialize!(p, serialize_uncompressed) + }, + |buf| { + let _p = G2Affine::deserialize_uncompressed(buf.as_slice()); + }, + ) + }); + + group.bench_function("g2_affine_eq", move |b| { + b.iter_with_setup( + || { + let p1 = rand!(G2Affine); + let p2 = p1; + (p1, p2) + }, + |(p1, p2)| { + let _res = p1 == Projective::from(p2); + }, + ) + }); + + group.bench_function("g2_affine_generator", move |b| { + b.iter(|| { + let _res = G2Affine::generator(); + }) + }); + + group.bench_function("g2_affine_infinity", move |b| { + b.iter(|| { + let _res = G2Affine::zero(); + }) + }); + + group.bench_function("g2_affine_scalar_mul_to_proj", move |b| { + b.iter_with_setup( + || (rand!(G2Affine), rand!(Fr)), + |(p, k)| { + let _res = p.mul(k); + }, + ) + }); + + group.bench_function("g2_affine_neg", move |b| { + b.iter_with_setup( + || rand!(G2Affine), + |p| { + let _res = p.neg(); + }, + ) + }); + + group.bench_function("g2_affine_serialize_comp", move |b| { + b.iter_with_setup( + || rand!(G2Affine), + |p_affine| { + let _buf = serialize!(p_affine, serialize_compressed); + }, + ) + }); + + group.bench_function("g2_affine_serialize_uncomp", move |b| { + b.iter_with_setup( + || rand!(G2Affine), + |p_affine| { + let _buf = serialize!(p_affine, serialize_uncompressed); + }, + ) + }); + + group.bench_function("g2_affine_to_proj", move |b| { + b.iter_with_setup( + || rand!(G2Affine), + |p_affine| { + let _res = G2Projective::from(p_affine); + }, + ) + }); + + group.bench_function("g2_proj_add", move |b| { + b.iter_with_setup( + || { + let p = rand!(G2Projective); + let q = rand!(G2Projective); + (p, q) + }, + |(p, q)| { + let _res = p + q; + }, + ) + }); + + group.bench_function("g2_proj_double", move |b| { + b.iter_with_setup( + || rand!(G2Projective), + |p| { + let _q = p.double(); + }, + ) + }); + + group.bench_function("g2_proj_eq", move |b| { + b.iter_with_setup( + || { + let p = rand!(G2Projective); + let q = p; + (p, q) + }, + |(p, q)| { + let _res = p == q; + }, + ) + }); + + group.bench_function("g2_proj_generator", move |b| { + b.iter(|| { + let _res = G2Projective::generator(); + }) + }); + + group.bench_function("g2_proj_infinity", move |b| { + b.iter(|| { + let _res = G2Projective::zero(); + }) + }); + + group.bench_function("g2_proj_neg", move |b| { + b.iter_with_setup( + || rand!(G2Projective), + |p| { + let _q = p.neg(); + }, + ) + }); + + group.bench_function("g2_proj_scalar_mul", move |b| { + b.iter_with_setup( + || { + let p = rand!(G2Projective); + let k = rand!(Fr); + (p, k) + }, + |(p, k)| { + let _q = p.mul(k); + }, + ) + }); + + group.bench_function("g2_proj_sub", move |b| { + b.iter_with_setup( + || { + let p = rand!(G2Projective); + let q = rand!(G2Projective); + (p, q) + }, + |(p, q)| { + let _r = p - q; + }, + ) + }); + + group.bench_function("g2_proj_to_affine", move |b| { + b.iter_with_setup( + || rand!(G2Projective), + |p_proj| { + let _ = p_proj.into_affine(); + }, + ) + }); + + group.bench_function("pairing", move |b| { + b.iter_with_setup( + || (rand!(G1Affine), rand!(G2Affine)), + |(g1e, g2e)| { + let _res = ark_bn254::Bn254::pairing(g1e, g2e).0; + }, + ) + }); + + let linear_regression_max_num_datapoints = 20; + + let pairing_product_max_num_pairs = 100; + for num_pairs in (0..pairing_product_max_num_pairs) + .step_by(pairing_product_max_num_pairs / linear_regression_max_num_datapoints) + { + group.bench_function(BenchmarkId::new("pairing_product", num_pairs), |b| { + b.iter_with_setup( + || { + let g1_elements = (0..num_pairs).map(|_i| rand!(G1Affine)).collect::>(); + let g2_elements = (0..num_pairs).map(|_i| rand!(G2Affine)).collect::>(); + (g1_elements, g2_elements) + }, + |(g1_elements, g2_elements)| { + let _product = + ark_bn254::Bn254::multi_pairing(g1_elements, g2_elements).0; + }, + ); + }); + } + + for num_entries in msm_all_bench_cases() { + group.bench_function(BenchmarkId::new("g1_affine_msm", num_entries), |b| { + b.iter_with_setup( + || { + let elements = (0..num_entries) + .map(|_i| rand!(G1Affine)) + .collect::>(); + let scalars = (0..num_entries).map(|_i| rand!(Fr)).collect::>(); + (elements, scalars) + }, + |(elements, scalars)| { + let _res: G1Projective = + ark_ec::VariableBaseMSM::msm(elements.as_slice(), scalars.as_slice()) + .unwrap(); + }, + ); + }); + } + + for num_entries in msm_all_bench_cases() { + group.bench_function(BenchmarkId::new("g2_affine_msm", num_entries), |b| { + b.iter_with_setup( + || { + let elements = (0..num_entries) + .map(|_i| rand!(G2Affine)) + .collect::>(); + let scalars = (0..num_entries).map(|_i| rand!(Fr)).collect::>(); + (elements, scalars) + }, + |(elements, scalars)| { + let _res: G2Projective = + ark_ec::VariableBaseMSM::msm(elements.as_slice(), scalars.as_slice()) + .unwrap(); + }, + ); + }); + } + + group.finish(); +} + +criterion_group!( + name = ark_bn254_benches; + config = Criterion::default(); //.measurement_time(Duration::from_secs(100)); + targets = bench_group); +criterion_main!(ark_bn254_benches); diff --git a/crates/aptos-crypto/benches/bench_utils.rs b/crates/aptos-crypto/benches/bench_utils.rs new file mode 100644 index 0000000000000..3dcf0672ef6d3 --- /dev/null +++ b/crates/aptos-crypto/benches/bench_utils.rs @@ -0,0 +1,178 @@ +use std::ops::{Add, Div, Mul, Neg, Sub}; +use ark_ff::{BigInteger256, Field, One, Zero}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_std::test_rng; +use ark_std::UniformRand; +use criterion::Bencher; + +fn rand() -> T { + T::rand(&mut test_rng()) +} + +pub fn bench_function_add(b: &mut Bencher) { + b.iter_with_setup( + || (rand::(), rand::()), + |(e_1, e_2)| { + let _e_3 = e_1 + e_2; + }, + ) +} + +pub fn bench_function_clone(b: &mut Bencher) { + b.iter_with_setup( + || rand::(), + |e| { + let _e_2 = e.clone(); + }, + ) +} + +pub fn bench_function_deser_comp(b: &mut Bencher) { + b.iter_with_setup( + || { + let e = rand::(); + let mut buf = vec![]; + e.serialize_compressed(&mut buf).unwrap(); + buf + }, + |buf| { + let _e = T::deserialize_compressed(buf.as_slice()).unwrap(); + }, + ) +} + +pub fn bench_function_deser_uncomp(b: &mut Bencher) { + b.iter_with_setup( + || { + let e = rand::(); + let mut buf = vec![]; + e.serialize_uncompressed(&mut buf).unwrap(); + buf + }, + |buf| { + let _e = T::deserialize_uncompressed(buf.as_slice()).unwrap(); + }, + ) +} + +pub fn bench_function_div(b: &mut Bencher) { + b.iter_with_setup( + || (rand::(), rand::()), + |(e, f)| { + let _g = e.div(f); + }, + ) +} + +pub fn bench_function_double(b: &mut Bencher) { + b.iter_with_setup( + || rand::(), + |e| { + let _e_2 = e.double(); + }, + ) +} + +pub fn bench_function_eq(b: &mut Bencher) { + b.iter_with_setup( + || { + let e_1 = rand::(); + let e_2 = e_1.clone(); + (e_1, e_2) + }, + |(e_1, e_2)| { + let _res = e_1 == e_2; + }, + ) +} + +pub fn bench_function_from_u64 + UniformRand>(b: &mut Bencher) { + b.iter_with_setup( + || rand::(), + |i| { + let _res = T::from(i); + }, + ) +} + +pub fn bench_function_inv(b: &mut Bencher) { + b.iter_with_setup( + || rand::(), + |e| { + let _e_inv = e.inverse(); + }, + ) +} + +pub fn bench_function_mul(b: &mut Bencher) { + b.iter_with_setup( + || (rand::(), rand::()), + |(e_1, e_2)| { + let _e_3 = e_1 * e_2; + }, + ) +} + +pub fn bench_function_neg(b: &mut Bencher) { + b.iter_with_setup( + || rand::(), + |e| { + let _e_2 = e.neg(); + }, + ) +} + +pub fn bench_function_one(b: &mut Bencher) { + b.iter(|| { + let _e = T::one(); + }) +} + +pub fn bench_function_pow_u256(b: &mut Bencher) { + b.iter_with_setup( + || { + let base = rand::(); + let exp = rand::(); + (base, exp) + }, + |(base, exp)| { + let _res = base.pow(exp); + }, + ) +} + +pub fn bench_function_serialize_uncomp(b: &mut Bencher) { + b.iter_with_setup( + || rand::(), + |e| { + let mut buf = vec![]; + e.serialize_uncompressed(&mut buf).unwrap(); + }, + ) +} + +pub fn bench_function_square(b: &mut Bencher) { + b.iter_with_setup( + || rand::(), + |e| { + let _res = e.square(); + }, + ) +} + +pub fn bench_function_sub(b: &mut Bencher) { + b.iter_with_setup( + || (rand::(), rand::()), + |(e, f)| { + let _res = e - f; + }, + ) +} + +pub fn bench_function_zero(b: &mut Bencher) { + b.iter( + || { + let _res = T::zero(); + }, + ) +} diff --git a/scripts/algebra-gas/update_algebra_gas_params.py b/scripts/algebra-gas/update_bls12381_algebra_gas_params.py similarity index 89% rename from scripts/algebra-gas/update_algebra_gas_params.py rename to scripts/algebra-gas/update_bls12381_algebra_gas_params.py index 06f3855cfaa03..597e4b0a4cadf 100755 --- a/scripts/algebra-gas/update_algebra_gas_params.py +++ b/scripts/algebra-gas/update_bls12381_algebra_gas_params.py @@ -7,6 +7,7 @@ ''' import argparse +from collections import defaultdict import fit_linear_model import load_bench_ns import load_bench_datapoints @@ -91,24 +92,30 @@ def get_algebra_lines(gas_per_ns): _,_,nanoseconds['ark_bls12_381_multi_pairing_per_pair'],nanoseconds['ark_bls12_381_multi_pairing_base'] = get_bench_ns_linear('target/criterion/ark_bls12_381/pairing_product') _,_,nanoseconds['ark_h2c_bls12381g1_xmd_sha256_sswu_per_msg_byte'],nanoseconds['ark_h2c_bls12381g1_xmd_sha256_sswu_base'] = get_bench_ns_linear('target/criterion/ark_bls12_381/hash_to_g1_proj') _,_,nanoseconds['ark_h2c_bls12381g2_xmd_sha256_sswu_per_msg_byte'],nanoseconds['ark_h2c_bls12381g2_xmd_sha256_sswu_base'] = get_bench_ns_linear('target/criterion/ark_bls12_381/hash_to_g2_proj') - gas_units = {k:gas_per_ns*v for k,v in nanoseconds.items()} - lines = [f' [.algebra.{k}, {{ {TARGET_GAS_VERSION}.. => "algebra.{k}" }}, {prettify_number(v)} * MUL],' for k,v in sorted(gas_units.items())] + + quantity_types = defaultdict(lambda: "InternalGas") + quantity_types['ark_bls12_381_multi_pairing_per_pair'] = 'InternalGasPerArg' + quantity_types['ark_h2c_bls12381g1_xmd_sha256_sswu_per_msg_byte'] = 'InternalGasPerByte' + quantity_types['ark_h2c_bls12381g2_xmd_sha256_sswu_per_msg_byte'] = 'InternalGasPerByte' + + gas_param_entries = { k:(int(gas_per_ns*v), quantity_types[k]) for k,v in nanoseconds.items()} + lines = [f' [algebra_{k}: {unt}, {{ {TARGET_GAS_VERSION}.. => "algebra.{k}" }}, {prettify_number(qty)}],' for k,(qty,unt) in sorted(gas_param_entries.items())] return lines def main(gas_per_ns): path = Path(PATH_STR) lines = path.read_text().split('\n') striped_lines = [line.strip() for line in lines] - line_id_begin = striped_lines.index('// Algebra gas parameters begin.') - line_id_end = striped_lines.index('// Algebra gas parameters end.') - generator_note_line = f' // Generated at time {time()} by `scripts/algebra-gas/update_algebra_gas_params.py` with gas_per_ns={gas_per_ns}.' + line_id_begin = striped_lines.index('// BLS12-381 algebra gas parameters begin.') + line_id_end = striped_lines.index('// BLS12-381 algebra gas parameters end.') + generator_note_line = f' // Generated at time {time()} by `scripts/algebra-gas/update_bls12381_algebra_gas_params.py` with gas_per_ns={gas_per_ns}.' new_lines = lines[:line_id_begin+1] + [generator_note_line] + get_algebra_lines(gas_per_ns) + lines[line_id_end:] path.write_text('\n'.join(new_lines)) PATH_STR = 'aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs' if __name__=='__main__': parser = argparse.ArgumentParser( - description=f'Generate gas parameters for algebra module in `{PATH_STR}`.') + description=f'Generate gas parameters for BLS12-381 algebra module in `{PATH_STR}`.') parser.add_argument('--gas_per_ns', required=True, type=float) args = parser.parse_args() main(args.gas_per_ns) diff --git a/scripts/algebra-gas/update_bn254_algebra_gas_params.py b/scripts/algebra-gas/update_bn254_algebra_gas_params.py new file mode 100755 index 0000000000000..80d906f1eda64 --- /dev/null +++ b/scripts/algebra-gas/update_bn254_algebra_gas_params.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python3 + +''' +This module automated the steps to +calculate gas parameters for `algebra.move` natives from benchmarking results, +then update the gas parameter definitions in rust. +''' + +import argparse +from collections import defaultdict +import fit_linear_model +import load_bench_ns +import load_bench_datapoints +from math import ceil +from pathlib import Path +from time import time + +# Typically you are making a new version of gas schedule, +# so this should be larger than `LATEST_GAS_FEATURE_VERSION` in `aptos-move/aptos-gas/src/gas_meter.rs`. +TARGET_GAS_VERSION = 12 + +def get_bench_ns_linear(bench_path): + datapoints = load_bench_datapoints.main(bench_path) + X,Y,k,b = fit_linear_model.main(datapoints) + return X,Y,k,b + +def prettify_number(x:int) -> str: + s = str(x) + n = len(s) + b = n % 3 + chunks_0 = [s[:b]] if b>=1 else [] + chunks = chunks_0 + [s[i:i+3] for i in range(b,n,3)] + return '_'.join(chunks) + +def get_algebra_lines(gas_per_ns): + nanoseconds = {} + nanoseconds['ark_bn254_fr_add'] = load_bench_ns.main('target/criterion/ark_bn254/fr_add') + nanoseconds['ark_bn254_fr_deser'] = load_bench_ns.main('target/criterion/ark_bn254/fr_deser') + nanoseconds['ark_bn254_fr_div'] = load_bench_ns.main('target/criterion/ark_bn254/fr_div') + nanoseconds['ark_bn254_fr_eq'] = load_bench_ns.main('target/criterion/ark_bn254/fr_eq') + nanoseconds['ark_bn254_fr_from_u64'] = load_bench_ns.main('target/criterion/ark_bn254/fr_from_u64') + nanoseconds['ark_bn254_fr_inv'] = load_bench_ns.main('target/criterion/ark_bn254/fr_inv') + nanoseconds['ark_bn254_fr_mul'] = load_bench_ns.main('target/criterion/ark_bn254/fr_mul') + nanoseconds['ark_bn254_fr_neg'] = load_bench_ns.main('target/criterion/ark_bn254/fr_neg') + nanoseconds['ark_bn254_fr_one'] = load_bench_ns.main('target/criterion/ark_bn254/fr_one') + nanoseconds['ark_bn254_fr_serialize'] = load_bench_ns.main('target/criterion/ark_bn254/fr_serialize') + nanoseconds['ark_bn254_fr_square'] = load_bench_ns.main('target/criterion/ark_bn254/fr_square') + nanoseconds['ark_bn254_fr_sub'] = load_bench_ns.main('target/criterion/ark_bn254/fr_sub') + nanoseconds['ark_bn254_fr_zero'] = 1 + nanoseconds['ark_bn254_fq_add'] = load_bench_ns.main('target/criterion/ark_bn254/fq_add') + nanoseconds['ark_bn254_fq_clone'] = load_bench_ns.main('target/criterion/ark_bn254/fq_clone') + nanoseconds['ark_bn254_fq_deser'] = load_bench_ns.main('target/criterion/ark_bn254/fq_deser') + nanoseconds['ark_bn254_fq_div'] = load_bench_ns.main('target/criterion/ark_bn254/fq_div') + nanoseconds['ark_bn254_fq_eq'] = load_bench_ns.main('target/criterion/ark_bn254/fq_eq') + nanoseconds['ark_bn254_fq_from_u64'] = load_bench_ns.main('target/criterion/ark_bn254/fq_from_u64') + nanoseconds['ark_bn254_fq_inv'] = load_bench_ns.main('target/criterion/ark_bn254/fq_inv') + nanoseconds['ark_bn254_fq_mul'] = load_bench_ns.main('target/criterion/ark_bn254/fq_mul') + nanoseconds['ark_bn254_fq_neg'] = load_bench_ns.main('target/criterion/ark_bn254/fq_neg') + nanoseconds['ark_bn254_fq_one'] = 1 + nanoseconds['ark_bn254_fq_pow_u256'] = load_bench_ns.main('target/criterion/ark_bn254/fq_pow_u256') + nanoseconds['ark_bn254_fq_serialize'] = load_bench_ns.main('target/criterion/ark_bn254/fq_serialize') + nanoseconds['ark_bn254_fq_square'] = load_bench_ns.main('target/criterion/ark_bn254/fq_square') + nanoseconds['ark_bn254_fq_sub'] = load_bench_ns.main('target/criterion/ark_bn254/fq_sub') + nanoseconds['ark_bn254_fq_zero'] = 1 + nanoseconds['ark_bn254_fq2_add'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_add') + nanoseconds['ark_bn254_fq2_clone'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_clone') + nanoseconds['ark_bn254_fq2_deser'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_deser') + nanoseconds['ark_bn254_fq2_div'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_div') + nanoseconds['ark_bn254_fq2_eq'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_eq') + nanoseconds['ark_bn254_fq2_from_u64'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_from_u64') + nanoseconds['ark_bn254_fq2_inv'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_inv') + nanoseconds['ark_bn254_fq2_mul'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_mul') + nanoseconds['ark_bn254_fq2_neg'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_neg') + nanoseconds['ark_bn254_fq2_one'] = 1 + nanoseconds['ark_bn254_fq2_pow_u256'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_pow_u256') + nanoseconds['ark_bn254_fq2_serialize'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_serialize') + nanoseconds['ark_bn254_fq2_square'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_square') + nanoseconds['ark_bn254_fq2_sub'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_sub') + nanoseconds['ark_bn254_fq2_zero'] = 1 + nanoseconds['ark_bn254_fq12_add'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_add') + nanoseconds['ark_bn254_fq12_clone'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_clone') + nanoseconds['ark_bn254_fq12_deser'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_deser') + nanoseconds['ark_bn254_fq12_div'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_div') + nanoseconds['ark_bn254_fq12_eq'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_eq') + nanoseconds['ark_bn254_fq12_from_u64'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_from_u64') + nanoseconds['ark_bn254_fq12_inv'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_inv') + nanoseconds['ark_bn254_fq12_mul'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_mul') + nanoseconds['ark_bn254_fq12_neg'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_neg') + nanoseconds['ark_bn254_fq12_one'] = 1 + nanoseconds['ark_bn254_fq12_pow_u256'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_pow_u256') + nanoseconds['ark_bn254_fq12_serialize'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_serialize') + nanoseconds['ark_bn254_fq12_square'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_square') + nanoseconds['ark_bn254_fq12_sub'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_sub') + nanoseconds['ark_bn254_fq12_zero'] = 1 + nanoseconds['ark_bn254_g1_affine_deser_comp'] = load_bench_ns.main('target/criterion/ark_bn254/g1_affine_deser_comp') + nanoseconds['ark_bn254_g1_affine_deser_uncomp'] = load_bench_ns.main('target/criterion/ark_bn254/g1_affine_deser_uncomp') + nanoseconds['ark_bn254_g1_affine_serialize_comp'] = load_bench_ns.main('target/criterion/ark_bn254/g1_affine_serialize_comp') + nanoseconds['ark_bn254_g1_affine_serialize_uncomp'] = load_bench_ns.main('target/criterion/ark_bn254/g1_affine_serialize_uncomp') + nanoseconds['ark_bn254_g1_proj_add'] = load_bench_ns.main('target/criterion/ark_bn254/g1_proj_add') + nanoseconds['ark_bn254_g1_proj_double'] = load_bench_ns.main('target/criterion/ark_bn254/g1_proj_double') + nanoseconds['ark_bn254_g1_proj_eq'] = load_bench_ns.main('target/criterion/ark_bn254/g1_proj_eq') + nanoseconds['ark_bn254_g1_proj_generator'] = 1 + nanoseconds['ark_bn254_g1_proj_infinity'] = 1 + nanoseconds['ark_bn254_g1_proj_neg'] = 1 + nanoseconds['ark_bn254_g1_proj_scalar_mul'] = load_bench_ns.main('target/criterion/ark_bn254/g1_proj_scalar_mul') + nanoseconds['ark_bn254_g1_proj_sub'] = load_bench_ns.main('target/criterion/ark_bn254/g1_proj_sub') + nanoseconds['ark_bn254_g1_proj_to_affine'] = load_bench_ns.main('target/criterion/ark_bn254/g1_proj_to_affine') + nanoseconds['ark_bn254_g2_affine_deser_comp'] = load_bench_ns.main('target/criterion/ark_bn254/g2_affine_deser_comp') + nanoseconds['ark_bn254_g2_affine_deser_uncomp'] = load_bench_ns.main('target/criterion/ark_bn254/g2_affine_deser_uncomp') + nanoseconds['ark_bn254_g2_affine_serialize_comp'] = load_bench_ns.main('target/criterion/ark_bn254/g2_affine_serialize_comp') + nanoseconds['ark_bn254_g2_affine_serialize_uncomp'] = load_bench_ns.main('target/criterion/ark_bn254/g2_affine_serialize_uncomp') + nanoseconds['ark_bn254_g2_proj_add'] = load_bench_ns.main('target/criterion/ark_bn254/g2_proj_add') + nanoseconds['ark_bn254_g2_proj_double'] = load_bench_ns.main('target/criterion/ark_bn254/g2_proj_double') + nanoseconds['ark_bn254_g2_proj_eq'] = load_bench_ns.main('target/criterion/ark_bn254/g2_proj_eq') + nanoseconds['ark_bn254_g2_proj_generator'] = 1 + nanoseconds['ark_bn254_g2_proj_infinity'] = 1 + nanoseconds['ark_bn254_g2_proj_neg'] = 1 + nanoseconds['ark_bn254_g2_proj_scalar_mul'] = load_bench_ns.main('target/criterion/ark_bn254/g2_proj_scalar_mul') + nanoseconds['ark_bn254_g2_proj_sub'] = load_bench_ns.main('target/criterion/ark_bn254/g2_proj_sub') + nanoseconds['ark_bn254_g2_proj_to_affine'] = load_bench_ns.main('target/criterion/ark_bn254/g2_proj_to_affine') + nanoseconds['ark_bn254_pairing'] = load_bench_ns.main('target/criterion/ark_bn254/pairing') + _,_,nanoseconds['ark_bn254_multi_pairing_per_pair'],nanoseconds['ark_bn254_multi_pairing_base'] = get_bench_ns_linear('target/criterion/ark_bn254/pairing_product') + + quantity_types = defaultdict(lambda: "InternalGas") + quantity_types['ark_bn254_multi_pairing_per_pair'] = 'InternalGasPerArg' + + gas_param_entries = { k:(int(gas_per_ns*v), quantity_types[k]) for k,v in nanoseconds.items()} + lines = [f' [algebra_{k}: {unt}, {{ {TARGET_GAS_VERSION}.. => "algebra.{k}" }}, {prettify_number(qty)}],' for k,(qty,unt) in sorted(gas_param_entries.items())] + return lines + +def main(gas_per_ns): + path = Path(PATH_STR) + lines = path.read_text().split('\n') + striped_lines = [line.strip() for line in lines] + line_id_begin = striped_lines.index('// BN254 algebra gas parameters begin.') + line_id_end = striped_lines.index('// BN254 algebra gas parameters end.') + generator_note_line = f' // Generated at time {time()} by `scripts/algebra-gas/update_bn254_algebra_gas_params.py` with gas_per_ns={gas_per_ns}.' + new_lines = lines[:line_id_begin+1] + [generator_note_line] + get_algebra_lines(gas_per_ns) + lines[line_id_end:] + path.write_text('\n'.join(new_lines)) + +PATH_STR = 'aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs' +if __name__=='__main__': + parser = argparse.ArgumentParser( + description=f'Generate gas parameters for BN254 algebra module in `{PATH_STR}`.') + parser.add_argument('--gas_per_ns', required=True, type=float) + args = parser.parse_args() + main(args.gas_per_ns) From 28bf7bc2ed817fe0d5e8cc9b05b1ab403765a6be Mon Sep 17 00:00:00 2001 From: caojiafeng Date: Mon, 4 Dec 2023 12:01:15 +0800 Subject: [PATCH 08/21] resolve comments --- .../sources/cryptography/bn254_algebra.move | 20 +----------------- .../move-stdlib/sources/configs/features.move | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move index a0757ffca0d01..4fdcf12eb9fc9 100644 --- a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move +++ b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move @@ -4,7 +4,7 @@ /// defined over a 254-bit (prime) field. The scalar field is highly 2-adic. /// /// This curve is also implemented in [libff](https://github.com/scipr-lab/libff/tree/master/libff/algebra/curves/alt_bn128) under the name `bn128`. -/// It is the same as the `bn256` curve used in Ethereum (eg: [go-ethereum](https://github.com/ethereum/go-ethereum/tree/master/crypto/bn254/cloudflare)). +/// It is the same as the `bn254` curve used in Ethereum (eg: [go-ethereum](https://github.com/ethereum/go-ethereum/tree/master/crypto/bn254/cloudflare)). /// /// #CAUTION /// **This curve does not satisfy the 128-bit security level anymore.** @@ -488,15 +488,6 @@ module std::bn254_algebra { // Subtraction. assert!(eq(&point_9g, &sub(&point_2g, &point_minus_7g_calc)), 1); - - // // Hash-to-group using suite `BLS12381G1_XMD:SHA-256_SSWU_RO_`. - // // Test vectors source: https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-bls12381g1_xmdsha-256_sswu_ - // let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_", &b""); - // let expected = std::option::extract(&mut deserialize(&x"052926add2207b76ca4fa57a8734416c8dc95e24501772c814278700eed6d1e4e8cf62d9c09db0fac349612b759e79a108ba738453bfed09cb546dbb0783dbb3a5f1f566ed67bb6be0e8c67e2e81a4cc68ee29813bb7994998f3eae0c9c6a265")); - // assert!(eq(&expected, &actual), 1); - // let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_", &b"abcdef0123456789"); - // let expected = std::option::extract(&mut deserialize(&x"11e0b079dea29a68f0383ee94fed1b940995272407e3bb916bbf268c263ddd57a6a27200a784cbc248e84f357ce82d9803a87ae2caf14e8ee52e51fa2ed8eefe80f02457004ba4d486d6aa1f517c0889501dc7413753f9599b099ebcbbd2d709")); - // assert!(eq(&expected, &actual), 1); } #[test_only] @@ -609,15 +600,6 @@ module std::bn254_algebra { // Subtraction. assert!(eq(&point_9g, &sub(&point_2g, &point_minus_7g_calc)), 1); - - // // Hash-to-group using suite `BLS12381G2_XMD:SHA-256_SSWU_RO_`. - // // Test vectors source: https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-bls12381g2_xmdsha-256_sswu_ - // let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_", &b""); - // let expected = std::option::extract(&mut deserialize(&x"05cb8437535e20ecffaef7752baddf98034139c38452458baeefab379ba13dff5bf5dd71b72418717047f5b0f37da03d0141ebfbdca40eb85b87142e130ab689c673cf60f1a3e98d69335266f30d9b8d4ac44c1038e9dcdd5393faf5c41fb78a12424ac32561493f3fe3c260708a12b7c620e7be00099a974e259ddc7d1f6395c3c811cdd19f1e8dbf3e9ecfdcbab8d60503921d7f6a12805e72940b963c0cf3471c7b2a524950ca195d11062ee75ec076daf2d4bc358c4b190c0c98064fdd92")); - // assert!(eq(&expected, &actual), 1); - // let actual = hash_to(&b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_", &b"abcdef0123456789"); - // let expected = std::option::extract(&mut deserialize(&x"190d119345b94fbd15497bcba94ecf7db2cbfd1e1fe7da034d26cbba169fb3968288b3fafb265f9ebd380512a71c3f2c121982811d2491fde9ba7ed31ef9ca474f0e1501297f68c298e9f4c0028add35aea8bb83d53c08cfc007c1e005723cd00bb5e7572275c567462d91807de765611490205a941a5a6af3b1691bfe596c31225d3aabdf15faff860cb4ef17c7c3be05571a0f8d3c08d094576981f4a3b8eda0a8e771fcdcc8ecceaf1356a6acf17574518acb506e435b639353c2e14827c8")); - // assert!(eq(&expected, &actual), 1); } #[test_only] diff --git a/aptos-move/framework/move-stdlib/sources/configs/features.move b/aptos-move/framework/move-stdlib/sources/configs/features.move index bd01c5f617bdf..98f775a759cc0 100644 --- a/aptos-move/framework/move-stdlib/sources/configs/features.move +++ b/aptos-move/framework/move-stdlib/sources/configs/features.move @@ -145,16 +145,6 @@ module std::features { is_enabled(BLS12_381_STRUCTURES) } - /// Whether the generic algebra implementation for BN254 operations are enabled. - /// - /// Lifetime: transient - const BN254_STRUCTURES: u64 = 43; - - public fun get_bn254_strutures_feature(): u64 { BN254_STRUCTURES } - - public fun bn254_structures_enabled(): bool acquires Features { - is_enabled(BN254_STRUCTURES) - } /// Whether native_public_key_validate aborts when a public key of the wrong length is given /// Lifetime: ephemeral @@ -331,6 +321,17 @@ module std::features { is_enabled(COMMISSION_CHANGE_DELEGATION_POOL) } + /// Whether the generic algebra implementation for BN254 operations are enabled. + /// + /// Lifetime: transient + const BN254_STRUCTURES: u64 = 43; + + public fun get_bn254_strutures_feature(): u64 { BN254_STRUCTURES } + + public fun bn254_structures_enabled(): bool acquires Features { + is_enabled(BN254_STRUCTURES) + } + // ============================================================================================ // Feature Flag Implementation From f391a95d46bc87bf4e916a117372a87eb2d5bd7e Mon Sep 17 00:00:00 2001 From: caojiafeng Date: Mon, 4 Dec 2023 12:03:57 +0800 Subject: [PATCH 09/21] doc: `cargo run -p aptos-framework release` to generate doc --- .../aptos-stdlib/doc/bn254_algebra.md | 201 +++++++++++++++++- .../framework/move-stdlib/doc/features.md | 96 ++++----- 2 files changed, 247 insertions(+), 50 deletions(-) diff --git a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md index 66a276d695917..e5a55bdc8e549 100644 --- a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md +++ b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md @@ -3,8 +3,64 @@ # Module `0x1::bn254_algebra` +This module defines marker types, constants and test cases for working with BN254 curves using the generic API defined in algebra.move. +BN254 was sampled as part of the [\[BCTV14\]](https://eprint.iacr.org/2013/879.pdf) paper . +The name denotes that it is a Barreto--Naehrig curve of embedding degree 12, +defined over a 254-bit (prime) field. The scalar field is highly 2-adic. +This curve is also implemented in [libff](https://github.com/scipr-lab/libff/tree/master/libff/algebra/curves/alt_bn128) under the name bn128. +It is the same as the bn254 curve used in Ethereum (eg: [go-ethereum](https://github.com/ethereum/go-ethereum/tree/master/crypto/bn254/cloudflare)). + + + +## CAUTION + +**This curve does not satisfy the 128-bit security level anymore.** + + +Curve information: +* Base field: q = +21888242871839275222246405745257275088696311157297823662689037894645226208583 +* Scalar field: r = +21888242871839275222246405745257275088548364400416034343698204186575808495617 +* valuation(q - 1, 2) = 1 +* valuation(r - 1, 2) = 28 +* G1 curve equation: y^2 = x^3 + 3 +* G2 curve equation: y^2 = x^3 + B, where +* B = 3/(u+9) where Fq2 is represented as Fq\[u\]/(u^2+1) = +Fq2(19485874751759354771024239261021720505790618469301721065564631296452457478373, +266929791119991161246907387137283842545076965332900288569378510910307636690) + + +Currently-supported BN254 structures include Fq12, Fr, Fq, Fq2, G1, G2 and Gt, +along with their widely-used serialization formats, +the pairing between G1, G2 and Gt. + +Other unimplemented BN254 structures and serialization formats are also listed here, +as they help define some of the currently supported structures. +Their implementation may also be added in the future. + +Fq6: the finite field $F_{q^6}$ used in BN254 curves, +which is an extension field of Fq2, constructed as $F_{q^6}=F_{q^2}[v]/(v^3-u-9)$. + +FormatFq6LscLsb: a serialization scheme for Fq6 elements, +where an element in the form $(c_0+c_1\cdot v+c_2\cdot v^2)$ is represented by a byte array b[] of size 192, +which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first: +- b[0..64] is $c_0$ serialized using FormatFq2LscLsb. +- b[64..128] is $c_1$ serialized using FormatFq2LscLsb. +- b[128..192] is $c_2$ serialized using FormatFq2LscLsb. + +G1Full: a group constructed by the points on the BN254 curve $E(F_q): y^2=x^3+3$ and the point at infinity, +under the elliptic curve point addition. +It contains the prime-order subgroup $G_1$ used in pairing. + +G2Full: a group constructed by the points on a curve $E'(F_{q^2}): y^2=x^3+3/(u+9)$ and the point at infinity, +under the elliptic curve point addition. +It contains the prime-order subgroup $G_2$ used in pairing. + + +- [CAUTION](#@CAUTION_0) - [Struct `Fr`](#0x1_bn254_algebra_Fr) - [Struct `FormatFrLsb`](#0x1_bn254_algebra_FormatFrLsb) - [Struct `FormatFrMsb`](#0x1_bn254_algebra_FormatFrMsb) @@ -23,7 +79,7 @@ - [Struct `FormatG2Compr`](#0x1_bn254_algebra_FormatG2Compr) - [Struct `Gt`](#0x1_bn254_algebra_Gt) - [Struct `FormatGt`](#0x1_bn254_algebra_FormatGt) -- [Constants](#@Constants_0) +- [Constants](#@Constants_1)
@@ -34,6 +90,8 @@ ## Struct `Fr` +The finite field $F_r$ that can be used as the scalar fields +associated with the groups $G_1$, $G_2$, $G_t$ in BN254-based pairing.
struct Fr
@@ -61,6 +119,10 @@
 
 ## Struct `FormatFrLsb`
 
+A serialization format for Fr elements,
+where an element is represented by a byte array b[] of size 32 with the least significant byte (LSB) coming first.
+
+NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
 
 
 
struct FormatFrLsb
@@ -88,6 +150,10 @@
 
 ## Struct `FormatFrMsb`
 
+A serialization scheme for Fr elements,
+where an element is represented by a byte array b[] of size 32 with the most significant byte (MSB) coming first.
+
+NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
 
 
 
struct FormatFrMsb
@@ -115,6 +181,7 @@
 
 ## Struct `Fq`
 
+The finite field $F_q$ that can be used as the base field of $G_1$
 
 
 
struct Fq
@@ -142,6 +209,10 @@
 
 ## Struct `FormatFqLsb`
 
+A serialization format for Fq elements,
+where an element is represented by a byte array b[] of size 32 with the least significant byte (LSB) coming first.
+
+NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
 
 
 
struct FormatFqLsb
@@ -169,6 +240,10 @@
 
 ## Struct `FormatFqMsb`
 
+A serialization scheme for Fq elements,
+where an element is represented by a byte array b[] of size 32 with the most significant byte (MSB) coming first.
+
+NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
 
 
 
struct FormatFqMsb
@@ -196,6 +271,8 @@
 
 ## Struct `Fq2`
 
+The finite field $F_q2$ that can be used as the base field of $G_2$
+which is an extension field of Fq, constructed as $F_{q^2}=F_{q}[u]/(u^2+1)$.
 
 
 
struct Fq2
@@ -223,6 +300,13 @@
 
 ## Struct `FormatFq2LscLsb`
 
+A serialization scheme for Fq2 elements,
+where an element $(c_0+c_1\cdot w)$ is represented by a byte array b[] of size N=64,
+which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first.
+- b[0..N] is $c_0$ serialized using FormatFqLscLsb.
+- b[N..384] is $c_1$ serialized using FormatFqLscLsb.
+
+NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
 
 
 
struct FormatFq2LscLsb
@@ -250,6 +334,8 @@
 
 ## Struct `Fq12`
 
+The finite field $F_{q^12}$ used in BN254 curves,
+which is an extension field of Fq6 (defined in the module documentation), constructed as $F_{q^12}=F_{q^6}[w]/(w^2-v)$.
 
 
 
struct Fq12
@@ -277,6 +363,13 @@
 
 ## Struct `FormatFq12LscLsb`
 
+A serialization scheme for Fq12 elements,
+where an element $(c_0+c_1\cdot w)$ is represented by a byte array b[] of size 384,
+which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first.
+- b[0..192] is $c_0$ serialized using FormatFq6LscLsb (defined in the module documentation).
+- b[192..384] is $c_1$ serialized using FormatFq6LscLsb.
+
+NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
 
 
 
struct FormatFq12LscLsb
@@ -304,6 +397,10 @@
 
 ## Struct `G1`
 
+The group $G_1$ in BN254-based pairing $G_1 \times G_2 \rightarrow G_t$.
+It is a subgroup of G1Full (defined in the module documentation) with a prime order $r$
+equal to 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001.
+(so Fr is the associated scalar field).
 
 
 
struct G1
@@ -331,6 +428,27 @@
 
 ## Struct `FormatG1Uncompr`
 
+A serialization scheme for G1 elements derived from arkworks.rs.
+
+Below is the serialization procedure that takes a G2 element p and outputs a byte array of size N=64.
+1. Let (x,y) be the coordinates of p if p is on the curve, or (0,0) otherwise.
+1. Serialize x and y into b_x[] and b_y[] respectively using FormatFqLsb (defined in the module documentation).
+1. Concatenate b_x[] and b_y[] into b[].
+1. If p is the point at infinity, set the infinity bit: b[N-1]: = b[N-1] | 0b0100_0000.
+1. If yis negative, set the negative bit:  b[N-1]: = b[N-1] | 0b1000_0000.
+1. Return b[].
+
+Below is the deserialization procedure that takes a byte array b[] and outputs either a G1 element or none.
+1. If the size of b[] is not N, return none.
+1. Compute the infinity flag as b[N-1] & 0b0100_0000 != 0.
+1. If the infinity flag is set, return the point at infinity.
+1. Deserialize [b[0], b[1], ..., b[N/2-1]] to x using FormatFqLsb. If x is none, return none.
+1. Deserialize [b[N/2], ..., b[N] & 0b0011_1111] to y using FormatFqLsb. If y is none, return none.
+1. Check if (x,y) is on curve E. If not, return none.
+1. Check if (x,y) is in the subgroup of order r. If not, return none.
+1. Return (x,y).
+
+NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
 
 
 
struct FormatG1Uncompr
@@ -358,6 +476,27 @@
 
 ## Struct `FormatG1Compr`
 
+A serialization scheme for G1 elements derived from arkworks.rs
+
+Below is the serialization procedure that takes a G1 element p and outputs a byte array of size N=32.
+1. Let (x,y) be the coordinates of p if p is on the curve, or (0,0) otherwise.
+1. Serialize x into b[] using FormatFqLsb (defined in the module documentation).
+1. If p is the point at infinity, set the infinity bit: b[N-1]: = b[N-1] | 0b0100_0000.
+1. If y > -y, set the lexicographical flag: b[N-1] := b[N-1] | 0x1000_0000.
+1. Return b[].
+
+Below is the deserialization procedure that takes a byte array b[] and outputs either a G1 element or none.
+1. If the size of b[] is not N, return none.
+1. Compute the infinity flag as b[N-1] & 0b0100_0000 != 0.
+1. If the infinity flag is set, return the point at infinity.
+1. Compute the lexicographical flag as b[N-1] & 0b1000_0000 != 0.
+1. Deserialize [b[0], b[1], ..., b[N/2-1] & 0b0011_1111] to x using FormatFqLsb. If x is none, return none.
+1. Solve the curve equation with x for y. If no such y exists, return none.
+1. Let y' be max(y,-y) if the lexicographical flag is set, or min(y,-y) otherwise.
+1. Check if (x,y') is in the subgroup of order r. If not, return none.
+1. Return (x,y').
+
+NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
 
 
 
struct FormatG1Compr
@@ -385,6 +524,10 @@
 
 ## Struct `G2`
 
+The group $G_2$ in BN254-based pairing $G_1 \times G_2 \rightarrow G_t$.
+It is a subgroup of G2Full (defined in the module documentation) with a prime order $r$ equal to
+0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001.
+(so Fr is the scalar field).
 
 
 
struct G2
@@ -412,6 +555,27 @@
 
 ## Struct `FormatG2Uncompr`
 
+A serialization scheme for G2 elements derived from arkworks.rs.
+
+Below is the serialization procedure that takes a G2 element p and outputs a byte array of size N=128.
+1. Let (x,y) be the coordinates of p if p is on the curve, or (0,0) otherwise.
+1. Serialize x and y into b_x[] and b_y[] respectively using FormatFq2Lsb (defined in the module documentation).
+1. Concatenate b_x[] and b_y[] into b[].
+1. If p is the point at infinity, set the infinity bit: b[N-1]: = b[N-1] | 0b0100_0000.
+1. If yis negative, set the negative bit:  b[N-1]: = b[N-1] | 0b1000_0000.
+1. Return b[].
+
+Below is the deserialization procedure that takes a byte array b[] and outputs either a G1 element or none.
+1. If the size of b[] is not N, return none.
+1. Compute the infinity flag as b[N-1] & 0b0100_0000 != 0.
+1. If the infinity flag is set, return the point at infinity.
+1. Deserialize [b[0], b[1], ..., b[N/2-1]] to x using FormatFq2Lsb. If x is none, return none.
+1. Deserialize [b[N/2], ..., b[N] & 0b0011_1111] to y using FormatFq2Lsb. If y is none, return none.
+1. Check if (x,y) is on curve E. If not, return none.
+1. Check if (x,y) is in the subgroup of order r. If not, return none.
+1. Return (x,y).
+
+NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
 
 
 
struct FormatG2Uncompr
@@ -439,6 +603,27 @@
 
 ## Struct `FormatG2Compr`
 
+A serialization scheme for G1 elements derived from arkworks.rs
+
+Below is the serialization procedure that takes a G1 element p and outputs a byte array of size N=64.
+1. Let (x,y) be the coordinates of p if p is on the curve, or (0,0) otherwise.
+1. Serialize x into b[] using FormatFq2Lsb (defined in the module documentation).
+1. If p is the point at infinity, set the infinity bit: b[N-1]: = b[N-1] | 0b0100_0000.
+1. If y > -y, set the lexicographical flag: b[N-1] := b[N-1] | 0x1000_0000.
+1. Return b[].
+
+Below is the deserialization procedure that takes a byte array b[] and outputs either a G1 element or none.
+1. If the size of b[] is not N, return none.
+1. Compute the infinity flag as b[N-1] & 0b0100_0000 != 0.
+1. If the infinity flag is set, return the point at infinity.
+1. Compute the lexicographical flag as b[N-1] & 0b1000_0000 != 0.
+1. Deserialize [b[0], b[1], ..., b[N/2-1] & 0b0011_1111] to x using FormatFq2Lsb. If x is none, return none.
+1. Solve the curve equation with x for y. If no such y exists, return none.
+1. Let y' be max(y,-y) if the lexicographical flag is set, or min(y,-y) otherwise.
+1. Check if (x,y') is in the subgroup of order r. If not, return none.
+1. Return (x,y').
+
+NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
 
 
 
struct FormatG2Compr
@@ -466,6 +651,11 @@
 
 ## Struct `Gt`
 
+The group $G_t$ in BN254-based pairing $G_1 \times G_2 \rightarrow G_t$.
+It is a multiplicative subgroup of Fq12,
+with a prime order $r$ equal to 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001.
+(so Fr is the scalar field).
+The identity of Gt is 1.
 
 
 
struct Gt
@@ -493,6 +683,13 @@
 
 ## Struct `FormatGt`
 
+A serialization scheme for Gt elements.
+
+To serialize, it treats a Gt element p as an Fq12 element and serialize it using FormatFq12LscLsb.
+
+To deserialize, it uses FormatFq12LscLsb to try deserializing to an Fq12 element then test the membership in Gt.
+
+NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
 
 
 
struct FormatGt
@@ -516,7 +713,7 @@
 
 
 
-
+
 
 ## Constants
 
diff --git a/aptos-move/framework/move-stdlib/doc/features.md b/aptos-move/framework/move-stdlib/doc/features.md
index 17aeed218f41e..2556a8acbd7a7 100644
--- a/aptos-move/framework/move-stdlib/doc/features.md
+++ b/aptos-move/framework/move-stdlib/doc/features.md
@@ -55,8 +55,6 @@ return true.
 -  [Function `cryptography_algebra_enabled`](#0x1_features_cryptography_algebra_enabled)
 -  [Function `get_bls12_381_strutures_feature`](#0x1_features_get_bls12_381_strutures_feature)
 -  [Function `bls12_381_structures_enabled`](#0x1_features_bls12_381_structures_enabled)
--  [Function `get_bn254_strutures_feature`](#0x1_features_get_bn254_strutures_feature)
--  [Function `bn254_structures_enabled`](#0x1_features_bn254_structures_enabled)
 -  [Function `get_periodical_reward_rate_decrease_feature`](#0x1_features_get_periodical_reward_rate_decrease_feature)
 -  [Function `periodical_reward_rate_decrease_enabled`](#0x1_features_periodical_reward_rate_decrease_enabled)
 -  [Function `get_partial_governance_voting`](#0x1_features_get_partial_governance_voting)
@@ -84,6 +82,8 @@ return true.
 -  [Function `operator_beneficiary_change_enabled`](#0x1_features_operator_beneficiary_change_enabled)
 -  [Function `get_commission_change_delegation_pool_feature`](#0x1_features_get_commission_change_delegation_pool_feature)
 -  [Function `commission_change_delegation_pool_enabled`](#0x1_features_commission_change_delegation_pool_enabled)
+-  [Function `get_bn254_strutures_feature`](#0x1_features_get_bn254_strutures_feature)
+-  [Function `bn254_structures_enabled`](#0x1_features_bn254_structures_enabled)
 -  [Function `change_feature_flags`](#0x1_features_change_feature_flags)
 -  [Function `is_enabled`](#0x1_features_is_enabled)
 -  [Function `set`](#0x1_features_set)
@@ -1129,52 +1129,6 @@ Lifetime: transient
 
 
 
-
-
-
-
-## Function `get_bn254_strutures_feature`
-
-
-
-
public fun get_bn254_strutures_feature(): u64
-
- - - -
-Implementation - - -
public fun get_bn254_strutures_feature(): u64 { BN254_STRUCTURES }
-
- - - -
- - - -## Function `bn254_structures_enabled` - - - -
public fun bn254_structures_enabled(): bool
-
- - - -
-Implementation - - -
public fun bn254_structures_enabled(): bool acquires Features {
-    is_enabled(BN254_STRUCTURES)
-}
-
- - -
@@ -1797,6 +1751,52 @@ Lifetime: transient + + + + +## Function `get_bn254_strutures_feature` + + + +
public fun get_bn254_strutures_feature(): u64
+
+ + + +
+Implementation + + +
public fun get_bn254_strutures_feature(): u64 { BN254_STRUCTURES }
+
+ + + +
+ + + +## Function `bn254_structures_enabled` + + + +
public fun bn254_structures_enabled(): bool
+
+ + + +
+Implementation + + +
public fun bn254_structures_enabled(): bool acquires Features {
+    is_enabled(BN254_STRUCTURES)
+}
+
+ + +
From 653e7989b3de1dc40e8d4de93e4153af5cc65ac2 Mon Sep 17 00:00:00 2001 From: caojiafeng Date: Wed, 6 Dec 2023 09:24:30 +0800 Subject: [PATCH 10/21] address comments, and regenerate doc --- .../aptos-stdlib/doc/bn254_algebra.md | 20 +++++-------------- .../sources/cryptography/bn254_algebra.move | 8 ++++++-- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md index e5a55bdc8e549..614ea3efb80c3 100644 --- a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md +++ b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md @@ -5,8 +5,9 @@ This module defines marker types, constants and test cases for working with BN254 curves using the generic API defined in algebra.move. BN254 was sampled as part of the [\[BCTV14\]](https://eprint.iacr.org/2013/879.pdf) paper . -The name denotes that it is a Barreto--Naehrig curve of embedding degree 12, -defined over a 254-bit (prime) field. The scalar field is highly 2-adic. +The name denotes that it is a Barreto--Naehrig curve of embedding degree 12, defined over a 254-bit (prime) field. +The scalar field is highly 2-adic which supports subgroups of roots of unity of size <= 2^28. +(as (21888242871839275222246405745257275088548364400416034343698204186575808495617 - 1) mod 2^28 = 0) This curve is also implemented in [libff](https://github.com/scipr-lab/libff/tree/master/libff/algebra/curves/alt_bn128) under the name bn128. It is the same as the bn254 curve used in Ethereum (eg: [go-ethereum](https://github.com/ethereum/go-ethereum/tree/master/crypto/bn254/cloudflare)). @@ -18,6 +19,8 @@ It is the same as the bn254 curve used in Ethereum (eg: [go-ethereu **This curve does not satisfy the 128-bit security level anymore.** +Its current security is estimated at 128-bits (see "Updating Key Size Estimations for Pairings"; by Barbulescu, Razvan and Duquesne, Sylvain; in Journal of Cryptology; 2019; https://doi.org/10.1007/s00145-018-9280-5) + Curve information: * Base field: q = @@ -79,7 +82,6 @@ It contains the prime-order subgroup $G_2$ used in pairing. - [Struct `FormatG2Compr`](#0x1_bn254_algebra_FormatG2Compr) - [Struct `Gt`](#0x1_bn254_algebra_Gt) - [Struct `FormatGt`](#0x1_bn254_algebra_FormatGt) -- [Constants](#@Constants_1)
@@ -713,17 +715,5 @@ NOTE: other implementation(s) using this format: ark-bn254-0.4.0. - - -## Constants - - - - - - -
const FQ_R_SERIALIZED: vector<u8> = [71, 253, 124, 216, 22, 140, 32, 60, 141, 202, 113, 104, 145, 106, 129, 151, 93, 88, 129, 129, 182, 69, 80, 184, 41, 160, 49, 225, 114, 78, 100, 48];
-
- [move-book]: https://aptos.dev/move/book/SUMMARY diff --git a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move index 4fdcf12eb9fc9..bd38d8118389e 100644 --- a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move +++ b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move @@ -1,7 +1,8 @@ /// This module defines marker types, constants and test cases for working with BN254 curves using the generic API defined in `algebra.move`. /// BN254 was sampled as part of the [\[BCTV14\]](https://eprint.iacr.org/2013/879.pdf) paper . -/// The name denotes that it is a Barreto--Naehrig curve of embedding degree 12, -/// defined over a 254-bit (prime) field. The scalar field is highly 2-adic. +/// The name denotes that it is a Barreto--Naehrig curve of embedding degree 12, defined over a 254-bit (prime) field. +/// The scalar field is highly 2-adic which supports subgroups of roots of unity of size <= 2^28. +/// (as (21888242871839275222246405745257275088548364400416034343698204186575808495617 - 1) mod 2^28 = 0) /// /// This curve is also implemented in [libff](https://github.com/scipr-lab/libff/tree/master/libff/algebra/curves/alt_bn128) under the name `bn128`. /// It is the same as the `bn254` curve used in Ethereum (eg: [go-ethereum](https://github.com/ethereum/go-ethereum/tree/master/crypto/bn254/cloudflare)). @@ -9,6 +10,8 @@ /// #CAUTION /// **This curve does not satisfy the 128-bit security level anymore.** /// +/// Its current security is estimated at 128-bits (see "Updating Key Size Estimations for Pairings"; by Barbulescu, Razvan and Duquesne, Sylvain; in Journal of Cryptology; 2019; https://doi.org/10.1007/s00145-018-9280-5) +/// /// /// Curve information: /// * Base field: q = @@ -737,6 +740,7 @@ module std::bn254_algebra { assert!(eq(&mul(&val_x, &val_x), &sqr(&val_x)), 1); } + #[test_only] const FQ_R_SERIALIZED: vector = x"47fd7cd8168c203c8dca7168916a81975d588181b64550b829a031e1724e6430"; #[test_only] const FQ_VAL_0_SERIALIZED_LSB: vector = x"0000000000000000000000000000000000000000000000000000000000000000"; From af3e4f84a8a0f5fba00d150971d9e9e0596ea82b Mon Sep 17 00:00:00 2001 From: "zhoujun.ma" Date: Fri, 8 Dec 2023 00:37:14 -0800 Subject: [PATCH 11/21] update doc --- aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md | 2 +- .../aptos-stdlib/sources/cryptography/bn254_algebra.move | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md index 614ea3efb80c3..b3ab1dea7b6f7 100644 --- a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md +++ b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md @@ -5,7 +5,7 @@ This module defines marker types, constants and test cases for working with BN254 curves using the generic API defined in algebra.move. BN254 was sampled as part of the [\[BCTV14\]](https://eprint.iacr.org/2013/879.pdf) paper . -The name denotes that it is a Barreto--Naehrig curve of embedding degree 12, defined over a 254-bit (prime) field. +The name denotes that it is a Barreto-Naehrig curve of embedding degree 12, defined over a 254-bit (prime) field. The scalar field is highly 2-adic which supports subgroups of roots of unity of size <= 2^28. (as (21888242871839275222246405745257275088548364400416034343698204186575808495617 - 1) mod 2^28 = 0) diff --git a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move index bd38d8118389e..958f6008ce81f 100644 --- a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move +++ b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move @@ -1,6 +1,6 @@ /// This module defines marker types, constants and test cases for working with BN254 curves using the generic API defined in `algebra.move`. /// BN254 was sampled as part of the [\[BCTV14\]](https://eprint.iacr.org/2013/879.pdf) paper . -/// The name denotes that it is a Barreto--Naehrig curve of embedding degree 12, defined over a 254-bit (prime) field. +/// The name denotes that it is a Barreto-Naehrig curve of embedding degree 12, defined over a 254-bit (prime) field. /// The scalar field is highly 2-adic which supports subgroups of roots of unity of size <= 2^28. /// (as (21888242871839275222246405745257275088548364400416034343698204186575808495617 - 1) mod 2^28 = 0) /// From 563a827467a54ada84e5fdab9b8905e280deef9a Mon Sep 17 00:00:00 2001 From: "zhoujun.ma" Date: Fri, 8 Dec 2023 02:31:50 -0800 Subject: [PATCH 12/21] update doc --- .../aptos-stdlib/doc/bn254_algebra.md | 24 +++++----- .../cryptography/bls12381_algebra.move | 9 ++-- .../sources/cryptography/bn254_algebra.move | 47 +++++++++---------- 3 files changed, 37 insertions(+), 43 deletions(-) diff --git a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md index b3ab1dea7b6f7..806792dc86bc1 100644 --- a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md +++ b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md @@ -273,7 +273,7 @@ NOTE: other implementation(s) using this format: ark-bn254-0.4.0. ## Struct `Fq2` -The finite field $F_q2$ that can be used as the base field of $G_2$ +The finite field $F_{q^2}$ that can be used as the base field of $G_2$ which is an extension field of Fq, constructed as $F_{q^2}=F_{q}[u]/(u^2+1)$. @@ -303,10 +303,10 @@ which is an extension field of Fq2 elements, -where an element $(c_0+c_1\cdot w)$ is represented by a byte array b[] of size N=64, +where an element $(c_0+c_1\cdot u)$ is represented by a byte array b[] of size N=64, which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first. -- b[0..N] is $c_0$ serialized using FormatFqLscLsb. -- b[N..384] is $c_1$ serialized using FormatFqLscLsb. +- b[0..32] is $c_0$ serialized using FormatFqLsb. +- b[32..64] is $c_1$ serialized using FormatFqLsb. NOTE: other implementation(s) using this format: ark-bn254-0.4.0. @@ -432,12 +432,12 @@ equal to 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001. A serialization scheme for G1 elements derived from arkworks.rs. -Below is the serialization procedure that takes a G2 element p and outputs a byte array of size N=64. +Below is the serialization procedure that takes a G1 element p and outputs a byte array of size N=64. 1. Let (x,y) be the coordinates of p if p is on the curve, or (0,0) otherwise. 1. Serialize x and y into b_x[] and b_y[] respectively using FormatFqLsb (defined in the module documentation). 1. Concatenate b_x[] and b_y[] into b[]. 1. If p is the point at infinity, set the infinity bit: b[N-1]: = b[N-1] | 0b0100_0000. -1. If yis negative, set the negative bit: b[N-1]: = b[N-1] | 0b1000_0000. +1. If y > -y, set the lexicographical bit: b[N-1]: = b[N-1] | 0b1000_0000. 1. Return b[]. Below is the deserialization procedure that takes a byte array b[] and outputs either a G1 element or none. @@ -561,18 +561,18 @@ A serialization scheme for G2 element p and outputs a byte array of size N=128. 1. Let (x,y) be the coordinates of p if p is on the curve, or (0,0) otherwise. -1. Serialize x and y into b_x[] and b_y[] respectively using FormatFq2Lsb (defined in the module documentation). +1. Serialize x and y into b_x[] and b_y[] respectively using FormatFq2LscLsb. 1. Concatenate b_x[] and b_y[] into b[]. 1. If p is the point at infinity, set the infinity bit: b[N-1]: = b[N-1] | 0b0100_0000. -1. If yis negative, set the negative bit: b[N-1]: = b[N-1] | 0b1000_0000. +1. If y > -y, set the lexicographical bit: b[N-1]: = b[N-1] | 0b1000_0000. 1. Return b[]. Below is the deserialization procedure that takes a byte array b[] and outputs either a G1 element or none. 1. If the size of b[] is not N, return none. 1. Compute the infinity flag as b[N-1] & 0b0100_0000 != 0. 1. If the infinity flag is set, return the point at infinity. -1. Deserialize [b[0], b[1], ..., b[N/2-1]] to x using FormatFq2Lsb. If x is none, return none. -1. Deserialize [b[N/2], ..., b[N] & 0b0011_1111] to y using FormatFq2Lsb. If y is none, return none. +1. Deserialize [b[0], b[1], ..., b[N/2-1]] to x using FormatFq2LscLsb. If x is none, return none. +1. Deserialize [b[N/2], ..., b[N] & 0b0011_1111] to y using FormatFq2LscLsb. If y is none, return none. 1. Check if (x,y) is on curve E. If not, return none. 1. Check if (x,y) is in the subgroup of order r. If not, return none. 1. Return (x,y). @@ -609,7 +609,7 @@ A serialization scheme for G1 element p and outputs a byte array of size N=64. 1. Let (x,y) be the coordinates of p if p is on the curve, or (0,0) otherwise. -1. Serialize x into b[] using FormatFq2Lsb (defined in the module documentation). +1. Serialize x into b[] using FormatFq2LscLsb (defined in the module documentation). 1. If p is the point at infinity, set the infinity bit: b[N-1]: = b[N-1] | 0b0100_0000. 1. If y > -y, set the lexicographical flag: b[N-1] := b[N-1] | 0x1000_0000. 1. Return b[]. @@ -619,7 +619,7 @@ Below is the deserialization procedure that takes a byte array b[] 1. Compute the infinity flag as b[N-1] & 0b0100_0000 != 0. 1. If the infinity flag is set, return the point at infinity. 1. Compute the lexicographical flag as b[N-1] & 0b1000_0000 != 0. -1. Deserialize [b[0], b[1], ..., b[N/2-1] & 0b0011_1111] to x using FormatFq2Lsb. If x is none, return none. +1. Deserialize [b[0], b[1], ..., b[N/2-1] & 0b0011_1111] to x using FormatFq2LscLsb. If x is none, return none. 1. Solve the curve equation with x for y. If no such y exists, return none. 1. Let y' be max(y,-y) if the lexicographical flag is set, or min(y,-y) otherwise. 1. Check if (x,y') is in the subgroup of order r. If not, return none. diff --git a/aptos-move/framework/aptos-stdlib/sources/cryptography/bls12381_algebra.move b/aptos-move/framework/aptos-stdlib/sources/cryptography/bls12381_algebra.move index b8b6b79631e70..5fb99beb93c1b 100644 --- a/aptos-move/framework/aptos-stdlib/sources/cryptography/bls12381_algebra.move +++ b/aptos-move/framework/aptos-stdlib/sources/cryptography/bls12381_algebra.move @@ -773,15 +773,12 @@ module aptos_std::bls12381_algebra { #[test_only] /// The maximum number of `G1` elements that can be created in a transaction, /// calculated by the current memory limit (1MB) and the in-mem G1 representation size (144 bytes per element). - const G1_NUM_MAX_NUMERATOR: u64 = 1048576; // TODO(#9330) - - #[test_only] - const G1_NUM_MAX_DENOMINATOR: u64 = 144; // TODO(#9330) + const G1_NUM_MAX: u64 = 1048576 / 144; #[test(fx = @std)] fun test_memory_limit(fx: signer) { enable_cryptography_algebra_natives(&fx); - let remaining = G1_NUM_MAX_NUMERATOR / G1_NUM_MAX_DENOMINATOR; + let remaining = G1_NUM_MAX; while (remaining > 0) { zero(); remaining = remaining - 1; @@ -792,7 +789,7 @@ module aptos_std::bls12381_algebra { #[expected_failure(abort_code = 0x090003, location = std::crypto_algebra)] fun test_memory_limit_exceeded_with_g1(fx: signer) { enable_cryptography_algebra_natives(&fx); - let remaining = G1_NUM_MAX_NUMERATOR / G1_NUM_MAX_DENOMINATOR + 1; + let remaining = G1_NUM_MAX + 1; while (remaining > 0) { zero(); remaining = remaining - 1; diff --git a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move index 958f6008ce81f..d07bbc8c38be6 100644 --- a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move +++ b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move @@ -88,15 +88,15 @@ module std::bn254_algebra { /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatFqMsb {} - /// The finite field $F_q2$ that can be used as the base field of $G_2$ + /// The finite field $F_{q^2}$ that can be used as the base field of $G_2$ /// which is an extension field of `Fq`, constructed as $F_{q^2}=F_{q}[u]/(u^2+1)$. struct Fq2 {} /// A serialization scheme for `Fq2` elements, - /// where an element $(c_0+c_1\cdot w)$ is represented by a byte array `b[]` of size N=64, + /// where an element $(c_0+c_1\cdot u)$ is represented by a byte array `b[]` of size N=64, /// which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first. - /// - `b[0..N]` is $c_0$ serialized using `FormatFqLscLsb`. - /// - `b[N..384]` is $c_1$ serialized using `FormatFqLscLsb`. + /// - `b[0..32]` is $c_0$ serialized using `FormatFqLsb`. + /// - `b[32..64]` is $c_1$ serialized using `FormatFqLsb`. /// /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0. struct FormatFq2LscLsb {} @@ -121,12 +121,12 @@ module std::bn254_algebra { /// A serialization scheme for `G1` elements derived from arkworks.rs. /// - /// Below is the serialization procedure that takes a `G2` element `p` and outputs a byte array of size N=64. + /// Below is the serialization procedure that takes a `G1` element `p` and outputs a byte array of size N=64. /// 1. Let `(x,y)` be the coordinates of `p` if `p` is on the curve, or `(0,0)` otherwise. /// 1. Serialize `x` and `y` into `b_x[]` and `b_y[]` respectively using `FormatFqLsb` (defined in the module documentation). /// 1. Concatenate `b_x[]` and `b_y[]` into `b[]`. /// 1. If `p` is the point at infinity, set the infinity bit: `b[N-1]: = b[N-1] | 0b0100_0000`. - /// 1. If `y`is negative, set the negative bit: `b[N-1]: = b[N-1] | 0b1000_0000`. + /// 1. If `y > -y`, set the lexicographical bit: `b[N-1]: = b[N-1] | 0b1000_0000`. /// 1. Return `b[]`. /// /// Below is the deserialization procedure that takes a byte array `b[]` and outputs either a `G1` element or none. @@ -175,18 +175,18 @@ module std::bn254_algebra { /// /// Below is the serialization procedure that takes a `G2` element `p` and outputs a byte array of size N=128. /// 1. Let `(x,y)` be the coordinates of `p` if `p` is on the curve, or `(0,0)` otherwise. - /// 1. Serialize `x` and `y` into `b_x[]` and `b_y[]` respectively using `FormatFq2Lsb` (defined in the module documentation). + /// 1. Serialize `x` and `y` into `b_x[]` and `b_y[]` respectively using `FormatFq2LscLsb`. /// 1. Concatenate `b_x[]` and `b_y[]` into `b[]`. /// 1. If `p` is the point at infinity, set the infinity bit: `b[N-1]: = b[N-1] | 0b0100_0000`. - /// 1. If `y`is negative, set the negative bit: `b[N-1]: = b[N-1] | 0b1000_0000`. + /// 1. If `y > -y`, set the lexicographical bit: `b[N-1]: = b[N-1] | 0b1000_0000`. /// 1. Return `b[]`. /// /// Below is the deserialization procedure that takes a byte array `b[]` and outputs either a `G1` element or none. /// 1. If the size of `b[]` is not N, return none. /// 1. Compute the infinity flag as `b[N-1] & 0b0100_0000 != 0`. /// 1. If the infinity flag is set, return the point at infinity. - /// 1. Deserialize `[b[0], b[1], ..., b[N/2-1]]` to `x` using `FormatFq2Lsb`. If `x` is none, return none. - /// 1. Deserialize `[b[N/2], ..., b[N] & 0b0011_1111]` to `y` using `FormatFq2Lsb`. If `y` is none, return none. + /// 1. Deserialize `[b[0], b[1], ..., b[N/2-1]]` to `x` using `FormatFq2LscLsb`. If `x` is none, return none. + /// 1. Deserialize `[b[N/2], ..., b[N] & 0b0011_1111]` to `y` using `FormatFq2LscLsb`. If `y` is none, return none. /// 1. Check if `(x,y)` is on curve `E`. If not, return none. /// 1. Check if `(x,y)` is in the subgroup of order `r`. If not, return none. /// 1. Return `(x,y)`. @@ -198,7 +198,7 @@ module std::bn254_algebra { /// /// Below is the serialization procedure that takes a `G1` element `p` and outputs a byte array of size N=64. /// 1. Let `(x,y)` be the coordinates of `p` if `p` is on the curve, or `(0,0)` otherwise. - /// 1. Serialize `x` into `b[]` using `FormatFq2Lsb` (defined in the module documentation). + /// 1. Serialize `x` into `b[]` using `FormatFq2LscLsb` (defined in the module documentation). /// 1. If `p` is the point at infinity, set the infinity bit: `b[N-1]: = b[N-1] | 0b0100_0000`. /// 1. If `y > -y`, set the lexicographical flag: `b[N-1] := b[N-1] | 0x1000_0000`. /// 1. Return `b[]`. @@ -208,7 +208,7 @@ module std::bn254_algebra { /// 1. Compute the infinity flag as `b[N-1] & 0b0100_0000 != 0`. /// 1. If the infinity flag is set, return the point at infinity. /// 1. Compute the lexicographical flag as `b[N-1] & 0b1000_0000 != 0`. - /// 1. Deserialize `[b[0], b[1], ..., b[N/2-1] & 0b0011_1111]` to `x` using `FormatFq2Lsb`. If `x` is none, return none. + /// 1. Deserialize `[b[0], b[1], ..., b[N/2-1] & 0b0011_1111]` to `x` using `FormatFq2LscLsb`. If `x` is none, return none. /// 1. Solve the curve equation with `x` for `y`. If no such `y` exists, return none. /// 1. Let `y'` be `max(y,-y)` if the lexicographical flag is set, or `min(y,-y)` otherwise. /// 1. Check if `(x,y')` is in the subgroup of order `r`. If not, return none. @@ -741,7 +741,7 @@ module std::bn254_algebra { } #[test_only] - const FQ_R_SERIALIZED: vector = x"47fd7cd8168c203c8dca7168916a81975d588181b64550b829a031e1724e6430"; + const Q_SERIALIZED: vector = x"47fd7cd8168c203c8dca7168916a81975d588181b64550b829a031e1724e6430"; #[test_only] const FQ_VAL_0_SERIALIZED_LSB: vector = x"0000000000000000000000000000000000000000000000000000000000000000"; #[test_only] @@ -758,7 +758,7 @@ module std::bn254_algebra { enable_cryptography_algebra_natives(&fx); // Constants. - assert!(FQ_R_SERIALIZED == order(), 1); + assert!(Q_SERIALIZED == order(), 1); // Serialization/deserialization. let val_0 = zero(); @@ -774,12 +774,12 @@ module std::bn254_algebra { assert!(FQ_VAL_7_SERIALIZED_MSB == serialize(&val_7), 1); // Deserialization should fail if given a byte array of right size but the value is not a member. - assert!(std::option::is_none(&deserialize(&x"01000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed73")), 1); - assert!(std::option::is_none(&deserialize(&x"73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001")), 1); + assert!(std::option::is_none(&deserialize(&x"47fd7cd8168c203c8dca7168916a81975d588181b64550b829a031e1724e6430")), 1); + assert!(std::option::is_none(&deserialize(&x"30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")), 1); // Deserialization should fail if given a byte array of wrong size. - assert!(std::option::is_none(&deserialize(&x"01000000fffffffffe5bfeff02a4bd5305d8a10908d83933487d9d2953a7ed7300")), 1); - assert!(std::option::is_none(&deserialize(&x"0073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001")), 1); + assert!(std::option::is_none(&deserialize(&x"46fd7cd8168c203c8dca7168916a81975d588181b64550b829a031e1724e643000")), 1); + assert!(std::option::is_none(&deserialize(&x"30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4600")), 1); assert!(std::option::is_none(&deserialize(&x"ffff")), 1); assert!(std::option::is_none(&deserialize(&x"ffff")), 1); @@ -885,16 +885,13 @@ module std::bn254_algebra { #[test_only] /// The maximum number of `G1` elements that can be created in a transaction, - /// calculated by the current memory limit (1MB) and the in-mem G1 representation size (32*3 bytes per element). - const G1_NUM_MAX_NUMERATOR: u64 = 1048576; // TODO(#9330) - - #[test_only] - const G1_NUM_MAX_DENOMINATOR: u64 = 96; // TODO(#9330) + /// calculated by the current memory limit (1MB) and the in-mem G1 representation size (96 bytes per element). + const G1_NUM_MAX: u64 = 1048576 / 96; #[test(fx = @std)] fun test_memory_limit(fx: signer) { enable_cryptography_algebra_natives(&fx); - let remaining = G1_NUM_MAX_NUMERATOR / G1_NUM_MAX_DENOMINATOR; + let remaining = G1_NUM_MAX; while (remaining > 0) { zero(); remaining = remaining - 1; @@ -905,7 +902,7 @@ module std::bn254_algebra { #[expected_failure(abort_code = 0x090003, location = std::crypto_algebra)] fun test_memory_limit_exceeded_with_g1(fx: signer) { enable_cryptography_algebra_natives(&fx); - let remaining = G1_NUM_MAX_NUMERATOR / G1_NUM_MAX_DENOMINATOR + 1; + let remaining = G1_NUM_MAX + 1; while (remaining > 0) { zero(); remaining = remaining - 1; From 7030c9f46f83f853a1ee33a056adb69e92c4fa3b Mon Sep 17 00:00:00 2001 From: "zhoujun.ma" Date: Fri, 8 Dec 2023 10:31:17 -0800 Subject: [PATCH 13/21] lint, fix ut --- .../io_limit_reached_by_new_bytes.exp | 12 +++--- .../out_of_gas_while_charging_storage_fee.exp | 12 +++--- .../out_of_gas_while_charging_write_gas.exp | 12 +++--- .../storage_limit_reached_by_new_bytes.exp | 12 +++--- .../src/tests/per_category_gas_limits.rs | 8 +++- crates/aptos-crypto/benches/ark_bn254.rs | 31 ++++++++------ crates/aptos-crypto/benches/bench_utils.rs | 40 +++++++------------ 7 files changed, 64 insertions(+), 63 deletions(-) diff --git a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/io_limit_reached_by_new_bytes.exp b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/io_limit_reached_by_new_bytes.exp index d7269c32a7f50..90781a6bc20f0 100644 --- a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/io_limit_reached_by_new_bytes.exp +++ b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/io_limit_reached_by_new_bytes.exp @@ -8,7 +8,7 @@ Ok( StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }, hash: OnceCell(Uninit), - }: Modification(a4aac0a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), + }: Modification(78a9c0a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::account::Account)" }, hash: OnceCell(Uninit), @@ -32,7 +32,7 @@ Ok( StateKey { inner: TableItem { handle: 1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca, key: 0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935 }, hash: OnceCell(Uninit), - }: Modification(a30bf005000000000100000000000000), + }: Modification(770af005000000000100000000000000), }, }, ), @@ -57,7 +57,7 @@ Ok( StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }, hash: OnceCell(Uninit), - }: Modification(6c79c0a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), + }: Modification(4078c0a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::account::Account)" }, hash: OnceCell(Uninit), @@ -65,7 +65,7 @@ Ok( StateKey { inner: TableItem { handle: 1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca, key: 0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935 }, hash: OnceCell(Uninit), - }: Modification(6bdaef05000000000100000000000000), + }: Modification(3fd9ef05000000000100000000000000), }, }, ), @@ -94,7 +94,7 @@ Ok( StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }, hash: OnceCell(Uninit), - }: Modification(1c4cc0a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), + }: Modification(f04ac0a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::account::Account)" }, hash: OnceCell(Uninit), @@ -102,7 +102,7 @@ Ok( StateKey { inner: TableItem { handle: 1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca, key: 0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935 }, hash: OnceCell(Uninit), - }: Modification(1badef05000000000100000000000000), + }: Modification(efabef05000000000100000000000000), }, }, ), diff --git a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/out_of_gas_while_charging_storage_fee.exp b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/out_of_gas_while_charging_storage_fee.exp index fe69d4370493d..ad5125784cf90 100644 --- a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/out_of_gas_while_charging_storage_fee.exp +++ b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/out_of_gas_while_charging_storage_fee.exp @@ -8,7 +8,7 @@ Ok( StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }, hash: OnceCell(Uninit), - }: Modification(283d28a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), + }: Modification(fc3b28a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::account::Account)" }, hash: OnceCell(Uninit), @@ -32,7 +32,7 @@ Ok( StateKey { inner: TableItem { handle: 1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca, key: 0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935 }, hash: OnceCell(Uninit), - }: Modification(279e5705000000000100000000000000), + }: Modification(fb9c5705000000000100000000000000), }, }, ), @@ -57,7 +57,7 @@ Ok( StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }, hash: OnceCell(Uninit), - }: Modification(686480a37e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), + }: Modification(3c6380a37e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::account::Account)" }, hash: OnceCell(Uninit), @@ -65,7 +65,7 @@ Ok( StateKey { inner: TableItem { handle: 1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca, key: 0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935 }, hash: OnceCell(Uninit), - }: Modification(67c5af04000000000100000000000000), + }: Modification(3bc4af04000000000100000000000000), }, }, ), @@ -90,7 +90,7 @@ Ok( StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }, hash: OnceCell(Uninit), - }: Modification(a88bd8a27e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), + }: Modification(7c8ad8a27e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::account::Account)" }, hash: OnceCell(Uninit), @@ -98,7 +98,7 @@ Ok( StateKey { inner: TableItem { handle: 1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca, key: 0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935 }, hash: OnceCell(Uninit), - }: Modification(a7ec0704000000000100000000000000), + }: Modification(7beb0704000000000100000000000000), }, }, ), diff --git a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/out_of_gas_while_charging_write_gas.exp b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/out_of_gas_while_charging_write_gas.exp index 3776a4d2f3f46..1cde6192ec59b 100644 --- a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/out_of_gas_while_charging_write_gas.exp +++ b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/out_of_gas_while_charging_write_gas.exp @@ -8,7 +8,7 @@ Ok( StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }, hash: OnceCell(Uninit), - }: Modification(343b28a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), + }: Modification(083a28a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::account::Account)" }, hash: OnceCell(Uninit), @@ -32,7 +32,7 @@ Ok( StateKey { inner: TableItem { handle: 1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca, key: 0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935 }, hash: OnceCell(Uninit), - }: Modification(339c5705000000000100000000000000), + }: Modification(079b5705000000000100000000000000), }, }, ), @@ -57,7 +57,7 @@ Ok( StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }, hash: OnceCell(Uninit), - }: Modification(746280a37e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), + }: Modification(486180a37e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::account::Account)" }, hash: OnceCell(Uninit), @@ -65,7 +65,7 @@ Ok( StateKey { inner: TableItem { handle: 1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca, key: 0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935 }, hash: OnceCell(Uninit), - }: Modification(73c3af04000000000100000000000000), + }: Modification(47c2af04000000000100000000000000), }, }, ), @@ -90,7 +90,7 @@ Ok( StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }, hash: OnceCell(Uninit), - }: Modification(b489d8a27e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), + }: Modification(8888d8a27e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::account::Account)" }, hash: OnceCell(Uninit), @@ -98,7 +98,7 @@ Ok( StateKey { inner: TableItem { handle: 1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca, key: 0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935 }, hash: OnceCell(Uninit), - }: Modification(b3ea0704000000000100000000000000), + }: Modification(87e90704000000000100000000000000), }, }, ), diff --git a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/storage_limit_reached_by_new_bytes.exp b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/storage_limit_reached_by_new_bytes.exp index 346ee58a514f8..c98a05abd6b10 100644 --- a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/storage_limit_reached_by_new_bytes.exp +++ b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.data/storage_limit_reached_by_new_bytes.exp @@ -8,7 +8,7 @@ Ok( StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }, hash: OnceCell(Uninit), - }: Modification(283d28a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), + }: Modification(fc3b28a47e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::account::Account)" }, hash: OnceCell(Uninit), @@ -32,7 +32,7 @@ Ok( StateKey { inner: TableItem { handle: 1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca, key: 0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935 }, hash: OnceCell(Uninit), - }: Modification(279e5705000000000100000000000000), + }: Modification(fb9c5705000000000100000000000000), }, }, ), @@ -57,7 +57,7 @@ Ok( StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }, hash: OnceCell(Uninit), - }: Modification(e0d56ea37e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), + }: Modification(b4d46ea37e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::account::Account)" }, hash: OnceCell(Uninit), @@ -65,7 +65,7 @@ Ok( StateKey { inner: TableItem { handle: 1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca, key: 0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935 }, hash: OnceCell(Uninit), - }: Modification(df369e04000000000100000000000000), + }: Modification(b3359e04000000000100000000000000), }, }, ), @@ -94,7 +94,7 @@ Ok( StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>)" }, hash: OnceCell(Uninit), - }: Modification(18e159a27e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), + }: Modification(ecdf59a27e8d03000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beef), StateKey { inner: AccessPath { address: 0xbeef, path: "Resource(0x1::account::Account)" }, hash: OnceCell(Uninit), @@ -102,7 +102,7 @@ Ok( StateKey { inner: TableItem { handle: 1b854694ae746cdbd8d44186ca4929b2b337df21d1c74633be19b2710552fdca, key: 0619dc29a0aac8fa146714058e8dd6d2d0f3bdf5f6331907bf91f3acd81e6935 }, hash: OnceCell(Uninit), - }: Modification(17428903000000000100000000000000), + }: Modification(eb408903000000000100000000000000), }, }, ), diff --git a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs index 012538886f613..be23c3de02275 100644 --- a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs +++ b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs @@ -95,7 +95,13 @@ fn io_limit_reached_by_new_bytes() { }); test_create_multiple_items(&mut h, &acc, |status| { - assert_vm_status!(status, StatusCode::IO_LIMIT_REACHED); + { + use aptos_types::transaction::*; + assert_eq!( + status, + TransactionStatus::Keep(ExecutionStatus::MiscellaneousError(Some(StatusCode::IO_LIMIT_REACHED))) + ); + } }); } diff --git a/crates/aptos-crypto/benches/ark_bn254.rs b/crates/aptos-crypto/benches/ark_bn254.rs index 7a55a72e5aca8..2cbd3b33f340c 100644 --- a/crates/aptos-crypto/benches/ark_bn254.rs +++ b/crates/aptos-crypto/benches/ark_bn254.rs @@ -6,17 +6,20 @@ #[macro_use] extern crate criterion; -use ark_bn254::{Fq, Fq2, Fq12, Fr, G1Affine, G1Projective, G2Affine, G2Projective}; -use ark_ec::{ - pairing::Pairing, short_weierstrass::Projective, AffineRepr, CurveGroup, - Group, +use crate::bench_utils::{ + bench_function_add, bench_function_clone, bench_function_deser_comp, + bench_function_deser_uncomp, bench_function_div, bench_function_double, bench_function_eq, + bench_function_from_u64, bench_function_inv, bench_function_mul, bench_function_neg, + bench_function_pow_u256, bench_function_serialize_uncomp, bench_function_square, + bench_function_sub, }; -use ark_ff::{Field, One, UniformRand, Zero}; +use ark_bn254::{Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective}; +use ark_ec::{pairing::Pairing, short_weierstrass::Projective, AffineRepr, CurveGroup, Group}; +use ark_ff::{UniformRand, Zero}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_std::test_rng; use criterion::{BenchmarkId, Criterion}; -use std::ops::{Add, Div, Mul, Neg}; -use crate::bench_utils::{bench_function_add, bench_function_clone, bench_function_deser_comp, bench_function_deser_uncomp, bench_function_div, bench_function_double, bench_function_eq, bench_function_from_u64, bench_function_inv, bench_function_mul, bench_function_neg, bench_function_pow_u256, bench_function_serialize_uncomp, bench_function_square, bench_function_sub}; +use std::ops::{Mul, Neg}; mod bench_utils; @@ -92,7 +95,6 @@ fn bench_group(c: &mut Criterion) { group.bench_function("fq2_square", bench_function_square::); group.bench_function("fq2_sub", bench_function_sub::); - group.bench_function("fq12_add", bench_function_add::); group.bench_function("fq12_clone", bench_function_clone::); group.bench_function("fq12_deser", bench_function_deser_uncomp::); @@ -109,8 +111,14 @@ fn bench_group(c: &mut Criterion) { group.bench_function("fq12_sub", bench_function_sub::); group.bench_function("g1_affine_add", bench_function_add::); - group.bench_function("g1_affine_deser_comp", bench_function_deser_comp::); - group.bench_function("g1_affine_deser_uncomp", bench_function_deser_uncomp::); + group.bench_function( + "g1_affine_deser_comp", + bench_function_deser_comp::, + ); + group.bench_function( + "g1_affine_deser_uncomp", + bench_function_deser_uncomp::, + ); group.bench_function("g1_affine_eq", bench_function_eq::); group.bench_function("g1_affine_generator", move |b| { b.iter(|| { @@ -477,8 +485,7 @@ fn bench_group(c: &mut Criterion) { (g1_elements, g2_elements) }, |(g1_elements, g2_elements)| { - let _product = - ark_bn254::Bn254::multi_pairing(g1_elements, g2_elements).0; + let _product = ark_bn254::Bn254::multi_pairing(g1_elements, g2_elements).0; }, ); }); diff --git a/crates/aptos-crypto/benches/bench_utils.rs b/crates/aptos-crypto/benches/bench_utils.rs index 3dcf0672ef6d3..ba30d34c203f1 100644 --- a/crates/aptos-crypto/benches/bench_utils.rs +++ b/crates/aptos-crypto/benches/bench_utils.rs @@ -1,9 +1,10 @@ -use std::ops::{Add, Div, Mul, Neg, Sub}; -use ark_ff::{BigInteger256, Field, One, Zero}; +// Copyright © Aptos Foundation + +use ark_ff::{BigInteger256, Field}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::test_rng; -use ark_std::UniformRand; +use ark_std::{test_rng, UniformRand}; use criterion::Bencher; +use std::ops::{Add, Div, Mul, Neg, Sub}; fn rand() -> T { T::rand(&mut test_rng()) @@ -27,7 +28,9 @@ pub fn bench_function_clone(b: &mut Bencher) { ) } -pub fn bench_function_deser_comp(b: &mut Bencher) { +pub fn bench_function_deser_comp( + b: &mut Bencher, +) { b.iter_with_setup( || { let e = rand::(); @@ -41,7 +44,9 @@ pub fn bench_function_deser_comp(b: &mut Bencher) { +pub fn bench_function_deser_uncomp( + b: &mut Bencher, +) { b.iter_with_setup( || { let e = rand::(); @@ -87,12 +92,9 @@ pub fn bench_function_eq(b: &mut Bencher) { } pub fn bench_function_from_u64 + UniformRand>(b: &mut Bencher) { - b.iter_with_setup( - || rand::(), - |i| { - let _res = T::from(i); - }, - ) + b.iter_with_setup(rand::, |i| { + let _res = T::from(i); + }) } pub fn bench_function_inv(b: &mut Bencher) { @@ -122,12 +124,6 @@ pub fn bench_function_neg(b: &mut Bencher) { ) } -pub fn bench_function_one(b: &mut Bencher) { - b.iter(|| { - let _e = T::one(); - }) -} - pub fn bench_function_pow_u256(b: &mut Bencher) { b.iter_with_setup( || { @@ -168,11 +164,3 @@ pub fn bench_function_sub(b: &mut Bencher) { }, ) } - -pub fn bench_function_zero(b: &mut Bencher) { - b.iter( - || { - let _res = T::zero(); - }, - ) -} From 3361d64b9dbdb6ae1e2a6bfca9d9e5546a0ca99a Mon Sep 17 00:00:00 2001 From: "zhoujun.ma" Date: Fri, 8 Dec 2023 11:56:51 -0800 Subject: [PATCH 14/21] lint --- .../src/tests/per_category_gas_limits.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs index be23c3de02275..3610ab21309e9 100644 --- a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs +++ b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs @@ -95,13 +95,13 @@ fn io_limit_reached_by_new_bytes() { }); test_create_multiple_items(&mut h, &acc, |status| { - { - use aptos_types::transaction::*; - assert_eq!( - status, - TransactionStatus::Keep(ExecutionStatus::MiscellaneousError(Some(StatusCode::IO_LIMIT_REACHED))) - ); - } + use aptos_types::transaction::*; + assert_eq!( + status, + TransactionStatus::Keep(ExecutionStatus::MiscellaneousError(Some( + StatusCode::IO_LIMIT_REACHED + ))) + ); }); } From 8e8187f467a944d89bd69e3c4e188940d3d38f65 Mon Sep 17 00:00:00 2001 From: caojiafeng Date: Sun, 10 Dec 2023 16:59:47 +0800 Subject: [PATCH 15/21] address comments from `alinush` Signed-off-by: caojiafeng --- .../aptos-stdlib/doc/bn254_algebra.md | 98 +--- .../sources/cryptography/bn254_algebra.move | 87 +-- .../cryptography/algebra/arithmetics/add.rs | 39 +- .../cryptography/algebra/arithmetics/div.rs | 31 +- .../algebra/arithmetics/double.rs | 23 +- .../cryptography/algebra/arithmetics/inv.rs | 26 +- .../cryptography/algebra/arithmetics/mul.rs | 32 +- .../cryptography/algebra/arithmetics/neg.rs | 39 +- .../algebra/arithmetics/scalar_mul.rs | 69 +-- .../cryptography/algebra/arithmetics/sqr.rs | 32 +- .../cryptography/algebra/arithmetics/sub.rs | 38 +- .../natives/cryptography/algebra/casting.rs | 21 +- .../natives/cryptography/algebra/constants.rs | 85 +-- .../src/natives/cryptography/algebra/eq.rs | 37 +- .../src/natives/cryptography/algebra/mod.rs | 83 +-- .../src/natives/cryptography/algebra/new.rs | 29 +- .../natives/cryptography/algebra/pairing.rs | 311 +++++------ .../src/natives/cryptography/algebra/rand.rs | 29 +- .../cryptography/algebra/serialization.rs | 515 ++++++++---------- 19 files changed, 526 insertions(+), 1098 deletions(-) diff --git a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md index 806792dc86bc1..e535bcd84fed6 100644 --- a/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md +++ b/aptos-move/framework/aptos-stdlib/doc/bn254_algebra.md @@ -36,7 +36,7 @@ Fq2(1948587475175935477102423926102172050579061846930172106556463129645245747837 266929791119991161246907387137283842545076965332900288569378510910307636690) -Currently-supported BN254 structures include Fq12, Fr, Fq, Fq2, G1, G2 and Gt, +Currently-supported BN254 structures include Fq12, Fr, Fq, Fq2, G1, G2 and Gt, along with their widely-used serialization formats, the pairing between G1, G2 and Gt. @@ -44,15 +44,24 @@ Other unimplemented BN254 structures and serialization formats are also listed h as they help define some of the currently supported structures. Their implementation may also be added in the future. +Fq2: The finite field $F_{q^2}$ that can be used as the base field of $G_2$ +which is an extension field of Fq, constructed as $F_{q^2}=F_{q}[u]/(u^2+1)$. + +FormatFq2LscLsb: A serialization scheme for Fq2 elements, +where an element $(c_0+c_1\cdot u)$ is represented by a byte array b[] of size N=64, +which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first. +- b[0..32] is $c_0$ serialized using FormatFqLscLsb. +- b[32..64] is $c_1$ serialized using FormatFqLscLsb. + Fq6: the finite field $F_{q^6}$ used in BN254 curves, -which is an extension field of Fq2, constructed as $F_{q^6}=F_{q^2}[v]/(v^3-u-9)$. +which is an extension field of Fq2, constructed as $F_{q^6}=F_{q^2}[v]/(v^3-u-9)$. FormatFq6LscLsb: a serialization scheme for Fq6 elements, where an element in the form $(c_0+c_1\cdot v+c_2\cdot v^2)$ is represented by a byte array b[] of size 192, which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first: -- b[0..64] is $c_0$ serialized using FormatFq2LscLsb. -- b[64..128] is $c_1$ serialized using FormatFq2LscLsb. -- b[128..192] is $c_2$ serialized using FormatFq2LscLsb. +- b[0..64] is $c_0$ serialized using FormatFq2LscLsb. +- b[64..128] is $c_1$ serialized using FormatFq2LscLsb. +- b[128..192] is $c_2$ serialized using FormatFq2LscLsb. G1Full: a group constructed by the points on the BN254 curve $E(F_q): y^2=x^3+3$ and the point at infinity, under the elliptic curve point addition. @@ -70,8 +79,6 @@ It contains the prime-order subgroup $G_2$ used in pairing. - [Struct `Fq`](#0x1_bn254_algebra_Fq) - [Struct `FormatFqLsb`](#0x1_bn254_algebra_FormatFqLsb) - [Struct `FormatFqMsb`](#0x1_bn254_algebra_FormatFqMsb) -- [Struct `Fq2`](#0x1_bn254_algebra_Fq2) -- [Struct `FormatFq2LscLsb`](#0x1_bn254_algebra_FormatFq2LscLsb) - [Struct `Fq12`](#0x1_bn254_algebra_Fq12) - [Struct `FormatFq12LscLsb`](#0x1_bn254_algebra_FormatFq12LscLsb) - [Struct `G1`](#0x1_bn254_algebra_G1) @@ -253,69 +260,6 @@ NOTE: other implementation(s) using this format: ark-bn254-0.4.0. -
-Fields - - -
-
-dummy_field: bool -
-
- -
-
- - -
- - - -## Struct `Fq2` - -The finite field $F_{q^2}$ that can be used as the base field of $G_2$ -which is an extension field of Fq, constructed as $F_{q^2}=F_{q}[u]/(u^2+1)$. - - -
struct Fq2
-
- - - -
-Fields - - -
-
-dummy_field: bool -
-
- -
-
- - -
- - - -## Struct `FormatFq2LscLsb` - -A serialization scheme for Fq2 elements, -where an element $(c_0+c_1\cdot u)$ is represented by a byte array b[] of size N=64, -which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first. -- b[0..32] is $c_0$ serialized using FormatFqLsb. -- b[32..64] is $c_1$ serialized using FormatFqLsb. - -NOTE: other implementation(s) using this format: ark-bn254-0.4.0. - - -
struct FormatFq2LscLsb
-
- - -
Fields @@ -338,6 +282,8 @@ NOTE: other implementation(s) using this format: ark-bn254-0.4.0. The finite field $F_{q^12}$ used in BN254 curves, which is an extension field of Fq6 (defined in the module documentation), constructed as $F_{q^12}=F_{q^6}[w]/(w^2-v)$. +The field can downcast to Gt if it's an element of the multiplicative subgroup Gt of Fq12 +with a prime order $r$ = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001.
struct Fq12
@@ -561,7 +507,7 @@ A serialization scheme for G2 element p and outputs a byte array of size N=128.
 1. Let (x,y) be the coordinates of p if p is on the curve, or (0,0) otherwise.
-1. Serialize x and y into b_x[] and b_y[] respectively using FormatFq2LscLsb.
+1. Serialize x and y into b_x[] and b_y[] respectively using FormatFq2LscLsb (defined in the module documentation).
 1. Concatenate b_x[] and b_y[] into b[].
 1. If p is the point at infinity, set the infinity bit: b[N-1]: = b[N-1] | 0b0100_0000.
 1. If y > -y, set the lexicographical bit:  b[N-1]: = b[N-1] | 0b1000_0000.
@@ -571,8 +517,8 @@ Below is the deserialization procedure that takes a byte array b[]
 1. If the size of b[] is not N, return none.
 1. Compute the infinity flag as b[N-1] & 0b0100_0000 != 0.
 1. If the infinity flag is set, return the point at infinity.
-1. Deserialize [b[0], b[1], ..., b[N/2-1]] to x using FormatFq2LscLsb. If x is none, return none.
-1. Deserialize [b[N/2], ..., b[N] & 0b0011_1111] to y using FormatFq2LscLsb. If y is none, return none.
+1. Deserialize [b[0], b[1], ..., b[N/2-1]] to x using FormatFq2LscLsb. If x is none, return none.
+1. Deserialize [b[N/2], ..., b[N] & 0b0011_1111] to y using FormatFq2LscLsb. If y is none, return none.
 1. Check if (x,y) is on curve E. If not, return none.
 1. Check if (x,y) is in the subgroup of order r. If not, return none.
 1. Return (x,y).
@@ -609,7 +555,7 @@ A serialization scheme for G1 element p and outputs a byte array of size N=64.
 1. Let (x,y) be the coordinates of p if p is on the curve, or (0,0) otherwise.
-1. Serialize x into b[] using FormatFq2LscLsb (defined in the module documentation).
+1. Serialize x into b[] using FormatFq2LscLsb (defined in the module documentation).
 1. If p is the point at infinity, set the infinity bit: b[N-1]: = b[N-1] | 0b0100_0000.
 1. If y > -y, set the lexicographical flag: b[N-1] := b[N-1] | 0x1000_0000.
 1. Return b[].
@@ -619,7 +565,7 @@ Below is the deserialization procedure that takes a byte array b[]
 1. Compute the infinity flag as b[N-1] & 0b0100_0000 != 0.
 1. If the infinity flag is set, return the point at infinity.
 1. Compute the lexicographical flag as b[N-1] & 0b1000_0000 != 0.
-1. Deserialize [b[0], b[1], ..., b[N/2-1] & 0b0011_1111] to x using FormatFq2LscLsb. If x is none, return none.
+1. Deserialize [b[0], b[1], ..., b[N/2-1] & 0b0011_1111] to x using FormatFq2LscLsb. If x is none, return none.
 1. Solve the curve equation with x for y. If no such y exists, return none.
 1. Let y' be max(y,-y) if the lexicographical flag is set, or min(y,-y) otherwise.
 1. Check if (x,y') is in the subgroup of order r. If not, return none.
@@ -654,7 +600,7 @@ NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
 ## Struct `Gt`
 
 The group $G_t$ in BN254-based pairing $G_1 \times G_2 \rightarrow G_t$.
-It is a multiplicative subgroup of Fq12,
+It is a multiplicative subgroup of Fq12, so it  can upcast to Fq12.
 with a prime order $r$ equal to 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001.
 (so Fr is the scalar field).
 The identity of Gt is 1.
diff --git a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move
index d07bbc8c38be6..a5cff4df7b289 100644
--- a/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move
+++ b/aptos-move/framework/aptos-stdlib/sources/cryptography/bn254_algebra.move
@@ -35,6 +35,15 @@
 /// as they help define some of the currently supported structures.
 /// Their implementation may also be added in the future.
 ///
+/// `Fq2`: The finite field $F_{q^2}$ that can be used as the base field of $G_2$
+/// which is an extension field of `Fq`, constructed as $F_{q^2}=F_{q}[u]/(u^2+1)$.
+///
+/// `FormatFq2LscLsb`: A serialization scheme for `Fq2` elements,
+/// where an element $(c_0+c_1\cdot u)$ is represented by a byte array `b[]` of size N=64,
+/// which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first.
+/// - `b[0..32]` is $c_0$ serialized using `FormatFqLscLsb`.
+/// - `b[32..64]` is $c_1$ serialized using `FormatFqLscLsb`.
+///
 /// `Fq6`: the finite field $F_{q^6}$ used in BN254 curves,
 /// which is an extension field of `Fq2`, constructed as $F_{q^6}=F_{q^2}[v]/(v^3-u-9)$.
 ///
@@ -88,21 +97,10 @@ module std::bn254_algebra {
     /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
     struct FormatFqMsb {}
 
-    /// The finite field $F_{q^2}$ that can be used as the base field of $G_2$
-    /// which is an extension field of `Fq`, constructed as $F_{q^2}=F_{q}[u]/(u^2+1)$.
-    struct Fq2 {}
-
-    /// A serialization scheme for `Fq2` elements,
-    /// where an element $(c_0+c_1\cdot u)$ is represented by a byte array `b[]` of size N=64,
-    /// which is a concatenation of its coefficients serialized, with the least significant coefficient (LSC) coming first.
-    /// - `b[0..32]` is $c_0$ serialized using `FormatFqLsb`.
-    /// - `b[32..64]` is $c_1$ serialized using `FormatFqLsb`.
-    ///
-    /// NOTE: other implementation(s) using this format: ark-bn254-0.4.0.
-    struct FormatFq2LscLsb {}
-
     /// The finite field $F_{q^12}$ used in BN254 curves,
     /// which is an extension field of `Fq6` (defined in the module documentation), constructed as $F_{q^12}=F_{q^6}[w]/(w^2-v)$.
+    /// The field can downcast to `Gt` if it's an element of the multiplicative subgroup `Gt` of `Fq12`
+    /// with a prime order $r$ = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001.
     struct Fq12 {}
     /// A serialization scheme for `Fq12` elements,
     /// where an element $(c_0+c_1\cdot w)$ is represented by a byte array `b[]` of size 384,
@@ -175,7 +173,7 @@ module std::bn254_algebra {
     ///
     /// Below is the serialization procedure that takes a `G2` element `p` and outputs a byte array of size N=128.
     /// 1. Let `(x,y)` be the coordinates of `p` if `p` is on the curve, or `(0,0)` otherwise.
-    /// 1. Serialize `x` and `y` into `b_x[]` and `b_y[]` respectively using `FormatFq2LscLsb`.
+    /// 1. Serialize `x` and `y` into `b_x[]` and `b_y[]` respectively using `FormatFq2LscLsb` (defined in the module documentation).
     /// 1. Concatenate `b_x[]` and `b_y[]` into `b[]`.
     /// 1. If `p` is the point at infinity, set the infinity bit: `b[N-1]: = b[N-1] | 0b0100_0000`.
     /// 1. If `y > -y`, set the lexicographical bit:  `b[N-1]: = b[N-1] | 0b1000_0000`.
@@ -218,7 +216,7 @@ module std::bn254_algebra {
     struct FormatG2Compr {}
 
     /// The group $G_t$ in BN254-based pairing $G_1 \times G_2 \rightarrow G_t$.
-    /// It is a multiplicative subgroup of `Fq12`,
+    /// It is a multiplicative subgroup of `Fq12`, so it  can upcast to `Fq12`.
     /// with a prime order $r$ equal to 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001.
     /// (so `Fr` is the scalar field).
     /// The identity of `Gt` is 1.
@@ -235,17 +233,6 @@ module std::bn254_algebra {
 
     // Tests begin.
 
-    #[test_only]
-    const FQ2_VAL_0_SERIALIZED: vector = x"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
-    #[test_only]
-    const FQ2_VAL_1_SERIALIZED: vector = x"01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
-    #[test_only]
-    const FQ2_VAL_7_SERIALIZED: vector = x"07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
-    #[test_only]
-    const FQ2_VAL_7_NEG_SERIALIZED: vector = x"40fd7cd8168c203c8dca7168916a81975d588181b64550b829a031e1724e64300000000000000000000000000000000000000000000000000000000000000000";
-    #[test_only]
-    const Q2_SERIALIZED: vector = x"b1695d27a258543b01c1ea092d0702a6dcca966d9c18504ac842127a959e68048db3c6345cfaed260656371651850bb01cd248037c6f9a599cbf3c76b8c42509";
-
     #[test_only]
     fun rand_vector(num: u64): vector> {
         let elements = vector[];
@@ -256,54 +243,6 @@ module std::bn254_algebra {
         elements
     }
 
-    #[test(fx = @std)]
-    fun test_fq2(fx: signer) {
-        enable_cryptography_algebra_natives(&fx);
-
-        // Constants.
-        assert!(Q2_SERIALIZED == order(), 1);
-
-        // Serialization/deserialization.
-        let val_0 = zero();
-        let val_1 = one();
-        assert!(FQ2_VAL_0_SERIALIZED == serialize(&val_0), 1);
-        assert!(FQ2_VAL_1_SERIALIZED == serialize(&val_1), 1);
-        let val_7 = from_u64(7);
-        let val_7_another = std::option::extract(&mut deserialize(&FQ2_VAL_7_SERIALIZED));
-        assert!(eq(&val_7, &val_7_another), 1);
-        assert!(FQ2_VAL_7_SERIALIZED == serialize(&val_7), 1);
-        assert!(std::option::is_none(&deserialize(&x"ffff")), 1);
-
-        // Negation.
-        let val_minus_7 = neg(&val_7);
-        assert!(FQ2_VAL_7_NEG_SERIALIZED == serialize(&val_minus_7), 1);
-
-        // Addition.
-        let val_9 = from_u64(9);
-        let val_2 = from_u64(2);
-        assert!(eq(&val_2, &add(&val_minus_7, &val_9)), 1);
-
-        // Subtraction.
-        assert!(eq(&val_9, &sub(&val_2, &val_minus_7)), 1);
-
-        // Multiplication.
-        let val_63 = from_u64(63);
-        assert!(eq(&val_63, &mul(&val_7, &val_9)), 1);
-
-        // division.
-        let val_0 = from_u64(0);
-        assert!(eq(&val_7, &std::option::extract(&mut div(&val_63, &val_9))), 1);
-        assert!(std::option::is_none(&div(&val_63, &val_0)), 1);
-
-        // Inversion.
-        assert!(eq(&val_minus_7, &neg(&val_7)), 1);
-        assert!(std::option::is_none(&inv(&val_0)), 1);
-
-        // Squaring.
-        let val_x = rand_insecure();
-        assert!(eq(&mul(&val_x, &val_x), &sqr(&val_x)), 1);
-    }
-
 
     #[test_only]
     const FQ12_VAL_0_SERIALIZED: vector = x"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/add.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/add.rs
index 8b1fce1f0fff9..96bde2b536b4e 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/add.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/add.rs
@@ -4,8 +4,8 @@ use crate::{
     abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled,
     ark_binary_op_internal,
     natives::cryptography::algebra::{
-        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure,
-        Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure,
+        E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     safe_borrow_element, store_element, structure_from_ty_arg,
 };
@@ -63,59 +63,42 @@ pub fn add_internal(
             mul,
             ALGEBRA_ARK_BLS12_381_FQ12_MUL
         ),
-        Some(Structure::BN254(s)) => add_internal_bn254(context, args, s),
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn add_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr => {
+        Some(Structure::BN254Fr) => {
             ark_binary_op_internal!(context, args, ark_bn254::Fr, add, ALGEBRA_ARK_BN254_FR_ADD)
         },
-        BN254Structure::BN254Fq => {
+        Some(Structure::BN254Fq) => {
             ark_binary_op_internal!(context, args, ark_bn254::Fq, add, ALGEBRA_ARK_BN254_FQ_ADD)
         },
-        BN254Structure::BN254Fq2 => ark_binary_op_internal!(
-            context,
-            args,
-            ark_bn254::Fq2,
-            add,
-            ALGEBRA_ARK_BN254_FQ2_ADD
-        ),
-        BN254Structure::BN254Fq12 => ark_binary_op_internal!(
+        Some(Structure::BN254Fq12) => ark_binary_op_internal!(
             context,
             args,
             ark_bn254::Fq12,
             add,
             ALGEBRA_ARK_BN254_FQ12_ADD
         ),
-        BN254Structure::BN254G1 => ark_binary_op_internal!(
+        Some(Structure::BN254G1) => ark_binary_op_internal!(
             context,
             args,
             ark_bn254::G1Projective,
             add,
             ALGEBRA_ARK_BN254_G1_PROJ_ADD
         ),
-        BN254Structure::BN254G2 => ark_binary_op_internal!(
+        Some(Structure::BN254G2) => ark_binary_op_internal!(
             context,
             args,
             ark_bn254::G2Projective,
             add,
             ALGEBRA_ARK_BN254_G2_PROJ_ADD
         ),
-        BN254Structure::BN254Gt => ark_binary_op_internal!(
+        Some(Structure::BN254Gt) => ark_binary_op_internal!(
             context,
             args,
             ark_bn254::Fq12,
             mul,
             ALGEBRA_ARK_BN254_FQ12_MUL
         ),
+        _ => Err(SafeNativeError::Abort {
+            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        }),
     }
 }
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/div.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/div.rs
index 688eb53879a34..b57e73aaf52c8 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/div.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/div.rs
@@ -3,8 +3,8 @@
 use crate::{
     abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled,
     natives::cryptography::algebra::{
-        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure,
-        Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure,
+        E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     safe_borrow_element, store_element, structure_from_ty_arg,
 };
@@ -59,20 +59,7 @@ pub fn div_internal(
             ALGEBRA_ARK_BLS12_381_FQ12_EQ,
             ALGEBRA_ARK_BLS12_381_FQ12_DIV
         ),
-        Some(Structure::BN254(s)) => div_internal_bn254(context, args, s),
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn div_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr => ark_div_internal!(
+        Some(Structure::BN254Fr) => ark_div_internal!(
             context,
             args,
             ark_bn254::Fr,
@@ -80,7 +67,7 @@ fn div_internal_bn254(
             ALGEBRA_ARK_BN254_FR_EQ,
             ALGEBRA_ARK_BN254_FR_DIV
         ),
-        BN254Structure::BN254Fq => ark_div_internal!(
+        Some(Structure::BN254Fq) => ark_div_internal!(
             context,
             args,
             ark_bn254::Fq,
@@ -88,15 +75,7 @@ fn div_internal_bn254(
             ALGEBRA_ARK_BN254_FQ_EQ,
             ALGEBRA_ARK_BN254_FQ_DIV
         ),
-        BN254Structure::BN254Fq2 => ark_div_internal!(
-            context,
-            args,
-            ark_bn254::Fq2,
-            div,
-            ALGEBRA_ARK_BN254_FQ2_EQ,
-            ALGEBRA_ARK_BN254_FQ2_DIV
-        ),
-        BN254Structure::BN254Fq12 => ark_div_internal!(
+        Some(Structure::BN254Fq12) => ark_div_internal!(
             context,
             args,
             ark_bn254::Fq12,
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/double.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/double.rs
index 9a6ed0190c9f6..afeaf4398ac5d 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/double.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/double.rs
@@ -4,8 +4,8 @@ use crate::{
     abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled,
     ark_unary_op_internal,
     natives::cryptography::algebra::{
-        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure,
-        Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure,
+        E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     safe_borrow_element, store_element, structure_from_ty_arg,
 };
@@ -47,34 +47,21 @@ pub fn double_internal(
             square,
             ALGEBRA_ARK_BLS12_381_FQ12_SQUARE
         ),
-        Some(Structure::BN254(s)) => double_internal_bn254(context, args, s),
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn double_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254G1 => ark_unary_op_internal!(
+        Some(Structure::BN254G1) => ark_unary_op_internal!(
             context,
             args,
             ark_bn254::G1Projective,
             double,
             ALGEBRA_ARK_BN254_G1_PROJ_DOUBLE
         ),
-        BN254Structure::BN254G2 => ark_unary_op_internal!(
+        Some(Structure::BN254G2) => ark_unary_op_internal!(
             context,
             args,
             ark_bn254::G2Projective,
             double,
             ALGEBRA_ARK_BN254_G2_PROJ_DOUBLE
         ),
-        BN254Structure::BN254Gt => ark_unary_op_internal!(
+        Some(Structure::BN254Gt) => ark_unary_op_internal!(
             context,
             args,
             ark_bn254::Fq12,
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/inv.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/inv.rs
index e73a3302d18d1..4b18e7c2481f1 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/inv.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/inv.rs
@@ -3,8 +3,8 @@
 use crate::{
     abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled,
     natives::cryptography::algebra::{
-        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure,
-        Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure,
+        E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     safe_borrow_element, store_element, structure_from_ty_arg,
 };
@@ -52,29 +52,13 @@ pub fn inv_internal(
             ark_bls12_381::Fq12,
             ALGEBRA_ARK_BLS12_381_FQ12_INV
         ),
-        Some(Structure::BN254(s)) => inv_internal_bn254(context, args, s),
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn inv_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr => {
+        Some(Structure::BN254Fr) => {
             ark_inverse_internal!(context, args, ark_bn254::Fr, ALGEBRA_ARK_BN254_FR_INV)
         },
-        BN254Structure::BN254Fq => {
+        Some(Structure::BN254Fq) => {
             ark_inverse_internal!(context, args, ark_bn254::Fq, ALGEBRA_ARK_BN254_FQ_INV)
         },
-        BN254Structure::BN254Fq2 => {
-            ark_inverse_internal!(context, args, ark_bn254::Fq2, ALGEBRA_ARK_BN254_FQ2_INV)
-        },
-        BN254Structure::BN254Fq12 => {
+        Some(Structure::BN254Fq12) => {
             ark_inverse_internal!(context, args, ark_bn254::Fq12, ALGEBRA_ARK_BN254_FQ12_INV)
         },
         _ => Err(SafeNativeError::Abort {
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/mul.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/mul.rs
index e377522e84673..c35ae84f63e11 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/mul.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/mul.rs
@@ -4,8 +4,8 @@ use crate::{
     abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled,
     ark_binary_op_internal,
     natives::cryptography::algebra::{
-        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure,
-        Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure,
+        E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     safe_borrow_element, store_element, structure_from_ty_arg,
 };
@@ -38,35 +38,13 @@ pub fn mul_internal(
             mul,
             ALGEBRA_ARK_BLS12_381_FQ12_MUL
         ),
-        Some(Structure::BN254(s)) => mul_internal_bn254(context, args, s),
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn mul_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr => {
+        Some(Structure::BN254Fr) => {
             ark_binary_op_internal!(context, args, ark_bn254::Fr, mul, ALGEBRA_ARK_BN254_FR_MUL)
         },
-        BN254Structure::BN254Fq => {
+        Some(Structure::BN254Fq) => {
             ark_binary_op_internal!(context, args, ark_bn254::Fq, mul, ALGEBRA_ARK_BN254_FQ_MUL)
         },
-        BN254Structure::BN254Fq2 => {
-            ark_binary_op_internal!(
-                context,
-                args,
-                ark_bn254::Fq2,
-                mul,
-                ALGEBRA_ARK_BN254_FQ2_MUL
-            )
-        },
-        BN254Structure::BN254Fq12 => {
+        Some(Structure::BN254Fq12) => {
             ark_binary_op_internal!(
                 context,
                 args,
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/neg.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/neg.rs
index 96a371eae35f6..3a339e507ad75 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/neg.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/neg.rs
@@ -4,8 +4,8 @@ use crate::{
     abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled,
     ark_unary_op_internal,
     natives::cryptography::algebra::{
-        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure,
-        Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure,
+        E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     safe_borrow_element, store_element, structure_from_ty_arg,
 };
@@ -63,54 +63,34 @@ pub fn neg_internal(
             let new_handle = store_element!(context, new_element)?;
             Ok(smallvec![Value::u64(new_handle as u64)])
         },
-        Some(Structure::BN254(s)) => neg_internal_bn254(context, args, s),
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn neg_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr => {
+        Some(Structure::BN254Fr) => {
             ark_unary_op_internal!(context, args, ark_bn254::Fr, neg, ALGEBRA_ARK_BN254_FR_NEG)
         },
-        BN254Structure::BN254Fq => {
+        Some(Structure::BN254Fq) => {
             ark_unary_op_internal!(context, args, ark_bn254::Fq, neg, ALGEBRA_ARK_BN254_FQ_NEG)
         },
-        BN254Structure::BN254Fq2 => ark_unary_op_internal!(
-            context,
-            args,
-            ark_bn254::Fq2,
-            neg,
-            ALGEBRA_ARK_BN254_FQ2_NEG
-        ),
-        BN254Structure::BN254Fq12 => ark_unary_op_internal!(
+        Some(Structure::BN254Fq12) => ark_unary_op_internal!(
             context,
             args,
             ark_bn254::Fq12,
             neg,
             ALGEBRA_ARK_BN254_FQ12_NEG
         ),
-        BN254Structure::BN254G1 => ark_unary_op_internal!(
+        Some(Structure::BN254G1) => ark_unary_op_internal!(
             context,
             args,
             ark_bn254::G1Projective,
             neg,
             ALGEBRA_ARK_BN254_G1_PROJ_NEG
         ),
-        BN254Structure::BN254G2 => ark_unary_op_internal!(
+        Some(Structure::BN254G2) => ark_unary_op_internal!(
             context,
             args,
             ark_bn254::G2Projective,
             neg,
             ALGEBRA_ARK_BN254_G2_PROJ_NEG
         ),
-        BN254Structure::BN254Gt => {
+        Some(Structure::BN254Gt) => {
             let handle = safely_pop_arg!(args, u64) as usize;
             safe_borrow_element!(context, handle, ark_bn254::Fq12, element_ptr, element);
             context.charge(ALGEBRA_ARK_BN254_FQ12_INV)?;
@@ -118,5 +98,8 @@ fn neg_internal_bn254(
             let new_handle = store_element!(context, new_element)?;
             Ok(smallvec![Value::u64(new_handle as u64)])
         },
+        _ => Err(SafeNativeError::Abort {
+            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        }),
     }
 }
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/scalar_mul.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/scalar_mul.rs
index e62961789cde2..29108510741c4 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/scalar_mul.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/scalar_mul.rs
@@ -4,9 +4,9 @@ use crate::{
     abort_unless_feature_flag_enabled,
     natives::cryptography::{
         algebra::{
-            abort_invariant_violated, AlgebraContext, BN254Structure, Structure,
-            E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES,
-            MOVE_ABORT_CODE_INPUT_VECTOR_SIZES_NOT_MATCHING, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+            abort_invariant_violated, AlgebraContext, Structure, E_TOO_MUCH_MEMORY_USED,
+            MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_INPUT_VECTOR_SIZES_NOT_MATCHING,
+            MOVE_ABORT_CODE_NOT_IMPLEMENTED,
         },
         helpers::log2_ceil,
     },
@@ -35,18 +35,11 @@ fn feature_flag_of_group_scalar_mul(
         | (Some(Structure::BLS12381Gt), Some(Structure::BLS12381Fr)) => {
             Some(FeatureFlag::BLS12_381_STRUCTURES)
         },
-        (
-            Some(Structure::BN254(BN254Structure::BN254G1)),
-            Some(Structure::BN254(BN254Structure::BN254Fr)),
-        )
-        | (
-            Some(Structure::BN254(BN254Structure::BN254G2)),
-            Some(Structure::BN254(BN254Structure::BN254Fr)),
-        )
-        | (
-            Some(Structure::BN254(BN254Structure::BN254Gt)),
-            Some(Structure::BN254(BN254Structure::BN254Fr)),
-        ) => Some(FeatureFlag::BN254_STRUCTURES),
+        (Some(Structure::BN254G1), Some(Structure::BN254Fr))
+        | (Some(Structure::BN254G2), Some(Structure::BN254Fr))
+        | (Some(Structure::BN254Gt), Some(Structure::BN254Fr)) => {
+            Some(FeatureFlag::BN254_STRUCTURES)
+        },
 
         _ => None,
     }
@@ -147,24 +140,7 @@ pub fn scalar_mul_internal(
             let new_handle = store_element!(context, new_element)?;
             Ok(smallvec![Value::u64(new_handle as u64)])
         },
-        (
-            Some(Structure::BN254(group_structure)),
-            Some(Structure::BN254(scalar_field_structure)),
-        ) => scalar_mul_internal_bn254(context, args, group_structure, scalar_field_structure),
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn scalar_mul_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    group_structure: BN254Structure,
-    scalar_field_structure: BN254Structure,
-) -> SafeNativeResult> {
-    match (group_structure, scalar_field_structure) {
-        (BN254Structure::BN254G1, BN254Structure::BN254Fr) => {
+        (Some(Structure::BN254G1), Some(Structure::BN254Fr)) => {
             ark_scalar_mul_internal!(
                 context,
                 args,
@@ -174,7 +150,7 @@ fn scalar_mul_internal_bn254(
                 ALGEBRA_ARK_BN254_G1_PROJ_SCALAR_MUL
             )
         },
-        (BN254Structure::BN254G2, BN254Structure::BN254Fr) => {
+        (Some(Structure::BN254G2), Some(Structure::BN254Fr)) => {
             ark_scalar_mul_internal!(
                 context,
                 args,
@@ -184,7 +160,7 @@ fn scalar_mul_internal_bn254(
                 ALGEBRA_ARK_BN254_G2_PROJ_SCALAR_MUL
             )
         },
-        (BN254Structure::BN254Gt, BN254Structure::BN254Fr) => {
+        (Some(Structure::BN254Gt), Some(Structure::BN254Fr)) => {
             let scalar_handle = safely_pop_arg!(args, u64) as usize;
             let element_handle = safely_pop_arg!(args, u64) as usize;
             safe_borrow_element!(
@@ -287,26 +263,7 @@ pub fn multi_scalar_mul_internal(
                 ark_bls12_381::Fr
             )
         },
-        (
-            Some(Structure::BN254(group_structure)),
-            Some(Structure::BN254(scalar_field_structure)),
-        ) => {
-            multi_scalar_mul_internal_bn254(context, args, group_structure, scalar_field_structure)
-        },
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn multi_scalar_mul_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    group_structure: BN254Structure,
-    scalar_field_structure: BN254Structure,
-) -> SafeNativeResult> {
-    match (group_structure, scalar_field_structure) {
-        (BN254Structure::BN254G1, BN254Structure::BN254Fr) => {
+        (Some(Structure::BN254G1), Some(Structure::BN254Fr)) => {
             ark_msm_internal!(
                 context,
                 args,
@@ -317,7 +274,7 @@ fn multi_scalar_mul_internal_bn254(
                 ark_bn254::Fr
             )
         },
-        (BN254Structure::BN254G2, BN254Structure::BN254Fr) => {
+        (Some(Structure::BN254G2), Some(Structure::BN254Fr)) => {
             ark_msm_internal!(
                 context,
                 args,
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sqr.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sqr.rs
index bcf36dcbc473e..f02921c2830f6 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sqr.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sqr.rs
@@ -4,8 +4,8 @@ use crate::{
     abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled,
     ark_unary_op_internal,
     natives::cryptography::algebra::{
-        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure,
-        Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure,
+        E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     safe_borrow_element, store_element, structure_from_ty_arg,
 };
@@ -38,20 +38,7 @@ pub fn sqr_internal(
             square,
             ALGEBRA_ARK_BLS12_381_FQ12_SQUARE
         ),
-        Some(Structure::BN254(s)) => sqr_internal_bn254(context, args, s),
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn sqr_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr => {
+        Some(Structure::BN254Fr) => {
             ark_unary_op_internal!(
                 context,
                 args,
@@ -60,7 +47,7 @@ fn sqr_internal_bn254(
                 ALGEBRA_ARK_BN254_FR_SQUARE
             )
         },
-        BN254Structure::BN254Fq => {
+        Some(Structure::BN254Fq) => {
             ark_unary_op_internal!(
                 context,
                 args,
@@ -69,16 +56,7 @@ fn sqr_internal_bn254(
                 ALGEBRA_ARK_BN254_FQ_SQUARE
             )
         },
-        BN254Structure::BN254Fq2 => {
-            ark_unary_op_internal!(
-                context,
-                args,
-                ark_bn254::Fq2,
-                square,
-                ALGEBRA_ARK_BN254_FQ2_SQUARE
-            )
-        },
-        BN254Structure::BN254Fq12 => {
+        Some(Structure::BN254Fq12) => {
             ark_unary_op_internal!(
                 context,
                 args,
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sub.rs b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sub.rs
index 8b586a33ed065..6aff9fd65fd53 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sub.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/arithmetics/sub.rs
@@ -4,8 +4,8 @@ use crate::{
     abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled,
     ark_binary_op_internal,
     natives::cryptography::algebra::{
-        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure,
-        Structure, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure,
+        E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     safe_borrow_element, store_element, structure_from_ty_arg,
 };
@@ -63,59 +63,43 @@ pub fn sub_internal(
             div,
             ALGEBRA_ARK_BLS12_381_FQ12_DIV
         ),
-        Some(Structure::BN254(s)) => sub_internal_bn254(context, args, s),
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
 
-fn sub_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr => {
+        Some(Structure::BN254Fr) => {
             ark_binary_op_internal!(context, args, ark_bn254::Fr, sub, ALGEBRA_ARK_BN254_FR_SUB)
         },
-        BN254Structure::BN254Fq => {
+        Some(Structure::BN254Fq) => {
             ark_binary_op_internal!(context, args, ark_bn254::Fq, sub, ALGEBRA_ARK_BN254_FQ_SUB)
         },
-        BN254Structure::BN254Fq2 => ark_binary_op_internal!(
-            context,
-            args,
-            ark_bn254::Fq2,
-            sub,
-            ALGEBRA_ARK_BN254_FQ2_SUB
-        ),
-        BN254Structure::BN254Fq12 => ark_binary_op_internal!(
+        Some(Structure::BN254Fq12) => ark_binary_op_internal!(
             context,
             args,
             ark_bn254::Fq12,
             sub,
             ALGEBRA_ARK_BN254_FQ12_SUB
         ),
-        BN254Structure::BN254G1 => ark_binary_op_internal!(
+        Some(Structure::BN254G1) => ark_binary_op_internal!(
             context,
             args,
             ark_bn254::G1Projective,
             sub,
             ALGEBRA_ARK_BN254_G1_PROJ_SUB
         ),
-        BN254Structure::BN254G2 => ark_binary_op_internal!(
+        Some(Structure::BN254G2) => ark_binary_op_internal!(
             context,
             args,
             ark_bn254::G2Projective,
             sub,
             ALGEBRA_ARK_BN254_G2_PROJ_SUB
         ),
-        BN254Structure::BN254Gt => ark_binary_op_internal!(
+        Some(Structure::BN254Gt) => ark_binary_op_internal!(
             context,
             args,
             ark_bn254::Fq12,
             div,
             ALGEBRA_ARK_BN254_FQ12_DIV
         ),
+        _ => Err(SafeNativeError::Abort {
+            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        }),
     }
 }
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/casting.rs b/aptos-move/framework/src/natives/cryptography/algebra/casting.rs
index 26a71b07c8118..309d3df24079a 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/casting.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/casting.rs
@@ -3,8 +3,8 @@
 use crate::{
     abort_unless_feature_flag_enabled,
     natives::cryptography::algebra::{
-        abort_invariant_violated, AlgebraContext, BN254Structure, Structure, BLS12381_R_SCALAR,
-        BN254_R_SCALAR, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        abort_invariant_violated, AlgebraContext, Structure, BLS12381_R_SCALAR, BN254_R_SCALAR,
+        MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     safe_borrow_element, structure_from_ty_arg,
 };
@@ -27,10 +27,9 @@ fn feature_flag_of_casting(
         (Some(Structure::BLS12381Fq12), Some(Structure::BLS12381Gt)) => {
             Some(FeatureFlag::BLS12_381_STRUCTURES)
         },
-        (
-            Some(Structure::BN254(BN254Structure::BN254Fq12)),
-            Some(Structure::BN254(BN254Structure::BN254Gt)),
-        ) => Some(FeatureFlag::BN254_STRUCTURES),
+        (Some(Structure::BN254Fq12), Some(Structure::BN254Gt)) => {
+            Some(FeatureFlag::BN254_STRUCTURES)
+        },
         _ => None,
     }
 }
@@ -62,10 +61,7 @@ pub fn downcast_internal(
                 Ok(smallvec![Value::bool(false), Value::u64(handle as u64)])
             }
         },
-        (
-            Some(Structure::BN254(BN254Structure::BN254Fq12)),
-            Some(Structure::BN254(BN254Structure::BN254Gt)),
-        ) => {
+        (Some(Structure::BN254Fq12), Some(Structure::BN254Gt)) => {
             let handle = safely_pop_arg!(args, u64) as usize;
             safe_borrow_element!(context, handle, ark_bn254::Fq12, element_ptr, element);
             context.charge(ALGEBRA_ARK_BN254_FQ12_POW_U256)?;
@@ -95,10 +91,7 @@ pub fn upcast_internal(
             let handle = safely_pop_arg!(args, u64);
             Ok(smallvec![Value::u64(handle)])
         },
-        (
-            Some(Structure::BN254(BN254Structure::BN254Gt)),
-            Some(Structure::BN254(BN254Structure::BN254Fq12)),
-        ) => {
+        (Some(Structure::BN254Gt), Some(Structure::BN254Fq12)) => {
             let handle = safely_pop_arg!(args, u64);
             Ok(smallvec![Value::u64(handle)])
         },
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/constants.rs b/aptos-move/framework/src/natives/cryptography/algebra/constants.rs
index f4d12284e59e7..abee6b1e4f054 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/constants.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/constants.rs
@@ -3,10 +3,9 @@
 use crate::{
     abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled,
     natives::cryptography::algebra::{
-        feature_flag_from_structure, AlgebraContext, BN254Structure, Structure,
-        BLS12381_GT_GENERATOR, BLS12381_Q12_LENDIAN, BLS12381_R_LENDIAN, BN254_GT_GENERATOR,
-        BN254_Q12_LENDIAN, BN254_Q2_LENDIAN, BN254_Q_LENDIAN, BN254_R_LENDIAN,
-        E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        feature_flag_from_structure, AlgebraContext, Structure, BLS12381_GT_GENERATOR,
+        BLS12381_Q12_LENDIAN, BLS12381_R_LENDIAN, BN254_GT_GENERATOR, BN254_Q12_LENDIAN, BN254_Q_LENDIAN, BN254_R_LENDIAN, E_TOO_MUCH_MEMORY_USED,
+        MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     store_element, structure_from_ty_arg,
 };
@@ -66,44 +65,33 @@ pub fn zero_internal(
             one,
             ALGEBRA_ARK_BLS12_381_FQ12_ONE
         ),
-        Some(Structure::BN254(s)) => zero_internal_bn254(context, s),
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-pub fn zero_internal_bn254(
-    context: &mut SafeNativeContext,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr => {
+        Some(Structure::BN254Fr) => {
             ark_constant_op_internal!(context, ark_bn254::Fr, zero, ALGEBRA_ARK_BN254_FR_ZERO)
         },
-        BN254Structure::BN254Fq => {
+        Some(Structure::BN254Fq) => {
             ark_constant_op_internal!(context, ark_bn254::Fq, zero, ALGEBRA_ARK_BN254_FQ_ZERO)
         },
-        BN254Structure::BN254Fq2 => {
-            ark_constant_op_internal!(context, ark_bn254::Fq2, zero, ALGEBRA_ARK_BN254_FQ2_ZERO)
-        },
-        BN254Structure::BN254Fq12 => {
+        Some(Structure::BN254Fq12) => {
             ark_constant_op_internal!(context, ark_bn254::Fq12, zero, ALGEBRA_ARK_BN254_FQ12_ZERO)
         },
-        BN254Structure::BN254G1 => ark_constant_op_internal!(
+        Some(Structure::BN254G1) => ark_constant_op_internal!(
             context,
             ark_bn254::G1Projective,
             zero,
             ALGEBRA_ARK_BN254_G1_PROJ_INFINITY
         ),
-        BN254Structure::BN254G2 => ark_constant_op_internal!(
+        Some(Structure::BN254G2) => ark_constant_op_internal!(
             context,
             ark_bn254::G2Projective,
             zero,
             ALGEBRA_ARK_BN254_G2_PROJ_INFINITY
         ),
-        BN254Structure::BN254Gt => {
+        Some(Structure::BN254Gt) => {
             ark_constant_op_internal!(context, ark_bn254::Fq12, one, ALGEBRA_ARK_BN254_FQ12_ONE)
         },
+        _ => Err(SafeNativeError::Abort {
+            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        }),
     }
 }
 
@@ -145,47 +133,36 @@ pub fn one_internal(
             let handle = store_element!(context, element)?;
             Ok(smallvec![Value::u64(handle as u64)])
         },
-        Some(Structure::BN254(s)) => one_internal_bn254(context, s),
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-fn one_internal_bn254(
-    context: &mut SafeNativeContext,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr => {
+        Some(Structure::BN254Fr) => {
             ark_constant_op_internal!(context, ark_bn254::Fr, one, ALGEBRA_ARK_BLS12_381_FR_ONE)
         },
-        BN254Structure::BN254Fq => {
+        Some(Structure::BN254Fq) => {
             ark_constant_op_internal!(context, ark_bn254::Fq, one, ALGEBRA_ARK_BN254_FQ_ONE)
         },
-        BN254Structure::BN254Fq2 => {
-            ark_constant_op_internal!(context, ark_bn254::Fq2, one, ALGEBRA_ARK_BN254_FQ2_ONE)
-        },
-        BN254Structure::BN254Fq12 => {
+        Some(Structure::BN254Fq12) => {
             ark_constant_op_internal!(context, ark_bn254::Fq12, one, ALGEBRA_ARK_BN254_FQ12_ONE)
         },
-        BN254Structure::BN254G1 => ark_constant_op_internal!(
+        Some(Structure::BN254G1) => ark_constant_op_internal!(
             context,
             ark_bn254::G1Projective,
             generator,
             ALGEBRA_ARK_BN254_G1_PROJ_GENERATOR
         ),
-        BN254Structure::BN254G2 => ark_constant_op_internal!(
+        Some(Structure::BN254G2) => ark_constant_op_internal!(
             context,
             ark_bn254::G2Projective,
             generator,
             ALGEBRA_ARK_BN254_G2_PROJ_GENERATOR
         ),
-        BN254Structure::BN254Gt => {
+        Some(Structure::BN254Gt) => {
             context.charge(ALGEBRA_ARK_BN254_FQ12_CLONE)?;
             let element = *Lazy::force(&BN254_GT_GENERATOR);
             let handle = store_element!(context, element)?;
             Ok(smallvec![Value::u64(handle as u64)])
         },
+        _ => Err(SafeNativeError::Abort {
+            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        }),
     }
 }
 
@@ -207,22 +184,14 @@ pub fn order_internal(
         Some(Structure::BLS12381Fq12) => {
             Ok(smallvec![Value::vector_u8(BLS12381_Q12_LENDIAN.clone())])
         },
-        Some(Structure::BN254(s)) => order_internal_bn254(s),
+        Some(Structure::BN254Fr)
+        | Some(Structure::BN254Gt)
+        | Some(Structure::BN254G1)
+        | Some(Structure::BN254G2) => Ok(smallvec![Value::vector_u8(BN254_R_LENDIAN.clone())]),
+        Some(Structure::BN254Fq) => Ok(smallvec![Value::vector_u8(BN254_Q_LENDIAN.clone())]),
+        Some(Structure::BN254Fq12) => Ok(smallvec![Value::vector_u8(BN254_Q12_LENDIAN.clone())]),
         _ => Err(SafeNativeError::Abort {
             abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
         }),
     }
 }
-
-#[inline]
-fn order_internal_bn254(structure: BN254Structure) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr
-        | BN254Structure::BN254Gt
-        | BN254Structure::BN254G1
-        | BN254Structure::BN254G2 => Ok(smallvec![Value::vector_u8(BN254_R_LENDIAN.clone())]),
-        BN254Structure::BN254Fq => Ok(smallvec![Value::vector_u8(BN254_Q_LENDIAN.clone())]),
-        BN254Structure::BN254Fq2 => Ok(smallvec![Value::vector_u8(BN254_Q2_LENDIAN.clone())]),
-        BN254Structure::BN254Fq12 => Ok(smallvec![Value::vector_u8(BN254_Q12_LENDIAN.clone())]),
-    }
-}
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/eq.rs b/aptos-move/framework/src/natives/cryptography/algebra/eq.rs
index 4b7bbdb1c717e..0b33ed77b998e 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/eq.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/eq.rs
@@ -3,8 +3,8 @@
 use crate::{
     abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled,
     natives::cryptography::algebra::{
-        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, BN254Structure,
-        Structure, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        abort_invariant_violated, feature_flag_from_structure, AlgebraContext, Structure,
+        MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     safe_borrow_element, structure_from_ty_arg,
 };
@@ -67,34 +67,16 @@ pub fn eq_internal(
             ark_bls12_381::Fq12,
             ALGEBRA_ARK_BLS12_381_FQ12_EQ
         ),
-        Some(Structure::BN254(bn254_structure)) => {
-            eq_internal_bn254(context, args, bn254_structure)
-        },
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn eq_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr => {
+        Some(Structure::BN254Fr) => {
             ark_eq_internal!(context, args, ark_bn254::Fr, ALGEBRA_ARK_BN254_FR_EQ)
         },
-        BN254Structure::BN254Fq => {
+        Some(Structure::BN254Fq) => {
             ark_eq_internal!(context, args, ark_bn254::Fq, ALGEBRA_ARK_BN254_FQ_EQ)
         },
-        BN254Structure::BN254Fq2 => {
-            ark_eq_internal!(context, args, ark_bn254::Fq2, ALGEBRA_ARK_BN254_FQ2_EQ)
-        },
-        BN254Structure::BN254Fq12 => {
+        Some(Structure::BN254Fq12) => {
             ark_eq_internal!(context, args, ark_bn254::Fq12, ALGEBRA_ARK_BN254_FQ12_EQ)
         },
-        BN254Structure::BN254G1 => {
+        Some(Structure::BN254G1) => {
             ark_eq_internal!(
                 context,
                 args,
@@ -102,7 +84,7 @@ fn eq_internal_bn254(
                 ALGEBRA_ARK_BN254_G1_PROJ_EQ
             )
         },
-        BN254Structure::BN254G2 => {
+        Some(Structure::BN254G2) => {
             ark_eq_internal!(
                 context,
                 args,
@@ -110,8 +92,11 @@ fn eq_internal_bn254(
                 ALGEBRA_ARK_BN254_G2_PROJ_EQ
             )
         },
-        BN254Structure::BN254Gt => {
+        Some(Structure::BN254Gt) => {
             ark_eq_internal!(context, args, ark_bn254::Fq12, ALGEBRA_ARK_BN254_FQ12_EQ)
         },
+        _ => Err(SafeNativeError::Abort {
+            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        }),
     }
 }
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/mod.rs b/aptos-move/framework/src/natives/cryptography/algebra/mod.rs
index 83c9ccf46fb68..6a300fdbe7bbe 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/mod.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/mod.rs
@@ -60,34 +60,14 @@ pub enum Structure {
     BLS12381G2,
     BLS12381Gt,
     BLS12381Fr,
-    BN254(BN254Structure),
-}
-#[derive(Copy, Clone, Eq, Hash, PartialEq)]
-pub enum BN254Structure {
+
     BN254Fr,
     BN254Fq,
-    BN254Fq2,
     BN254Fq12,
     BN254G1,
     BN254G2,
     BN254Gt,
 }
-impl TryFrom for BN254Structure {
-    type Error = ();
-
-    fn try_from(value: TypeTag) -> Result {
-        match value.to_string().as_str() {
-            "0x1::bn254_algebra::Fr" => Ok(Self::BN254Fr),
-            "0x1::bn254_algebra::Fq" => Ok(Self::BN254Fq),
-            "0x1::bn254_algebra::Fq2" => Ok(Self::BN254Fq2),
-            "0x1::bn254_algebra::Fq12" => Ok(Self::BN254Fq12),
-            "0x1::bn254_algebra::G1" => Ok(Self::BN254G1),
-            "0x1::bn254_algebra::G2" => Ok(Self::BN254G2),
-            "0x1::bn254_algebra::Gt" => Ok(Self::BN254Gt),
-            _ => Err(()),
-        }
-    }
-}
 
 impl TryFrom for Structure {
     type Error = ();
@@ -100,7 +80,13 @@ impl TryFrom for Structure {
             "0x1::bls12381_algebra::G2" => Ok(Structure::BLS12381G2),
             "0x1::bls12381_algebra::Gt" => Ok(Structure::BLS12381Gt),
 
-            _ => Ok(Structure::BN254(BN254Structure::try_from(value)?)),
+            "0x1::bn254_algebra::Fr" => Ok(Self::BN254Fr),
+            "0x1::bn254_algebra::Fq" => Ok(Self::BN254Fq),
+            "0x1::bn254_algebra::Fq12" => Ok(Self::BN254Fq12),
+            "0x1::bn254_algebra::G1" => Ok(Self::BN254G1),
+            "0x1::bn254_algebra::G2" => Ok(Self::BN254G2),
+            "0x1::bn254_algebra::Gt" => Ok(Self::BN254Gt),
+            _ => Err(()),
         }
     }
 }
@@ -125,11 +111,6 @@ pub enum SerializationFormat {
     BLS12381FrLsb,
     BLS12381FrMsb,
 
-    BN254(BN254SerializationFormat),
-}
-
-#[derive(Copy, Clone, Eq, Hash, PartialEq)]
-pub enum BN254SerializationFormat {
     BN254G1Compressed,
     BN254G1Uncompressed,
     BN254G2Compressed,
@@ -139,31 +120,9 @@ pub enum BN254SerializationFormat {
     BN254FrMsb,
     BN254FqLsb,
     BN254FqMsb,
-    BN254Fq2LscLsb,
     BN254Fq12LscLsb,
 }
 
-impl TryFrom for BN254SerializationFormat {
-    type Error = ();
-
-    fn try_from(value: TypeTag) -> Result {
-        match value.to_string().as_str() {
-            "0x1::bn254_algebra::FormatG1Uncompr" => Ok(Self::BN254G1Uncompressed),
-            "0x1::bn254_algebra::FormatG1Compr" => Ok(Self::BN254G1Compressed),
-            "0x1::bn254_algebra::FormatG2Uncompr" => Ok(Self::BN254G2Uncompressed),
-            "0x1::bn254_algebra::FormatG2Compr" => Ok(Self::BN254G2Compressed),
-            "0x1::bn254_algebra::FormatGt" => Ok(Self::BN254Gt),
-            "0x1::bn254_algebra::FormatFrLsb" => Ok(Self::BN254FrLsb),
-            "0x1::bn254_algebra::FormatFrMsb" => Ok(Self::BN254FrMsb),
-            "0x1::bn254_algebra::FormatFqLsb" => Ok(Self::BN254FqLsb),
-            "0x1::bn254_algebra::FormatFqMsb" => Ok(Self::BN254FqMsb),
-            "0x1::bn254_algebra::FormatFq2LscLsb" => Ok(Self::BN254Fq2LscLsb),
-            "0x1::bn254_algebra::FormatFq12LscLsb" => Ok(Self::BN254Fq12LscLsb),
-            _ => Err(()),
-        }
-    }
-}
-
 impl TryFrom for SerializationFormat {
     type Error = ();
 
@@ -184,9 +143,17 @@ impl TryFrom for SerializationFormat {
             "0x1::bls12381_algebra::FormatFrLsb" => Ok(SerializationFormat::BLS12381FrLsb),
             "0x1::bls12381_algebra::FormatFrMsb" => Ok(SerializationFormat::BLS12381FrMsb),
 
-            _ => Ok(SerializationFormat::BN254(
-                BN254SerializationFormat::try_from(value)?,
-            )),
+            "0x1::bn254_algebra::FormatG1Uncompr" => Ok(Self::BN254G1Uncompressed),
+            "0x1::bn254_algebra::FormatG1Compr" => Ok(Self::BN254G1Compressed),
+            "0x1::bn254_algebra::FormatG2Uncompr" => Ok(Self::BN254G2Uncompressed),
+            "0x1::bn254_algebra::FormatG2Compr" => Ok(Self::BN254G2Compressed),
+            "0x1::bn254_algebra::FormatGt" => Ok(Self::BN254Gt),
+            "0x1::bn254_algebra::FormatFrLsb" => Ok(Self::BN254FrLsb),
+            "0x1::bn254_algebra::FormatFrMsb" => Ok(Self::BN254FrMsb),
+            "0x1::bn254_algebra::FormatFqLsb" => Ok(Self::BN254FqLsb),
+            "0x1::bn254_algebra::FormatFqMsb" => Ok(Self::BN254FqMsb),
+            "0x1::bn254_algebra::FormatFq12LscLsb" => Ok(Self::BN254Fq12LscLsb),
+            _ => Err(()),
         }
     }
 }
@@ -280,7 +247,12 @@ fn feature_flag_from_structure(structure_opt: Option) -> Option Some(FeatureFlag::BLS12_381_STRUCTURES),
-        Some(Structure::BN254(_)) => Some(FeatureFlag::BN254_STRUCTURES),
+        Some(Structure::BN254Fr)
+        | Some(Structure::BN254Fq)
+        | Some(Structure::BN254Fq12)
+        | Some(Structure::BN254G1)
+        | Some(Structure::BN254G2)
+        | Some(Structure::BN254Gt) => Some(FeatureFlag::BN254_STRUCTURES),
         _ => None,
     }
 }
@@ -344,11 +316,6 @@ const BN254_R_SCALAR: ark_ff::BigInteger256 = ark_bn254::Fr::MODULUS;
 static BN254_Q_LENDIAN: Lazy> = Lazy::new(|| BN254_Q_SCALAR.to_bytes_le());
 const BN254_Q_SCALAR: ark_ff::BigInteger256 = ark_bn254::Fq::MODULUS;
 
-/// generated by: ark_bn254::Fq::MODULUS.pow(2)
-static BN254_Q2_LENDIAN: Lazy> = Lazy::new(|| {
-    hex::decode("b1695d27a258543b01c1ea092d0702a6dcca966d9c18504ac842127a959e68048db3c6345cfaed260656371651850bb01cd248037c6f9a599cbf3c76b8c42509").unwrap()
-});
-
 /// generated by: ark_bn254::Fq::MODULUS.pow(12)
 static BN254_Q12_LENDIAN: Lazy> = Lazy::new(|| {
     hex::decode("21f186cad2e2d4c1dbaf8a066b0ebf41f734e3f859b1c523a6c1f4d457413fdbe3cd44add090135d3ae519acc30ee3bdb6bfac6573b767e975b18a77d53cdcddebf3672c74da9d1409d51b2b2db7ff000d59e3aa7cf09220159f925c86b65459ca6558c4eaa703bf45d85030ff85cc6a879c7e2c4034f7045faf20e4d3dcfffac5eb6634c3e7b939b69b2be70bdf6b9a4680297839b4e3a48cd746bd4d0ea82749ffb7e71bd9b3fb10aa684d71e6adab1250b1d8604d91b51c76c256a50b60ddba2f52b6cc853ac926c6ea86d09d400b2f2330e5c8e92e38905ba50a50c9e11cd979c284bf1327ccdc051a6da1a4a7eac5cec16757a27a1a2311bedd108a9b21ac0814269e7523a5dd3a1f5f4767ffe504a6cb3994fb0ec98d5cd5da00b9cb1188a85f2aa871ecb8a0f9d64141f1ccd2699c138e0ef9ac4d8d6a692b29db0f38b60eb08426ab46109fbab9a5221bb44dd338aafebcc4e6c10dd933597f3ff44ba41d04e82871447f3a759cfa9397c22c0c77f13618dfb65adc8aacf008").unwrap()
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/new.rs b/aptos-move/framework/src/natives/cryptography/algebra/new.rs
index 5e332aaa2073a..1b09aa05fe877 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/new.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/new.rs
@@ -3,8 +3,8 @@
 use crate::{
     abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled,
     natives::cryptography::algebra::{
-        feature_flag_from_structure, AlgebraContext, BN254Structure, Structure,
-        E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        feature_flag_from_structure, AlgebraContext, Structure, E_TOO_MUCH_MEMORY_USED,
+        MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     store_element, structure_from_ty_arg,
 };
@@ -47,32 +47,13 @@ pub fn from_u64_internal(
             ark_bls12_381::Fq12,
             ALGEBRA_ARK_BLS12_381_FQ12_FROM_U64
         ),
-        Some(Structure::BN254(s)) => from_u64_internal_bn254(context, args, s),
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn from_u64_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr => {
+        Some(Structure::BN254Fr) => {
             from_u64_internal!(context, args, ark_bn254::Fr, ALGEBRA_ARK_BN254_FR_FROM_U64)
         },
-        BN254Structure::BN254Fq => {
+        Some(Structure::BN254Fq) => {
             from_u64_internal!(context, args, ark_bn254::Fq, ALGEBRA_ARK_BN254_FQ_FROM_U64)
         },
-        BN254Structure::BN254Fq2 => from_u64_internal!(
-            context,
-            args,
-            ark_bn254::Fq2,
-            ALGEBRA_ARK_BN254_FQ2_FROM_U64
-        ),
-        BN254Structure::BN254Fq12 => from_u64_internal!(
+        Some(Structure::BN254Fq12) => from_u64_internal!(
             context,
             args,
             ark_bn254::Fq12,
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/pairing.rs b/aptos-move/framework/src/natives/cryptography/algebra/pairing.rs
index 278975fa93b24..a232bcb3e36e7 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/pairing.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/pairing.rs
@@ -3,9 +3,9 @@
 use crate::{
     abort_unless_feature_flag_enabled,
     natives::cryptography::algebra::{
-        abort_invariant_violated, AlgebraContext, BN254Structure, Structure,
-        E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES,
-        MOVE_ABORT_CODE_INPUT_VECTOR_SIZES_NOT_MATCHING, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        abort_invariant_violated, AlgebraContext, Structure, E_TOO_MUCH_MEMORY_USED,
+        MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_INPUT_VECTOR_SIZES_NOT_MATCHING,
+        MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     safe_borrow_element, store_element, structure_from_ty_arg,
 };
@@ -30,11 +30,9 @@ fn feature_flag_of_pairing(
         (Some(Structure::BLS12381G1), Some(Structure::BLS12381G2), Some(Structure::BLS12381Gt)) => {
             Some(FeatureFlag::BLS12_381_STRUCTURES)
         },
-        (
-            Some(Structure::BN254(BN254Structure::BN254G1)),
-            Some(Structure::BN254(BN254Structure::BN254G2)),
-            Some(Structure::BN254(BN254Structure::BN254Gt)),
-        ) => Some(FeatureFlag::BN254_STRUCTURES),
+        (Some(Structure::BN254G1), Some(Structure::BN254G2), Some(Structure::BN254Gt)) => {
+            Some(FeatureFlag::BN254_STRUCTURES)
+        },
         _ => None,
     }
 }
@@ -45,7 +43,87 @@ macro_rules! abort_unless_pairing_enabled {
         abort_unless_feature_flag_enabled!($context, flag_opt);
     };
 }
+macro_rules! pairing_internal {
+    (
+        $context:expr,
+        $args:ident,
+        $pairing:ty,
+        $g1_projective:ty,
+        $g2_projective:ty,
+        $pairing_gas_cost:expr,
+        $g1_proj_to_affine_gas_cost:expr,
+        $g2_proj_to_affine_gas_cost:expr
+    ) => {{
+        let g2_element_handle = safely_pop_arg!($args, u64) as usize;
+        let g1_element_handle = safely_pop_arg!($args, u64) as usize;
+        safe_borrow_element!(
+            $context,
+            g1_element_handle,
+            $g1_projective,
+            g1_element_ptr,
+            g1_element
+        );
+        $context.charge($g1_proj_to_affine_gas_cost)?;
+        let g1_element_affine = g1_element.into_affine();
+        safe_borrow_element!(
+            $context,
+            g2_element_handle,
+            $g2_projective,
+            g2_element_ptr,
+            g2_element
+        );
+        $context.charge($g2_proj_to_affine_gas_cost)?;
+        let g2_element_affine = g2_element.into_affine();
+        $context.charge($pairing_gas_cost)?;
+        let new_element = <$pairing>::pairing(g1_element_affine, g2_element_affine).0;
+        let new_handle = store_element!($context, new_element)?;
+        Ok(smallvec![Value::u64(new_handle as u64)])
+    }};
+}
+macro_rules! multi_pairing_internal {
+    (
+        $context:expr,
+        $args:ident,
+        $pairing:ty,
+        $g1_projective:ty,
+        $g2_projective:ty,
+        $multi_pairing_base_gas:expr,
+        $multi_pairing_per_pair_gas:expr,
+        $g1_proj_to_affine_gas:expr,
+        $g2_proj_to_affine_gas:expr
+    ) => {{
+        let g2_element_handles = safely_pop_arg!($args, Vec);
+        let g1_element_handles = safely_pop_arg!($args, Vec);
+        let num_entries = g1_element_handles.len();
+        if num_entries != g2_element_handles.len() {
+            return Err(SafeNativeError::Abort {
+                abort_code: MOVE_ABORT_CODE_INPUT_VECTOR_SIZES_NOT_MATCHING,
+            });
+        }
+
+        $context.charge($g1_proj_to_affine_gas.per::() * NumArgs::from(num_entries as u64))?;
+        let mut g1_elements_affine = Vec::with_capacity(num_entries);
+        for handle in g1_element_handles {
+            safe_borrow_element!($context, handle as usize, $g1_projective, ptr, element);
+            g1_elements_affine.push(element.into_affine());
+        }
 
+        $context.charge($g2_proj_to_affine_gas.per::() * NumArgs::from(num_entries as u64))?;
+        let mut g2_elements_affine = Vec::with_capacity(num_entries);
+        for handle in g2_element_handles {
+            safe_borrow_element!($context, handle as usize, $g2_projective, ptr, element);
+            g2_elements_affine.push(element.into_affine());
+        }
+
+        $context.charge(
+            $multi_pairing_base_gas
+                + $multi_pairing_per_pair_gas * NumArgs::from(num_entries as u64),
+        )?;
+        let new_element = <$pairing>::multi_pairing(g1_elements_affine, g2_elements_affine).0;
+        let new_handle = store_element!($context, new_element)?;
+        Ok(smallvec![Value::u64(new_handle as u64)])
+    }};
+}
 pub fn multi_pairing_internal(
     context: &mut SafeNativeContext,
     ty_args: Vec,
@@ -58,124 +136,30 @@ pub fn multi_pairing_internal(
     abort_unless_pairing_enabled!(context, g1_opt, g2_opt, gt_opt);
     match (g1_opt, g2_opt, gt_opt) {
         (Some(Structure::BLS12381G1), Some(Structure::BLS12381G2), Some(Structure::BLS12381Gt)) => {
-            let g2_element_handles = safely_pop_arg!(args, Vec);
-            let g1_element_handles = safely_pop_arg!(args, Vec);
-            let num_entries = g1_element_handles.len();
-            if num_entries != g2_element_handles.len() {
-                return Err(SafeNativeError::Abort {
-                    abort_code: MOVE_ABORT_CODE_INPUT_VECTOR_SIZES_NOT_MATCHING,
-                });
-            }
-
-            context.charge(
-                ALGEBRA_ARK_BLS12_381_G1_PROJ_TO_AFFINE.per::()
-                    * NumArgs::from(num_entries as u64),
-            )?;
-            let mut g1_elements_affine = Vec::with_capacity(num_entries);
-            for handle in g1_element_handles {
-                safe_borrow_element!(
-                    context,
-                    handle as usize,
-                    ark_bls12_381::G1Projective,
-                    ptr,
-                    element
-                );
-                g1_elements_affine.push(element.into_affine());
-            }
-
-            context.charge(
-                ALGEBRA_ARK_BLS12_381_G2_PROJ_TO_AFFINE.per::()
-                    * NumArgs::from(num_entries as u64),
-            )?;
-            let mut g2_elements_affine = Vec::with_capacity(num_entries);
-            for handle in g2_element_handles {
-                safe_borrow_element!(
-                    context,
-                    handle as usize,
-                    ark_bls12_381::G2Projective,
-                    ptr,
-                    element
-                );
-                g2_elements_affine.push(element.into_affine());
-            }
-
-            context.charge(
-                ALGEBRA_ARK_BLS12_381_MULTI_PAIRING_BASE
-                    + ALGEBRA_ARK_BLS12_381_MULTI_PAIRING_PER_PAIR
-                        * NumArgs::from(num_entries as u64),
-            )?;
-            let new_element =
-                ark_bls12_381::Bls12_381::multi_pairing(g1_elements_affine, g2_elements_affine).0;
-            let new_handle = store_element!(context, new_element)?;
-            Ok(smallvec![Value::u64(new_handle as u64)])
-        },
-        (Some(Structure::BN254(g1)), Some(Structure::BN254(g2)), Some(Structure::BN254(gt))) => {
-            multi_pairing_internal_bn254(context, args, g1, g2, gt)
+            multi_pairing_internal!(
+                context,
+                args,
+                ark_bls12_381::Bls12_381,
+                ark_bls12_381::G1Projective,
+                ark_bls12_381::G2Projective,
+                ALGEBRA_ARK_BLS12_381_MULTI_PAIRING_BASE,
+                ALGEBRA_ARK_BLS12_381_MULTI_PAIRING_PER_PAIR,
+                ALGEBRA_ARK_BLS12_381_G1_PROJ_TO_AFFINE,
+                ALGEBRA_ARK_BLS12_381_G2_PROJ_TO_AFFINE
+            )
         },
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn multi_pairing_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    g1: BN254Structure,
-    g2: BN254Structure,
-    gt: BN254Structure,
-) -> SafeNativeResult> {
-    match (g1, g2, gt) {
-        (BN254Structure::BN254G1, BN254Structure::BN254G2, BN254Structure::BN254Gt) => {
-            let g2_element_handles = safely_pop_arg!(args, Vec);
-            let g1_element_handles = safely_pop_arg!(args, Vec);
-            let num_entries = g1_element_handles.len();
-            if num_entries != g2_element_handles.len() {
-                return Err(SafeNativeError::Abort {
-                    abort_code: MOVE_ABORT_CODE_INPUT_VECTOR_SIZES_NOT_MATCHING,
-                });
-            }
-
-            context.charge(
-                ALGEBRA_ARK_BN254_G1_PROJ_TO_AFFINE.per::()
-                    * NumArgs::from(num_entries as u64),
-            )?;
-            let mut g1_elements_affine = Vec::with_capacity(num_entries);
-            for handle in g1_element_handles {
-                safe_borrow_element!(
-                    context,
-                    handle as usize,
-                    ark_bn254::G1Projective,
-                    ptr,
-                    element
-                );
-                g1_elements_affine.push(element.into_affine());
-            }
-
-            context.charge(
-                ALGEBRA_ARK_BN254_G2_PROJ_TO_AFFINE.per::()
-                    * NumArgs::from(num_entries as u64),
-            )?;
-            let mut g2_elements_affine = Vec::with_capacity(num_entries);
-            for handle in g2_element_handles {
-                safe_borrow_element!(
-                    context,
-                    handle as usize,
-                    ark_bn254::G2Projective,
-                    ptr,
-                    element
-                );
-                g2_elements_affine.push(element.into_affine());
-            }
-
-            context.charge(
-                ALGEBRA_ARK_BN254_MULTI_PAIRING_BASE
-                    + ALGEBRA_ARK_BN254_MULTI_PAIRING_PER_PAIR * NumArgs::from(num_entries as u64),
-            )?;
-            let new_element =
-                ark_bn254::Bn254::multi_pairing(g1_elements_affine, g2_elements_affine).0;
-            let new_handle = store_element!(context, new_element)?;
-            Ok(smallvec![Value::u64(new_handle as u64)])
+        (Some(Structure::BN254G1), Some(Structure::BN254G2), Some(Structure::BN254Gt)) => {
+            multi_pairing_internal!(
+                context,
+                args,
+                ark_bn254::Bn254,
+                ark_bn254::G1Projective,
+                ark_bn254::G2Projective,
+                ALGEBRA_ARK_BN254_MULTI_PAIRING_BASE,
+                ALGEBRA_ARK_BN254_MULTI_PAIRING_PER_PAIR,
+                ALGEBRA_ARK_BN254_G1_PROJ_TO_AFFINE,
+                ALGEBRA_ARK_BN254_G2_PROJ_TO_AFFINE
+            )
         },
         _ => Err(SafeNativeError::Abort {
             abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
@@ -195,75 +179,28 @@ pub fn pairing_internal(
     abort_unless_pairing_enabled!(context, g1_opt, g2_opt, gt_opt);
     match (g1_opt, g2_opt, gt_opt) {
         (Some(Structure::BLS12381G1), Some(Structure::BLS12381G2), Some(Structure::BLS12381Gt)) => {
-            let g2_element_handle = safely_pop_arg!(args, u64) as usize;
-            let g1_element_handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(
+            pairing_internal!(
                 context,
-                g1_element_handle,
+                args,
+                ark_bls12_381::Bls12_381,
                 ark_bls12_381::G1Projective,
-                g1_element_ptr,
-                g1_element
-            );
-            context.charge(ALGEBRA_ARK_BLS12_381_G1_PROJ_TO_AFFINE)?;
-            let g1_element_affine = g1_element.into_affine();
-            safe_borrow_element!(
-                context,
-                g2_element_handle,
                 ark_bls12_381::G2Projective,
-                g2_element_ptr,
-                g2_element
-            );
-            context.charge(ALGEBRA_ARK_BLS12_381_G2_PROJ_TO_AFFINE)?;
-            let g2_element_affine = g2_element.into_affine();
-            context.charge(ALGEBRA_ARK_BLS12_381_PAIRING)?;
-            let new_element =
-                ark_bls12_381::Bls12_381::pairing(g1_element_affine, g2_element_affine).0;
-            let new_handle = store_element!(context, new_element)?;
-            Ok(smallvec![Value::u64(new_handle as u64)])
+                ALGEBRA_ARK_BLS12_381_PAIRING,
+                ALGEBRA_ARK_BLS12_381_G1_PROJ_TO_AFFINE,
+                ALGEBRA_ARK_BLS12_381_G2_PROJ_TO_AFFINE
+            )
         },
-        (Some(Structure::BN254(g1)), Some(Structure::BN254(g2)), Some(Structure::BN254(gt))) => {
-            pairing_internal_bn254(context, args, g1, g2, gt)
-        },
-
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-fn pairing_internal_bn254(
-    context: &mut SafeNativeContext,
-    mut args: VecDeque,
-    g1: BN254Structure,
-    g2: BN254Structure,
-    gt: BN254Structure,
-) -> SafeNativeResult> {
-    match (g1, g2, gt) {
-        (BN254Structure::BN254G1, BN254Structure::BN254G2, BN254Structure::BN254Gt) => {
-            let g2_element_handle = safely_pop_arg!(args, u64) as usize;
-            let g1_element_handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(
+        (Some(Structure::BN254G1), Some(Structure::BN254G2), Some(Structure::BN254Gt)) => {
+            pairing_internal!(
                 context,
-                g1_element_handle,
+                args,
+                ark_bn254::Bn254,
                 ark_bn254::G1Projective,
-                g1_element_ptr,
-                g1_element
-            );
-            context.charge(ALGEBRA_ARK_BN254_G1_PROJ_TO_AFFINE)?;
-            let g1_element_affine = g1_element.into_affine();
-            safe_borrow_element!(
-                context,
-                g2_element_handle,
                 ark_bn254::G2Projective,
-                g2_element_ptr,
-                g2_element
-            );
-            context.charge(ALGEBRA_ARK_BN254_G2_PROJ_TO_AFFINE)?;
-            let g2_element_affine = g2_element.into_affine();
-            context.charge(ALGEBRA_ARK_BN254_PAIRING)?;
-            let new_element = ark_bn254::Bn254::pairing(g1_element_affine, g2_element_affine).0;
-            let new_handle = store_element!(context, new_element)?;
-            Ok(smallvec![Value::u64(new_handle as u64)])
+                ALGEBRA_ARK_BN254_PAIRING,
+                ALGEBRA_ARK_BN254_G1_PROJ_TO_AFFINE,
+                ALGEBRA_ARK_BN254_G2_PROJ_TO_AFFINE
+            )
         },
         _ => Err(SafeNativeError::Abort {
             abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/rand.rs b/aptos-move/framework/src/natives/cryptography/algebra/rand.rs
index 682d3ff2c17c1..ec2ec6578dd92 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/rand.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/rand.rs
@@ -3,7 +3,7 @@
 #[cfg(feature = "testing")]
 use crate::{
     natives::cryptography::algebra::{
-        AlgebraContext, BN254Structure, Structure, BLS12381_GT_GENERATOR, BN254_GT_GENERATOR,
+        AlgebraContext, Structure, BLS12381_GT_GENERATOR, BN254_GT_GENERATOR,
         E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES,
     },
     structure_from_ty_arg,
@@ -77,36 +77,22 @@ pub fn rand_insecure_internal(
                 Err(abort_code) => Err(SafeNativeError::Abort { abort_code }),
             }
         },
-        Some(Structure::BN254(s)) => rand_insecure_internal_bn254(context, s),
-        _ => unreachable!(),
-    }
-}
-#[cfg(feature = "testing")]
-#[inline]
-fn rand_insecure_internal_bn254(
-    context: &mut SafeNativeContext,
-    structure: BN254Structure,
-) -> SafeNativeResult> {
-    match structure {
-        BN254Structure::BN254Fr => {
+        Some(Structure::BN254Fr) => {
             ark_rand_internal!(context, ark_bn254::Fr)
         },
-        BN254Structure::BN254Fq => {
+        Some(Structure::BN254Fq) => {
             ark_rand_internal!(context, ark_bn254::Fq)
         },
-        BN254Structure::BN254Fq2 => {
-            ark_rand_internal!(context, ark_bn254::Fq2)
-        },
-        BN254Structure::BN254Fq12 => {
+        Some(Structure::BN254Fq12) => {
             ark_rand_internal!(context, ark_bn254::Fq12)
         },
-        BN254Structure::BN254G1 => {
+        Some(Structure::BN254G1) => {
             ark_rand_internal!(context, ark_bn254::G1Projective)
         },
-        BN254Structure::BN254G2 => {
+        Some(Structure::BN254G2) => {
             ark_rand_internal!(context, ark_bn254::G2Projective)
         },
-        BN254Structure::BN254Gt => {
+        Some(Structure::BN254Gt) => {
             let k = ark_bn254::Fr::rand(&mut test_rng());
             let k_bigint: ark_ff::BigInteger256 = k.into();
             let element = BN254_GT_GENERATOR.pow(k_bigint);
@@ -115,5 +101,6 @@ fn rand_insecure_internal_bn254(
                 Err(abort_code) => Err(SafeNativeError::Abort { abort_code }),
             }
         },
+        _ => unreachable!(),
     }
 }
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs b/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs
index ee928543752ab..a93b30d8bab7c 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/serialization.rs
@@ -3,9 +3,9 @@
 use crate::{
     abort_unless_feature_flag_enabled,
     natives::cryptography::algebra::{
-        abort_invariant_violated, AlgebraContext, BN254SerializationFormat, BN254Structure,
-        SerializationFormat, Structure, BLS12381_R_SCALAR, BN254_R_SCALAR, E_TOO_MUCH_MEMORY_USED,
-        MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        abort_invariant_violated, AlgebraContext, SerializationFormat, Structure,
+        BLS12381_R_SCALAR, BN254_R_SCALAR, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES,
+        MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     safe_borrow_element, store_element, structure_from_ty_arg,
 };
@@ -37,7 +37,16 @@ pub fn feature_flag_of_serialization_format(
         | Some(SerializationFormat::BLS12381G2Uncompressed)
         | Some(SerializationFormat::BLS12381G2Compressed)
         | Some(SerializationFormat::BLS12381Gt) => Some(FeatureFlag::BLS12_381_STRUCTURES),
-        Some(SerializationFormat::BN254(_)) => Some(FeatureFlag::BN254_STRUCTURES),
+        Some(SerializationFormat::BN254FrLsb)
+        | Some(SerializationFormat::BN254FrMsb)
+        | Some(SerializationFormat::BN254FqLsb)
+        | Some(SerializationFormat::BN254FqMsb)
+        | Some(SerializationFormat::BN254Fq12LscLsb)
+        | Some(SerializationFormat::BN254G1Uncompressed)
+        | Some(SerializationFormat::BN254G1Compressed)
+        | Some(SerializationFormat::BN254G2Uncompressed)
+        | Some(SerializationFormat::BN254G2Compressed)
+        | Some(SerializationFormat::BN254Gt) => Some(FeatureFlag::BN254_STRUCTURES),
         _ => None,
     }
 }
@@ -56,285 +65,217 @@ macro_rules! format_from_ty_arg {
     }};
 }
 
-pub fn serialize_internal(
-    context: &mut SafeNativeContext,
-    ty_args: Vec,
-    mut args: VecDeque,
-) -> SafeNativeResult> {
-    assert_eq!(2, ty_args.len());
-    let structure_opt = structure_from_ty_arg!(context, &ty_args[0]);
-    let format_opt = format_from_ty_arg!(context, &ty_args[1]);
-    abort_unless_serialization_format_enabled!(context, format_opt);
-    match (structure_opt, format_opt) {
-        (
-            Some(Structure::BN254(bn254_structure)),
-            Some(SerializationFormat::BN254(bn254_format)),
-        ) => serialize_internal_bn254(context, args, bn254_structure, bn254_format),
-        (Some(Structure::BLS12381Fr), Some(SerializationFormat::BLS12381FrLsb)) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(context, handle, ark_bls12_381::Fr, element_ptr, element);
-            let mut buf = vec![];
-            context.charge(ALGEBRA_ARK_BLS12_381_FR_SERIALIZE)?;
-            element
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (Some(Structure::BLS12381Fr), Some(SerializationFormat::BLS12381FrMsb)) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(context, handle, ark_bls12_381::Fr, element_ptr, element);
-            let mut buf = vec![];
-            context.charge(ALGEBRA_ARK_BLS12_381_FR_SERIALIZE)?;
-            element
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            buf.reverse();
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (Some(Structure::BLS12381Fq12), Some(SerializationFormat::BLS12381Fq12LscLsb)) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(context, handle, ark_bls12_381::Fq12, element_ptr, element);
+macro_rules! serialize_element {
+    (
+        $context:expr,
+        $args:ident,
+        $structure_to_match:expr,
+        $format_to_match:expr,
+        [$(($field_structure:pat, $field_format:pat, $field_ty:ty, $field_serialization_func:ident,$reverse:expr, $field_serialization_gas:expr)),* $(,)?],
+        [$(($curve_structure:pat,$curve_format:pat, $curve_ty:ty, $curve_serialization_func:ident, $curve_serialization_gas:expr)),* $(,)?]
+    ) => {
+        match ($structure_to_match, $format_to_match) {
+        $(
+          ($field_structure,$field_format) => {
+            let handle = safely_pop_arg!($args, u64) as usize;
+            safe_borrow_element!($context, handle, $field_ty, element_ptr, element);
             let mut buf = vec![];
-            context.charge(ALGEBRA_ARK_BLS12_381_FQ12_SERIALIZE)?;
+            $context.charge($field_serialization_gas)?;
             element
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (Some(Structure::BLS12381G1), Some(SerializationFormat::BLS12381G1Uncompressed)) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(
-                context,
-                handle,
-                ark_bls12_381::G1Projective,
-                element_ptr,
-                element
-            );
-            let element_affine = element.into_affine();
-            let mut buf = Vec::new();
-            context.charge(ALGEBRA_ARK_BLS12_381_G1_AFFINE_SERIALIZE_UNCOMP)?;
-            element_affine
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (Some(Structure::BLS12381G1), Some(SerializationFormat::BLS12381G1Compressed)) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(
-                context,
-                handle,
-                ark_bls12_381::G1Projective,
-                element_ptr,
-                element
-            );
-            let element_affine = element.into_affine();
-            let mut buf = Vec::new();
-            context.charge(ALGEBRA_ARK_BLS12_381_G1_AFFINE_SERIALIZE_COMP)?;
-            element_affine
-                .serialize_compressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (Some(Structure::BLS12381G2), Some(SerializationFormat::BLS12381G2Uncompressed)) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(
-                context,
-                handle,
-                ark_bls12_381::G2Projective,
-                element_ptr,
-                element
-            );
-            let element_affine = element.into_affine();
-            let mut buf = Vec::new();
-            context.charge(ALGEBRA_ARK_BLS12_381_G2_AFFINE_SERIALIZE_UNCOMP)?;
-            element_affine
-                .serialize_uncompressed(&mut buf)
+                .$field_serialization_func(&mut buf)
                 .map_err(|_e| abort_invariant_violated())?;
+            if $reverse {
+                buf.reverse();
+            }
             Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (Some(Structure::BLS12381G2), Some(SerializationFormat::BLS12381G2Compressed)) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
+          }
+        )*
+        $(
+          ($curve_structure,$curve_format) => {
+            let handle = safely_pop_arg!($args, u64) as usize;
             safe_borrow_element!(
-                context,
+                $context,
                 handle,
-                ark_bls12_381::G2Projective,
+                $curve_ty,
                 element_ptr,
                 element
             );
             let element_affine = element.into_affine();
             let mut buf = Vec::new();
-            context.charge(ALGEBRA_ARK_BLS12_381_G2_AFFINE_SERIALIZE_COMP)?;
+            $context.charge($curve_serialization_gas)?;
             element_affine
-                .serialize_compressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (Some(Structure::BLS12381Gt), Some(SerializationFormat::BLS12381Gt)) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(context, handle, ark_bls12_381::Fq12, element_ptr, element);
-            let mut buf = vec![];
-            context.charge(ALGEBRA_ARK_BLS12_381_FQ12_SERIALIZE)?;
-            element
-                .serialize_uncompressed(&mut buf)
+                .$curve_serialization_func(&mut buf)
                 .map_err(|_e| abort_invariant_violated())?;
             Ok(smallvec![Value::vector_u8(buf)])
-        },
-        _ => Err(SafeNativeError::Abort {
+          }
+        )*
+          _ => Err(SafeNativeError::Abort {
             abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
+          })
+        }
+    };
 }
 
-fn serialize_internal_bn254(
+pub fn serialize_internal(
     context: &mut SafeNativeContext,
+    ty_args: Vec,
     mut args: VecDeque,
-    structure: BN254Structure,
-    format: BN254SerializationFormat,
 ) -> SafeNativeResult> {
-    match (structure, format) {
-        (BN254Structure::BN254Fr, BN254SerializationFormat::BN254FrLsb) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(context, handle, ark_bn254::Fr, element_ptr, element);
-            let mut buf = vec![];
-            context.charge(ALGEBRA_ARK_BN254_FR_SERIALIZE)?;
-            element
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (BN254Structure::BN254Fr, BN254SerializationFormat::BN254FrMsb) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(context, handle, ark_bn254::Fr, element_ptr, element);
-            let mut buf = vec![];
-            context.charge(ALGEBRA_ARK_BN254_FR_SERIALIZE)?;
-            element
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            buf.reverse();
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (BN254Structure::BN254Fq, BN254SerializationFormat::BN254FqLsb) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(context, handle, ark_bn254::Fq, element_ptr, element);
-            let mut buf = vec![];
-            context.charge(ALGEBRA_ARK_BN254_FQ_SERIALIZE)?;
-            element
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (BN254Structure::BN254Fq, BN254SerializationFormat::BN254FqMsb) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(context, handle, ark_bn254::Fq, element_ptr, element);
-            let mut buf = vec![];
-            context.charge(ALGEBRA_ARK_BN254_FQ_SERIALIZE)?;
-            element
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            buf.reverse();
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (BN254Structure::BN254Fq2, BN254SerializationFormat::BN254Fq2LscLsb) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(context, handle, ark_bn254::Fq2, element_ptr, element);
-            let mut buf = vec![];
-            context.charge(ALGEBRA_ARK_BN254_FQ2_SERIALIZE)?;
-            element
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (BN254Structure::BN254Fq12, BN254SerializationFormat::BN254Fq12LscLsb) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(context, handle, ark_bn254::Fq12, element_ptr, element);
-            let mut buf = vec![];
-            context.charge(ALGEBRA_ARK_BN254_FQ12_SERIALIZE)?;
-            element
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (BN254Structure::BN254G1, BN254SerializationFormat::BN254G1Uncompressed) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(
-                context,
-                handle,
-                ark_bn254::G1Projective,
-                element_ptr,
-                element
-            );
-            let element_affine = element.into_affine();
-            let mut buf = Vec::new();
-            context.charge(ALGEBRA_ARK_BN254_G1_AFFINE_SERIALIZE_UNCOMP)?;
-            element_affine
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (BN254Structure::BN254G1, BN254SerializationFormat::BN254G1Compressed) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(
-                context,
-                handle,
-                ark_bn254::G1Projective,
-                element_ptr,
-                element
-            );
-            let element_affine = element.into_affine();
-            let mut buf = Vec::new();
-            context.charge(ALGEBRA_ARK_BN254_G1_AFFINE_SERIALIZE_COMP)?;
-            element_affine
-                .serialize_compressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (BN254Structure::BN254G2, BN254SerializationFormat::BN254G2Uncompressed) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(
-                context,
-                handle,
-                ark_bn254::G2Projective,
-                element_ptr,
-                element
-            );
-            let element_affine = element.into_affine();
-            let mut buf = Vec::new();
-            context.charge(ALGEBRA_ARK_BN254_G2_AFFINE_SERIALIZE_UNCOMP)?;
-            element_affine
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (BN254Structure::BN254G2, BN254SerializationFormat::BN254G2Compressed) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(
-                context,
-                handle,
-                ark_bn254::G2Projective,
-                element_ptr,
-                element
-            );
-            let element_affine = element.into_affine();
-            let mut buf = Vec::new();
-            context.charge(ALGEBRA_ARK_BN254_G2_AFFINE_SERIALIZE_COMP)?;
-            element_affine
-                .serialize_compressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        (BN254Structure::BN254Gt, BN254SerializationFormat::BN254Gt) => {
-            let handle = safely_pop_arg!(args, u64) as usize;
-            safe_borrow_element!(context, handle, ark_bn254::Fq12, element_ptr, element);
-            let mut buf = vec![];
-            context.charge(ALGEBRA_ARK_BN254_FQ12_SERIALIZE)?;
-            element
-                .serialize_uncompressed(&mut buf)
-                .map_err(|_e| abort_invariant_violated())?;
-            Ok(smallvec![Value::vector_u8(buf)])
-        },
-        _ => Err(SafeNativeError::Abort {
+    assert_eq!(2, ty_args.len());
+    let structure_opt = structure_from_ty_arg!(context, &ty_args[0]);
+    let format_opt = format_from_ty_arg!(context, &ty_args[1]);
+    abort_unless_serialization_format_enabled!(context, format_opt);
+    if let (Some(structure), Some(format)) = (structure_opt, format_opt) {
+        serialize_element!(
+            context,
+            args,
+            structure,
+            format,
+            [
+                (
+                    Structure::BLS12381Fr,
+                    SerializationFormat::BLS12381FrLsb,
+                    ark_bls12_381::Fr,
+                    serialize_uncompressed,
+                    false,
+                    ALGEBRA_ARK_BLS12_381_FR_SERIALIZE
+                ),
+                (
+                    Structure::BLS12381Fr,
+                    SerializationFormat::BLS12381FrMsb,
+                    ark_bls12_381::Fr,
+                    serialize_uncompressed,
+                    true,
+                    ALGEBRA_ARK_BLS12_381_FR_SERIALIZE
+                ),
+                (
+                    Structure::BLS12381Fq12,
+                    SerializationFormat::BLS12381Fq12LscLsb,
+                    ark_bls12_381::Fq12,
+                    serialize_uncompressed,
+                    false,
+                    ALGEBRA_ARK_BLS12_381_FQ12_SERIALIZE
+                ),
+                (
+                    Structure::BLS12381Gt,
+                    SerializationFormat::BLS12381Gt,
+                    ark_bls12_381::Fq12,
+                    serialize_uncompressed,
+                    false,
+                    ALGEBRA_ARK_BLS12_381_FQ12_SERIALIZE
+                ),
+                (
+                    Structure::BN254Fr,
+                    SerializationFormat::BN254FrLsb,
+                    ark_bn254::Fr,
+                    serialize_uncompressed,
+                    false,
+                    ALGEBRA_ARK_BN254_FR_SERIALIZE
+                ),
+                (
+                    Structure::BN254Fr,
+                    SerializationFormat::BN254FrMsb,
+                    ark_bn254::Fr,
+                    serialize_uncompressed,
+                    true,
+                    ALGEBRA_ARK_BN254_FR_SERIALIZE
+                ),
+                (
+                    Structure::BN254Fq,
+                    SerializationFormat::BN254FqLsb,
+                    ark_bn254::Fq,
+                    serialize_uncompressed,
+                    false,
+                    ALGEBRA_ARK_BN254_FQ_SERIALIZE
+                ),
+                (
+                    Structure::BN254Fq,
+                    SerializationFormat::BN254FqMsb,
+                    ark_bn254::Fq,
+                    serialize_uncompressed,
+                    true,
+                    ALGEBRA_ARK_BN254_FQ_SERIALIZE
+                ),
+                (
+                    Structure::BN254Fq12,
+                    SerializationFormat::BN254Fq12LscLsb,
+                    ark_bn254::Fq12,
+                    serialize_uncompressed,
+                    false,
+                    ALGEBRA_ARK_BN254_FQ12_SERIALIZE
+                ),
+                (
+                    Structure::BN254Gt,
+                    SerializationFormat::BN254Gt,
+                    ark_bn254::Fq12,
+                    serialize_uncompressed,
+                    false,
+                    ALGEBRA_ARK_BN254_FQ12_SERIALIZE
+                )
+            ],
+            [
+                (
+                    Structure::BLS12381G1,
+                    SerializationFormat::BLS12381G1Uncompressed,
+                    ark_bls12_381::G1Projective,
+                    serialize_uncompressed,
+                    ALGEBRA_ARK_BLS12_381_G1_AFFINE_SERIALIZE_UNCOMP
+                ),
+                (
+                    Structure::BLS12381G1,
+                    SerializationFormat::BLS12381G1Compressed,
+                    ark_bls12_381::G1Projective,
+                    serialize_compressed,
+                    ALGEBRA_ARK_BLS12_381_G1_AFFINE_SERIALIZE_COMP
+                ),
+                (
+                    Structure::BLS12381G2,
+                    SerializationFormat::BLS12381G2Uncompressed,
+                    ark_bls12_381::G2Projective,
+                    serialize_uncompressed,
+                    ALGEBRA_ARK_BLS12_381_G2_AFFINE_SERIALIZE_UNCOMP
+                ),
+                (
+                    Structure::BLS12381G2,
+                    SerializationFormat::BLS12381G2Compressed,
+                    ark_bls12_381::G2Projective,
+                    serialize_compressed,
+                    ALGEBRA_ARK_BLS12_381_G2_AFFINE_SERIALIZE_COMP
+                ),
+                (
+                    Structure::BN254G1,
+                    SerializationFormat::BN254G1Uncompressed,
+                    ark_bn254::G1Projective,
+                    serialize_uncompressed,
+                    ALGEBRA_ARK_BN254_G1_AFFINE_SERIALIZE_UNCOMP
+                ),
+                (
+                    Structure::BN254G1,
+                    SerializationFormat::BN254G1Compressed,
+                    ark_bn254::G1Projective,
+                    serialize_compressed,
+                    ALGEBRA_ARK_BN254_G1_AFFINE_SERIALIZE_COMP
+                ),
+                (
+                    Structure::BN254G2,
+                    SerializationFormat::BN254G2Uncompressed,
+                    ark_bn254::G2Projective,
+                    serialize_uncompressed,
+                    ALGEBRA_ARK_BN254_G2_AFFINE_SERIALIZE_UNCOMP
+                ),
+                (
+                    Structure::BN254G2,
+                    SerializationFormat::BN254G2Compressed,
+                    ark_bn254::G2Projective,
+                    serialize_compressed,
+                    ALGEBRA_ARK_BN254_G2_AFFINE_SERIALIZE_COMP
+                ),
+            ]
+        )
+    } else {
+        Err(SafeNativeError::Abort {
             abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
+        })
     }
 }
 
@@ -391,10 +332,6 @@ pub fn deserialize_internal(
     let bytes_ref = vector_ref.as_bytes_ref();
     let bytes = bytes_ref.as_slice();
     match (structure_opt, format_opt) {
-        (
-            Some(Structure::BN254(bn254_structure)),
-            Some(SerializationFormat::BN254(bn254_format)),
-        ) => deserialize_internal_bn254(context, bn254_structure, bn254_format, bytes),
         (Some(Structure::BLS12381Fr), Some(SerializationFormat::BLS12381FrLsb)) => {
             // Valid BLS12381FrLsb serialization should be 32-byte.
             // NOTE: Arkworks deserialization cost grows as the input size grows.
@@ -512,20 +449,7 @@ pub fn deserialize_internal(
                 _ => Ok(smallvec![Value::bool(false), Value::u64(0)]),
             }
         },
-        _ => Err(SafeNativeError::Abort {
-            abort_code: MOVE_ABORT_CODE_NOT_IMPLEMENTED,
-        }),
-    }
-}
-
-pub fn deserialize_internal_bn254(
-    context: &mut SafeNativeContext,
-    structure: BN254Structure,
-    format: BN254SerializationFormat,
-    bytes: &[u8],
-) -> SafeNativeResult> {
-    match (structure, format) {
-        (BN254Structure::BN254Fr, BN254SerializationFormat::BN254FrLsb) => {
+        (Some(Structure::BN254Fr), Some(SerializationFormat::BN254FrLsb)) => {
             if bytes.len() != 32 {
                 return Ok(smallvec![Value::bool(false), Value::u64(0)]);
             }
@@ -537,7 +461,7 @@ pub fn deserialize_internal_bn254(
                 ALGEBRA_ARK_BN254_FR_DESER
             )
         },
-        (BN254Structure::BN254Fr, BN254SerializationFormat::BN254FrMsb) => {
+        (Some(Structure::BN254Fr), Some(SerializationFormat::BN254FrMsb)) => {
             if bytes.len() != 32 {
                 return Ok(smallvec![Value::bool(false), Value::u64(0)]);
             }
@@ -552,7 +476,7 @@ pub fn deserialize_internal_bn254(
                 ALGEBRA_ARK_BN254_FR_DESER
             )
         },
-        (BN254Structure::BN254Fq, BN254SerializationFormat::BN254FqLsb) => {
+        (Some(Structure::BN254Fq), Some(SerializationFormat::BN254FqLsb)) => {
             if bytes.len() != 32 {
                 return Ok(smallvec![Value::bool(false), Value::u64(0)]);
             }
@@ -564,7 +488,7 @@ pub fn deserialize_internal_bn254(
                 ALGEBRA_ARK_BN254_FQ_DESER
             )
         },
-        (BN254Structure::BN254Fq, BN254SerializationFormat::BN254FqMsb) => {
+        (Some(Structure::BN254Fq), Some(SerializationFormat::BN254FqMsb)) => {
             if bytes.len() != 32 {
                 return Ok(smallvec![Value::bool(false), Value::u64(0)]);
             }
@@ -579,20 +503,7 @@ pub fn deserialize_internal_bn254(
                 ALGEBRA_ARK_BN254_FQ_DESER
             )
         },
-        (BN254Structure::BN254Fq2, BN254SerializationFormat::BN254Fq2LscLsb) => {
-            // Valid BN254Fq2LscLsb serialization should be 32*2 = 64-byte.
-            if bytes.len() != 64 {
-                return Ok(smallvec![Value::bool(false), Value::u64(0)]);
-            }
-            ark_deserialize_internal!(
-                context,
-                bytes,
-                ark_bn254::Fq2,
-                deserialize_uncompressed,
-                ALGEBRA_ARK_BN254_FQ2_DESER
-            )
-        },
-        (BN254Structure::BN254Fq12, BN254SerializationFormat::BN254Fq12LscLsb) => {
+        (Some(Structure::BN254Fq12), Some(SerializationFormat::BN254Fq12LscLsb)) => {
             // Valid BN254Fq12LscLsb serialization should be 32*12 = 64-byte.
             if bytes.len() != 384 {
                 return Ok(smallvec![Value::bool(false), Value::u64(0)]);
@@ -605,7 +516,7 @@ pub fn deserialize_internal_bn254(
                 ALGEBRA_ARK_BN254_FQ12_DESER
             )
         },
-        (BN254Structure::BN254G1, BN254SerializationFormat::BN254G1Uncompressed) => {
+        (Some(Structure::BN254G1), Some(SerializationFormat::BN254G1Uncompressed)) => {
             // Valid BN254G1AffineUncompressed serialization should be 64-byte.
             if bytes.len() != 64 {
                 return Ok(smallvec![Value::bool(false), Value::u64(0)]);
@@ -618,7 +529,7 @@ pub fn deserialize_internal_bn254(
                 ALGEBRA_ARK_BN254_G1_AFFINE_DESER_UNCOMP
             )
         },
-        (BN254Structure::BN254G1, BN254SerializationFormat::BN254G1Compressed) => {
+        (Some(Structure::BN254G1), Some(SerializationFormat::BN254G1Compressed)) => {
             // Valid BN254G1AffineCompressed serialization should be 32-byte.
             if bytes.len() != 32 {
                 return Ok(smallvec![Value::bool(false), Value::u64(0)]);
@@ -631,7 +542,7 @@ pub fn deserialize_internal_bn254(
                 ALGEBRA_ARK_BN254_G1_AFFINE_DESER_COMP
             )
         },
-        (BN254Structure::BN254G2, BN254SerializationFormat::BN254G2Uncompressed) => {
+        (Some(Structure::BN254G2), Some(SerializationFormat::BN254G2Uncompressed)) => {
             // Valid BN254G2AffineUncompressed serialization should be 128-byte.
             if bytes.len() != 128 {
                 return Ok(smallvec![Value::bool(false), Value::u64(0)]);
@@ -644,7 +555,7 @@ pub fn deserialize_internal_bn254(
                 ALGEBRA_ARK_BN254_G2_AFFINE_DESER_UNCOMP
             )
         },
-        (BN254Structure::BN254G2, BN254SerializationFormat::BN254G2Compressed) => {
+        (Some(Structure::BN254G2), Some(SerializationFormat::BN254G2Compressed)) => {
             // Valid BN254G2AffineCompressed serialization should be 64-byte.
             if bytes.len() != 64 {
                 return Ok(smallvec![Value::bool(false), Value::u64(0)]);
@@ -657,7 +568,7 @@ pub fn deserialize_internal_bn254(
                 ALGEBRA_ARK_BN254_G2_AFFINE_DESER_COMP
             )
         },
-        (BN254Structure::BN254Gt, BN254SerializationFormat::BN254Gt) => {
+        (Some(Structure::BN254Gt), Some(SerializationFormat::BN254Gt)) => {
             // Valid BN254Gt serialization should be 32*12=384-byte.
             if bytes.len() != 384 {
                 return Ok(smallvec![Value::bool(false), Value::u64(0)]);

From 0199f695f7fb7d3caee525f7963a88c91277a75a Mon Sep 17 00:00:00 2001
From: caojiafeng 
Date: Sun, 10 Dec 2023 17:18:25 +0800
Subject: [PATCH 16/21] delete bn254_fq2 related code

---
 .../src/gas_schedule/aptos_framework.rs           | 15 ---------------
 crates/aptos-crypto/benches/ark_bn254.rs          | 15 ---------------
 .../update_bn254_algebra_gas_params.py            | 15 ---------------
 3 files changed, 45 deletions(-)

diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs
index cc315caf46f7e..7f1b64793a1e7 100644
--- a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs
+++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs
@@ -33,21 +33,6 @@ crate::gas_schedule::macros::define_gas_parameters!(
         [algebra_ark_bn254_fq12_square: InternalGas, { 12.. => "algebra.ark_bn254_fq12_square" }, 468_955],
         [algebra_ark_bn254_fq12_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq12_sub" }, 30_497],
         [algebra_ark_bn254_fq12_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq12_zero" }, 209],
-        [algebra_ark_bn254_fq2_add: InternalGas, { 12.. => "algebra.ark_bn254_fq2_add" }, 4_417],
-        [algebra_ark_bn254_fq2_clone: InternalGas, { 12.. => "algebra.ark_bn254_fq2_clone" }, 4_318],
-        [algebra_ark_bn254_fq2_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq2_deser" }, 25_524],
-        [algebra_ark_bn254_fq2_div: InternalGas, { 12.. => "algebra.ark_bn254_fq2_div" }, 1_183_329],
-        [algebra_ark_bn254_fq2_eq: InternalGas, { 12.. => "algebra.ark_bn254_fq2_eq" }, 4_393],
-        [algebra_ark_bn254_fq2_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fq2_from_u64" }, 14_227],
-        [algebra_ark_bn254_fq2_inv: InternalGas, { 12.. => "algebra.ark_bn254_fq2_inv" }, 1_161_471],
-        [algebra_ark_bn254_fq2_mul: InternalGas, { 12.. => "algebra.ark_bn254_fq2_mul" }, 22_085],
-        [algebra_ark_bn254_fq2_neg: InternalGas, { 12.. => "algebra.ark_bn254_fq2_neg" }, 4_319],
-        [algebra_ark_bn254_fq2_one: InternalGas, { 12.. => "algebra.ark_bn254_fq2_one" }, 209],
-        [algebra_ark_bn254_fq2_pow_u256: InternalGas, { 12.. => "algebra.ark_bn254_fq2_pow_u256" }, 6_265_467],
-        [algebra_ark_bn254_fq2_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fq2_serialize" }, 44_735],
-        [algebra_ark_bn254_fq2_square: InternalGas, { 12.. => "algebra.ark_bn254_fq2_square" }, 23_962],
-        [algebra_ark_bn254_fq2_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq2_sub" }, 8_116],
-        [algebra_ark_bn254_fq2_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq2_zero" }, 209],
         [algebra_ark_bn254_fq_add: InternalGas, { 12.. => "algebra.ark_bn254_fq_add" }, 4_373],
         [algebra_ark_bn254_fq_clone: InternalGas, { 12.. => "algebra.ark_bn254_fq_clone" }, 4_313],
         [algebra_ark_bn254_fq_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq_deser" }, 17_588],
diff --git a/crates/aptos-crypto/benches/ark_bn254.rs b/crates/aptos-crypto/benches/ark_bn254.rs
index 2cbd3b33f340c..33d8899dc9a19 100644
--- a/crates/aptos-crypto/benches/ark_bn254.rs
+++ b/crates/aptos-crypto/benches/ark_bn254.rs
@@ -80,21 +80,6 @@ fn bench_group(c: &mut Criterion) {
     group.bench_function("fq_square", bench_function_square::);
     group.bench_function("fq_sub", bench_function_sub::);
 
-    group.bench_function("fq2_add", bench_function_add::);
-    group.bench_function("fq2_clone", bench_function_clone::);
-    group.bench_function("fq2_deser", bench_function_deser_uncomp::);
-    group.bench_function("fq2_div", bench_function_div::);
-    group.bench_function("fq2_double", bench_function_double::);
-    group.bench_function("fq2_eq", bench_function_eq::);
-    group.bench_function("fq2_from_u64", bench_function_from_u64::);
-    group.bench_function("fq2_inv", bench_function_inv::);
-    group.bench_function("fq2_mul", bench_function_mul::);
-    group.bench_function("fq2_neg", bench_function_neg::);
-    group.bench_function("fq2_pow_u256", bench_function_pow_u256::);
-    group.bench_function("fq2_serialize", bench_function_serialize_uncomp::);
-    group.bench_function("fq2_square", bench_function_square::);
-    group.bench_function("fq2_sub", bench_function_sub::);
-
     group.bench_function("fq12_add", bench_function_add::);
     group.bench_function("fq12_clone", bench_function_clone::);
     group.bench_function("fq12_deser", bench_function_deser_uncomp::);
diff --git a/scripts/algebra-gas/update_bn254_algebra_gas_params.py b/scripts/algebra-gas/update_bn254_algebra_gas_params.py
index 80d906f1eda64..3bafa05900f77 100755
--- a/scripts/algebra-gas/update_bn254_algebra_gas_params.py
+++ b/scripts/algebra-gas/update_bn254_algebra_gas_params.py
@@ -62,21 +62,6 @@ def get_algebra_lines(gas_per_ns):
     nanoseconds['ark_bn254_fq_square'] = load_bench_ns.main('target/criterion/ark_bn254/fq_square')
     nanoseconds['ark_bn254_fq_sub'] = load_bench_ns.main('target/criterion/ark_bn254/fq_sub')
     nanoseconds['ark_bn254_fq_zero'] = 1
-    nanoseconds['ark_bn254_fq2_add'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_add')
-    nanoseconds['ark_bn254_fq2_clone'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_clone')
-    nanoseconds['ark_bn254_fq2_deser'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_deser')
-    nanoseconds['ark_bn254_fq2_div'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_div')
-    nanoseconds['ark_bn254_fq2_eq'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_eq')
-    nanoseconds['ark_bn254_fq2_from_u64'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_from_u64')
-    nanoseconds['ark_bn254_fq2_inv'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_inv')
-    nanoseconds['ark_bn254_fq2_mul'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_mul')
-    nanoseconds['ark_bn254_fq2_neg'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_neg')
-    nanoseconds['ark_bn254_fq2_one'] = 1
-    nanoseconds['ark_bn254_fq2_pow_u256'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_pow_u256')
-    nanoseconds['ark_bn254_fq2_serialize'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_serialize')
-    nanoseconds['ark_bn254_fq2_square'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_square')
-    nanoseconds['ark_bn254_fq2_sub'] = load_bench_ns.main('target/criterion/ark_bn254/fq2_sub')
-    nanoseconds['ark_bn254_fq2_zero'] = 1
     nanoseconds['ark_bn254_fq12_add'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_add')
     nanoseconds['ark_bn254_fq12_clone'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_clone')
     nanoseconds['ark_bn254_fq12_deser'] = load_bench_ns.main('target/criterion/ark_bn254/fq12_deser')

From 62e3cf8f0d0b4a568afcda4851c68c31c351bd3f Mon Sep 17 00:00:00 2001
From: caojiafeng 
Date: Sun, 10 Dec 2023 17:55:11 +0800
Subject: [PATCH 17/21] address comments on bench

Signed-off-by: caojiafeng 
---
 crates/aptos-crypto/benches/ark_bls12_381.rs | 341 +++----------------
 crates/aptos-crypto/benches/ark_bn254.rs     |   2 +-
 2 files changed, 49 insertions(+), 294 deletions(-)

diff --git a/crates/aptos-crypto/benches/ark_bls12_381.rs b/crates/aptos-crypto/benches/ark_bls12_381.rs
index 341376dca48ea..cdae361b229a6 100644
--- a/crates/aptos-crypto/benches/ark_bls12_381.rs
+++ b/crates/aptos-crypto/benches/ark_bls12_381.rs
@@ -6,18 +6,27 @@
 #[macro_use]
 extern crate criterion;
 
+use crate::bench_utils::{
+    bench_function_add, bench_function_clone, bench_function_deser_comp,
+    bench_function_deser_uncomp, bench_function_div, bench_function_double, bench_function_eq,
+    bench_function_from_u64, bench_function_inv, bench_function_mul, bench_function_neg,
+    bench_function_pow_u256, bench_function_serialize_uncomp, bench_function_square,
+    bench_function_sub,
+};
 use aptos_crypto::test_utils::random_bytes;
 use ark_bls12_381::{Fq12, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
 use ark_ec::{
     hashing::HashToCurve, pairing::Pairing, short_weierstrass::Projective, AffineRepr, CurveGroup,
     Group,
 };
-use ark_ff::{BigInteger256, Field, One, UniformRand, Zero};
+use ark_ff::{One, UniformRand, Zero};
 use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
 use ark_std::test_rng;
 use criterion::{BenchmarkId, Criterion};
 use rand::thread_rng;
-use std::ops::{Add, Div, Mul, Neg};
+use std::ops::{Add, Mul, Neg};
+
+mod bench_utils;
 
 fn msm_all_bench_cases() -> Vec {
     let series_until_65 = (1..65).step_by(2);
@@ -46,26 +55,9 @@ macro_rules! serialize {
 fn bench_group(c: &mut Criterion) {
     let mut group = c.benchmark_group("ark_bls12_381");
 
-    group.bench_function("fr_add", move |b| {
-        b.iter_with_setup(
-            || (rand!(Fr), rand!(Fr)),
-            |(k_1, k_2)| {
-                let _k_3 = k_1 + k_2;
-            },
-        )
-    });
+    group.bench_function("fr_add", bench_function_add::);
 
-    group.bench_function("fr_deser", move |b| {
-        b.iter_with_setup(
-            || {
-                let k = rand!(Fr);
-                serialize!(k, serialize_uncompressed)
-            },
-            |buf| {
-                let _k = Fr::deserialize_uncompressed(buf.as_slice()).unwrap();
-            },
-        )
-    });
+    group.bench_function("fr_deser", bench_function_deser_uncomp::);
 
     group.bench_function("fr_deser_invalid_4_bytes", move |b| {
         b.iter_with_setup(
@@ -94,54 +86,17 @@ fn bench_group(c: &mut Criterion) {
         )
     });
 
-    group.bench_function("fr_div", move |b| {
-        b.iter_with_setup(
-            || (rand!(Fr), rand!(Fr)),
-            |(k_1, k_2)| {
-                let _k_3 = k_1 / k_2;
-            },
-        )
-    });
-
-    group.bench_function("fr_eq", move |b| {
-        b.iter_with_setup(
-            || {
-                let k_1 = rand!(Fr);
-                let k_2 = k_1;
-                (k_1, k_2)
-            },
-            |(k_1, k_2)| {
-                let _res = k_1 == k_2;
-            },
-        )
-    });
-
-    group.bench_function("fr_from_u64", move |b| {
-        b.iter_with_setup(
-            || rand!(u64),
-            |v| {
-                let _res: Fr = BigInteger256::from(v).into();
-            },
-        )
-    });
-
-    group.bench_function("fr_inv", move |b| {
-        b.iter_with_setup(
-            || rand!(Fr),
-            |k| {
-                let _k_inv = k.inverse();
-            },
-        )
-    });
-
-    group.bench_function("fr_mul", move |b| {
-        b.iter_with_setup(
-            || (rand!(Fr), rand!(Fr)),
-            |(k_1, k_2)| {
-                let _k_3 = k_1 * k_2;
-            },
-        )
-    });
+    group.bench_function("fr_div", bench_function_div::);
+    group.bench_function("fr_double", bench_function_double::);
+    group.bench_function("fr_eq", bench_function_eq::);
+    group.bench_function("fr_from_u64", bench_function_from_u64::);
+    group.bench_function("fr_inv", bench_function_inv::);
+    group.bench_function("fr_mul", bench_function_mul::);
+    group.bench_function("fr_neg", bench_function_neg::);
+    group.bench_function("fr_pow_u256", bench_function_pow_u256::);
+    group.bench_function("fr_serialize", bench_function_serialize_uncomp::);
+    group.bench_function("fr_square", bench_function_square::);
+    group.bench_function("fr_sub", bench_function_sub::);
 
     group.bench_function("fr_mul_self", move |b| {
         b.iter_with_setup(
@@ -152,15 +107,6 @@ fn bench_group(c: &mut Criterion) {
         )
     });
 
-    group.bench_function("fr_neg", move |b| {
-        b.iter_with_setup(
-            || rand!(Fr),
-            |k| {
-                let _k_inv = k.neg();
-            },
-        )
-    });
-
     group.bench_function("fr_one", move |b| {
         b.iter_with_setup(
             || {},
@@ -170,33 +116,6 @@ fn bench_group(c: &mut Criterion) {
         )
     });
 
-    group.bench_function("fr_serialize", move |b| {
-        b.iter_with_setup(
-            || rand!(Fr),
-            |k| {
-                let _buf = serialize!(k, serialize_uncompressed);
-            },
-        )
-    });
-
-    group.bench_function("fr_square", move |b| {
-        b.iter_with_setup(
-            || rand!(Fr),
-            |k| {
-                let _k2 = k.square();
-            },
-        )
-    });
-
-    group.bench_function("fr_sub", move |b| {
-        b.iter_with_setup(
-            || (rand!(Fr), rand!(Fr)),
-            |(k_1, k_2)| {
-                let _k_3 = k_1 - k_2;
-            },
-        )
-    });
-
     group.bench_function("fr_zero", move |b| {
         b.iter_with_setup(
             || {},
@@ -205,15 +124,20 @@ fn bench_group(c: &mut Criterion) {
             },
         )
     });
-
-    group.bench_function("fq12_add", move |b| {
-        b.iter_with_setup(
-            || (rand!(Fq12), rand!(Fq12)),
-            |(e_1, e_2)| {
-                let _e_3 = e_1 + e_2;
-            },
-        )
-    });
+    group.bench_function("fq12_add", bench_function_add::);
+    group.bench_function("fq12_clone", bench_function_clone::);
+    group.bench_function("fq12_deser", bench_function_deser_uncomp::);
+    group.bench_function("fq12_div", bench_function_div::);
+    group.bench_function("fq12_double", bench_function_double::);
+    group.bench_function("fq12_eq", bench_function_eq::);
+    group.bench_function("fq12_from_u64", bench_function_from_u64::);
+    group.bench_function("fq12_inv", bench_function_inv::);
+    group.bench_function("fq12_mul", bench_function_mul::);
+    group.bench_function("fq12_neg", bench_function_neg::);
+    group.bench_function("fq12_pow_u256", bench_function_pow_u256::);
+    group.bench_function("fq12_serialize", bench_function_serialize_uncomp::);
+    group.bench_function("fq12_square", bench_function_square::);
+    group.bench_function("fq12_sub", bench_function_sub::);
 
     group.bench_function("fq12_add_self", move |b| {
         b.iter_with_setup(
@@ -224,89 +148,6 @@ fn bench_group(c: &mut Criterion) {
         )
     });
 
-    group.bench_function("fq12_clone", move |b| {
-        b.iter_with_setup(
-            || rand!(Fq12),
-            |e| {
-                let _e_2 = e;
-            },
-        )
-    });
-
-    group.bench_function("fq12_deser", move |b| {
-        b.iter_with_setup(
-            || {
-                let e = rand!(Fq12);
-                serialize!(e, serialize_uncompressed)
-            },
-            |buf| {
-                let _e = Fq12::deserialize_uncompressed(buf.as_slice()).unwrap();
-            },
-        )
-    });
-
-    group.bench_function("fq12_div", move |b| {
-        b.iter_with_setup(
-            || {
-                let e = rand!(Fq12);
-                let f = rand!(Fq12);
-                (e, f)
-            },
-            |(e, f)| {
-                let _g = e.div(f);
-            },
-        )
-    });
-
-    group.bench_function("fq12_double", move |b| {
-        b.iter_with_setup(
-            || rand!(Fq12),
-            |e| {
-                let _e_2 = e.double();
-            },
-        )
-    });
-
-    group.bench_function("fq12_eq", move |b| {
-        b.iter_with_setup(
-            || {
-                let e_1 = rand!(Fq12);
-                let e_2 = e_1;
-                (e_1, e_2)
-            },
-            |(e_1, e_2)| {
-                let _res = e_1 == e_2;
-            },
-        )
-    });
-
-    group.bench_function("fq12_from_u64", move |b| {
-        b.iter_with_setup(
-            || rand!(u64),
-            |i| {
-                let _res = Fq12::from(i);
-            },
-        )
-    });
-
-    group.bench_function("fq12_inv", move |b| {
-        b.iter_with_setup(
-            || rand!(Fq12),
-            |e| {
-                let _e_inv = e.inverse();
-            },
-        )
-    });
-
-    group.bench_function("fq12_mul", move |b| {
-        b.iter_with_setup(
-            || (rand!(Fq12), rand!(Fq12)),
-            |(e_1, e_2)| {
-                let _e_3 = e_1 * e_2;
-            },
-        )
-    });
-
     group.bench_function("fq12_mul_self", move |b| {
         b.iter_with_setup(
             || rand!(Fq12),
@@ -316,63 +157,12 @@ fn bench_group(c: &mut Criterion) {
         )
     });
 
-    group.bench_function("fq12_neg", move |b| {
-        b.iter_with_setup(
-            || rand!(Fq12),
-            |e| {
-                let _e_2 = e.neg();
-            },
-        )
-    });
-
     group.bench_function("fq12_one", move |b| {
         b.iter(|| {
             let _e = Fq12::one();
         })
     });
 
-    group.bench_function("fq12_pow_u256", move |b| {
-        b.iter_with_setup(
-            || {
-                let base = rand!(Fq12);
-                let exp = rand!(Fr);
-                let exp = BigInteger256::from(exp);
-                (base, exp)
-            },
-            |(base, exp)| {
-                let _res = base.pow(exp);
-            },
-        )
-    });
-
-    group.bench_function("fq12_serialize", move |b| {
-        b.iter_with_setup(
-            || rand!(Fq12),
-            |e| {
-                let mut buf = vec![];
-                e.serialize_uncompressed(&mut buf).unwrap();
-            },
-        )
-    });
-
-    group.bench_function("fq12_square", move |b| {
-        b.iter_with_setup(
-            || rand!(Fq12),
-            |e| {
-                let _res = e.square();
-            },
-        )
-    });
-
-    group.bench_function("fq12_sub", move |b| {
-        b.iter_with_setup(
-            || (rand!(Fq12), rand!(Fq12)),
-            |(e, f)| {
-                let _res = e - f;
-            },
-        )
-    });
-
     group.bench_function("fq12_zero", move |b| {
         b.iter_with_setup(
             || (),
@@ -382,51 +172,16 @@ fn bench_group(c: &mut Criterion) {
         )
     });
 
-    group.bench_function("g1_affine_add", move |b| {
-        b.iter_with_setup(
-            || (rand!(G1Affine), rand!(G1Affine)),
-            |(p1, p2)| {
-                let _p3 = p1 + p2;
-            },
-        )
-    });
-
-    group.bench_function("g1_affine_deser_comp", move |b| {
-        b.iter_with_setup(
-            || {
-                let p = rand!(G1Affine);
-                serialize!(p, serialize_compressed)
-            },
-            |buf| {
-                let _p = G1Affine::deserialize_compressed(buf.as_slice());
-            },
-        )
-    });
-
-    group.bench_function("g1_affine_deser_uncomp", move |b| {
-        b.iter_with_setup(
-            || {
-                let p = rand!(G1Affine);
-                serialize!(p, serialize_uncompressed)
-            },
-            |buf| {
-                let _p = G1Affine::deserialize_uncompressed(buf.as_slice());
-            },
-        )
-    });
-
-    group.bench_function("g1_affine_eq", move |b| {
-        b.iter_with_setup(
-            || {
-                let p1 = rand!(G1Affine);
-                let p2 = p1;
-                (p1, p2)
-            },
-            |(p1, p2)| {
-                let _res = p1 == Projective::from(p2);
-            },
-        )
-    });
+    group.bench_function("g1_affine_add", bench_function_add::);
+    group.bench_function(
+        "g1_affine_deser_comp",
+        bench_function_deser_comp::,
+    );
+    group.bench_function(
+        "g1_affine_deser_uncomp",
+        bench_function_deser_uncomp::,
+    );
+    group.bench_function("g1_affine_eq", bench_function_eq::);
 
     group.bench_function("g1_affine_generator", move |b| {
         b.iter(|| {
diff --git a/crates/aptos-crypto/benches/ark_bn254.rs b/crates/aptos-crypto/benches/ark_bn254.rs
index 33d8899dc9a19..1b36d34177a2b 100644
--- a/crates/aptos-crypto/benches/ark_bn254.rs
+++ b/crates/aptos-crypto/benches/ark_bn254.rs
@@ -13,7 +13,7 @@ use crate::bench_utils::{
     bench_function_pow_u256, bench_function_serialize_uncomp, bench_function_square,
     bench_function_sub,
 };
-use ark_bn254::{Fq, Fq12, Fq2, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
+use ark_bn254::{Fq, Fq12, Fr, G1Affine, G1Projective, G2Affine, G2Projective};
 use ark_ec::{pairing::Pairing, short_weierstrass::Projective, AffineRepr, CurveGroup, Group};
 use ark_ff::{UniformRand, Zero};
 use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};

From 61858266daf3b29c143df2bb5ac904e07285a806 Mon Sep 17 00:00:00 2001
From: "zhoujun.ma" 
Date: Mon, 11 Dec 2023 14:23:42 -0800
Subject: [PATCH 18/21] lint, also hardcode BN254 Gt generator to save cold
 start time

---
 .../src/natives/cryptography/algebra/constants.rs    |  5 +++--
 .../src/natives/cryptography/algebra/mod.rs          | 12 +++++-------
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/aptos-move/framework/src/natives/cryptography/algebra/constants.rs b/aptos-move/framework/src/natives/cryptography/algebra/constants.rs
index abee6b1e4f054..4865372ec2eb7 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/constants.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/constants.rs
@@ -4,8 +4,9 @@ use crate::{
     abort_unless_arithmetics_enabled_for_structure, abort_unless_feature_flag_enabled,
     natives::cryptography::algebra::{
         feature_flag_from_structure, AlgebraContext, Structure, BLS12381_GT_GENERATOR,
-        BLS12381_Q12_LENDIAN, BLS12381_R_LENDIAN, BN254_GT_GENERATOR, BN254_Q12_LENDIAN, BN254_Q_LENDIAN, BN254_R_LENDIAN, E_TOO_MUCH_MEMORY_USED,
-        MEMORY_LIMIT_IN_BYTES, MOVE_ABORT_CODE_NOT_IMPLEMENTED,
+        BLS12381_Q12_LENDIAN, BLS12381_R_LENDIAN, BN254_GT_GENERATOR, BN254_Q12_LENDIAN,
+        BN254_Q_LENDIAN, BN254_R_LENDIAN, E_TOO_MUCH_MEMORY_USED, MEMORY_LIMIT_IN_BYTES,
+        MOVE_ABORT_CODE_NOT_IMPLEMENTED,
     },
     store_element, structure_from_ty_arg,
 };
diff --git a/aptos-move/framework/src/natives/cryptography/algebra/mod.rs b/aptos-move/framework/src/natives/cryptography/algebra/mod.rs
index 6a300fdbe7bbe..919e983b44f01 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/mod.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/mod.rs
@@ -27,7 +27,7 @@ use arithmetics::{
 };
 use ark_ec::{pairing::Pairing, AffineRepr};
 use ark_ff::{BigInteger, PrimeField};
-use ark_serialize::CanonicalDeserialize;
+use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
 use better_any::{Tid, TidAble};
 use move_binary_format::errors::PartialVMError;
 use move_core_types::{language_storage::TypeTag, vm_status::StatusCode};
@@ -303,14 +303,12 @@ static BLS12381_Q12_LENDIAN: Lazy> = Lazy::new(|| {
     hex::decode("1175f55da544c7625f8ccb1360e2b1d3ca40747811c8f5ed04440afe232b476c0215676aec05f2a44ac2da6b6d1b7cff075e7b2a587e0aab601a8d3db4f0d29906e5e4d0d78119f396d5a59f0f8d1ca8bca62540be6ab9c12d0ca00de1f311f106278d000e55a393c9766a74e0d08a298450f60d7e666575e3354bf14b8731f4e721c0c180a5ed55c2f8f51f815baecbf96b5fc717eb58ac161a27d1d5f2bdc1a079609b9d6449165b2466b32a01eac7992a1ea0cac2f223cde1d56f9bbccc67afe44621daf858df3fc0eb837818f3e42ab3e131ce4e492efa63c108e6ef91c29ed63b3045baebcb0ab8d203c7f558beaffccba31b12aca7f54b58d0c28340e4fdb3c7c94fe9c4fef9d640ff2fcff02f1748416cbed0981fbff49f0e39eaf8a30273e67ed851944d33d6a593ef5ddcd62da84568822a6045b633bf6a513b3cfe8f9de13e76f8dcbd915980dec205eab6a5c0c72dcebd9afff1d25509ddbf33f8e24131fbd74cda93336514340cf8036b66b09ed9e6a6ac37e22fb3ac407e321beae8cd9fe74c8aaeb4edaa9a7272848fc623f6fe835a2e647379f547fc5ec6371318a85bfa60009cb20ccbb8a467492988a87633c14c0324ba0d0c3e1798ed29c8494cea35023746da05e35d184b4a301d5b2238d665495c6318b5af8653758008952d06cb9e62487b196d64383c73c06d6e1cccdf9b3ce8f95679e7050d949004a55f4ccf95b2552880ae36d1f7e09504d2338316d87d14a064511a295d768113e301bdf9d4383a8be32192d3f2f3b2de14181c73839a7cb4af5301").unwrap()
 });
 
-/// Gt = e(G1, G2)
 static BN254_GT_GENERATOR: Lazy = Lazy::new(|| {
-    ark_bn254::Bn254::pairing(
-        ark_bn254::G1Affine::generator(),
-        ark_bn254::G2Affine::generator(),
-    )
-    .0
+    // Gt generator is defined as the `e(g1_generator, g2_generator)`.
+    let buf = hex::decode("950e879d73631f5eb5788589eb5f7ef8d63e0a28de1ba00dfe4ca9ed3f252b264a8afb8eb4349db466ed1809ea4d7c39bdab7938821f1b0a00a295c72c2de002e01dbdfd0254134efcb1ec877395d25f937719b344adb1a58d129be2d6f2a9132b16a16e8ab030b130e69c69bd20b4c45986e6744a98314b5c1a0f50faa90b04dbaf9ef8aeeee3f50be31c210b598f4752f073987f9d35be8f6770d83f2ffc0af0d18dd9d2dbcdf943825acc12a7a9ddca45e629d962c6bd64908c3930a5541cfe2924dcc5580d5cef7a4bfdec90a91b59926f850d4a7923c01a5a5dbf0f5c094a2b9fb9d415820fa6b40c59bb9eade9c953407b0fc11da350a9d872cad6d3142974ca385854afdf5f583c04231adc5957c8914b6b20dc89660ed7c3bbe7c01d972be2d53ecdb27a1bcc16ac610db95aa7d237c8ff55a898cb88645a0e32530b23d7ebf5dafdd79b0f9c2ac4ba07ce18d3d16cf36e47916c4cae5d08d3afa813972c769e8514533e380c9443b3e1ee5c96fa3a0a73f301b626454721527bf900").unwrap();
+    ark_bn254::Fq12::deserialize_uncompressed(buf.as_slice()).unwrap()
 });
+
 static BN254_R_LENDIAN: Lazy> = Lazy::new(|| BN254_R_SCALAR.to_bytes_le());
 const BN254_R_SCALAR: ark_ff::BigInteger256 = ark_bn254::Fr::MODULUS;
 static BN254_Q_LENDIAN: Lazy> = Lazy::new(|| BN254_Q_SCALAR.to_bytes_le());

From 2f3e78a7e8cb1492e470216bb555fba83b4ce1d8 Mon Sep 17 00:00:00 2001
From: "zhoujun.ma" 
Date: Mon, 11 Dec 2023 14:55:40 -0800
Subject: [PATCH 19/21] revert debugging stuff

---
 .../e2e-move-tests/src/tests/per_category_gas_limits.rs   | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs
index 3610ab21309e9..012538886f613 100644
--- a/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs
+++ b/aptos-move/e2e-move-tests/src/tests/per_category_gas_limits.rs
@@ -95,13 +95,7 @@ fn io_limit_reached_by_new_bytes() {
     });
 
     test_create_multiple_items(&mut h, &acc, |status| {
-        use aptos_types::transaction::*;
-        assert_eq!(
-            status,
-            TransactionStatus::Keep(ExecutionStatus::MiscellaneousError(Some(
-                StatusCode::IO_LIMIT_REACHED
-            )))
-        );
+        assert_vm_status!(status, StatusCode::IO_LIMIT_REACHED);
     });
 }
 

From a77c7e341afe21663b398ae893cc5a95ce1acfc8 Mon Sep 17 00:00:00 2001
From: "zhoujun.ma" 
Date: Mon, 11 Dec 2023 16:02:30 -0800
Subject: [PATCH 20/21] update gas version

---
 .../src/gas_schedule/aptos_framework.rs       | 146 +++++++++---------
 aptos-move/aptos-gas-schedule/src/ver.rs      |   4 +-
 .../update_bn254_algebra_gas_params.py        |   2 +-
 3 files changed, 77 insertions(+), 75 deletions(-)

diff --git a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs
index 7f1b64793a1e7..c31c2b81bc2b1 100644
--- a/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs
+++ b/aptos-move/aptos-gas-schedule/src/gas_schedule/aptos_framework.rs
@@ -18,82 +18,82 @@ crate::gas_schedule::macros::define_gas_parameters!(
 
         // BN254 algebra gas parameters begin.
         // Generated at time 1701559125.5498126 by `scripts/algebra-gas/update_bn254_algebra_gas_params.py` with gas_per_ns=209.10511688369482.
-        [algebra_ark_bn254_fq12_add: InternalGas, { 12.. => "algebra.ark_bn254_fq12_add" }, 4_406],
-        [algebra_ark_bn254_fq12_clone: InternalGas, { 12.. => "algebra.ark_bn254_fq12_clone" }, 4_392],
-        [algebra_ark_bn254_fq12_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq12_deser" }, 129_063],
-        [algebra_ark_bn254_fq12_div: InternalGas, { 12.. => "algebra.ark_bn254_fq12_div" }, 2_813_602],
-        [algebra_ark_bn254_fq12_eq: InternalGas, { 12.. => "algebra.ark_bn254_fq12_eq" }, 12_142],
-        [algebra_ark_bn254_fq12_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fq12_from_u64" }, 14_463],
-        [algebra_ark_bn254_fq12_inv: InternalGas, { 12.. => "algebra.ark_bn254_fq12_inv" }, 2_168_418],
-        [algebra_ark_bn254_fq12_mul: InternalGas, { 12.. => "algebra.ark_bn254_fq12_mul" }, 643_914],
-        [algebra_ark_bn254_fq12_neg: InternalGas, { 12.. => "algebra.ark_bn254_fq12_neg" }, 13_311],
-        [algebra_ark_bn254_fq12_one: InternalGas, { 12.. => "algebra.ark_bn254_fq12_one" }, 209],
-        [algebra_ark_bn254_fq12_pow_u256: InternalGas, { 12.. => "algebra.ark_bn254_fq12_pow_u256" }, 192_871_746],
-        [algebra_ark_bn254_fq12_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fq12_serialize" }, 117_336],
-        [algebra_ark_bn254_fq12_square: InternalGas, { 12.. => "algebra.ark_bn254_fq12_square" }, 468_955],
-        [algebra_ark_bn254_fq12_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq12_sub" }, 30_497],
-        [algebra_ark_bn254_fq12_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq12_zero" }, 209],
-        [algebra_ark_bn254_fq_add: InternalGas, { 12.. => "algebra.ark_bn254_fq_add" }, 4_373],
-        [algebra_ark_bn254_fq_clone: InternalGas, { 12.. => "algebra.ark_bn254_fq_clone" }, 4_313],
-        [algebra_ark_bn254_fq_deser: InternalGas, { 12.. => "algebra.ark_bn254_fq_deser" }, 17_588],
-        [algebra_ark_bn254_fq_div: InternalGas, { 12.. => "algebra.ark_bn254_fq_div" }, 1_140_544],
-        [algebra_ark_bn254_fq_eq: InternalGas, { 12.. => "algebra.ark_bn254_fq_eq" }, 4_373],
-        [algebra_ark_bn254_fq_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fq_from_u64" }, 14_137],
-        [algebra_ark_bn254_fq_inv: InternalGas, { 12.. => "algebra.ark_bn254_fq_inv" }, 1_136_577],
-        [algebra_ark_bn254_fq_mul: InternalGas, { 12.. => "algebra.ark_bn254_fq_mul" }, 10_050],
-        [algebra_ark_bn254_fq_neg: InternalGas, { 12.. => "algebra.ark_bn254_fq_neg" }, 4_314],
-        [algebra_ark_bn254_fq_one: InternalGas, { 12.. => "algebra.ark_bn254_fq_one" }, 209],
-        [algebra_ark_bn254_fq_pow_u256: InternalGas, { 12.. => "algebra.ark_bn254_fq_pow_u256" }, 2_081_451],
-        [algebra_ark_bn254_fq_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fq_serialize" }, 25_938],
-        [algebra_ark_bn254_fq_square: InternalGas, { 12.. => "algebra.ark_bn254_fq_square" }, 4_314],
-        [algebra_ark_bn254_fq_sub: InternalGas, { 12.. => "algebra.ark_bn254_fq_sub" }, 6_148],
-        [algebra_ark_bn254_fq_zero: InternalGas, { 12.. => "algebra.ark_bn254_fq_zero" }, 209],
-        [algebra_ark_bn254_fr_add: InternalGas, { 12.. => "algebra.ark_bn254_fr_add" }, 4_377],
-        [algebra_ark_bn254_fr_deser: InternalGas, { 12.. => "algebra.ark_bn254_fr_deser" }, 16_722],
-        [algebra_ark_bn254_fr_div: InternalGas, { 12.. => "algebra.ark_bn254_fr_div" }, 1_217_943],
-        [algebra_ark_bn254_fr_eq: InternalGas, { 12.. => "algebra.ark_bn254_fr_eq" }, 4_396],
-        [algebra_ark_bn254_fr_from_u64: InternalGas, { 12.. => "algebra.ark_bn254_fr_from_u64" }, 13_485],
-        [algebra_ark_bn254_fr_inv: InternalGas, { 12.. => "algebra.ark_bn254_fr_inv" }, 1_209_015],
-        [algebra_ark_bn254_fr_mul: InternalGas, { 12.. => "algebra.ark_bn254_fr_mul" }, 9_867],
-        [algebra_ark_bn254_fr_neg: InternalGas, { 12.. => "algebra.ark_bn254_fr_neg" }, 4_314],
-        [algebra_ark_bn254_fr_one: InternalGas, { 12.. => "algebra.ark_bn254_fr_one" }, 0],
-        [algebra_ark_bn254_fr_serialize: InternalGas, { 12.. => "algebra.ark_bn254_fr_serialize" }, 25_749],
-        [algebra_ark_bn254_fr_square: InternalGas, { 12.. => "algebra.ark_bn254_fr_square" }, 4_311],
-        [algebra_ark_bn254_fr_sub: InternalGas, { 12.. => "algebra.ark_bn254_fr_sub" }, 10_370],
-        [algebra_ark_bn254_fr_zero: InternalGas, { 12.. => "algebra.ark_bn254_fr_zero" }, 209],
-        [algebra_ark_bn254_g1_affine_deser_comp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_deser_comp" }, 23_497_333],
-        [algebra_ark_bn254_g1_affine_deser_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_deser_uncomp" }, 21_528_706],
-        [algebra_ark_bn254_g1_affine_serialize_comp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_serialize_comp" }, 44_924],
-        [algebra_ark_bn254_g1_affine_serialize_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g1_affine_serialize_uncomp" }, 58_820],
-        [algebra_ark_bn254_g1_proj_add: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_add" }, 106_501],
-        [algebra_ark_bn254_g1_proj_double: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_double" }, 63_682],
-        [algebra_ark_bn254_g1_proj_eq: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_eq" }, 53_021],
-        [algebra_ark_bn254_g1_proj_generator: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_generator" }, 209],
-        [algebra_ark_bn254_g1_proj_infinity: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_infinity" }, 209],
-        [algebra_ark_bn254_g1_proj_neg: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_neg" }, 209],
-        [algebra_ark_bn254_g1_proj_scalar_mul: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_scalar_mul" }, 26_456_386],
-        [algebra_ark_bn254_g1_proj_sub: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_sub" }, 106_903],
-        [algebra_ark_bn254_g1_proj_to_affine: InternalGas, { 12.. => "algebra.ark_bn254_g1_proj_to_affine" }, 6_340],
-        [algebra_ark_bn254_g2_affine_deser_comp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_deser_comp" }, 67_710_223],
-        [algebra_ark_bn254_g2_affine_deser_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_deser_uncomp" }, 60_677_591],
-        [algebra_ark_bn254_g2_affine_serialize_comp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_serialize_comp" }, 69_214],
-        [algebra_ark_bn254_g2_affine_serialize_uncomp: InternalGas, { 12.. => "algebra.ark_bn254_g2_affine_serialize_uncomp" }, 98_505],
-        [algebra_ark_bn254_g2_proj_add: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_add" }, 318_234],
-        [algebra_ark_bn254_g2_proj_double: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_double" }, 158_874],
-        [algebra_ark_bn254_g2_proj_eq: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_eq" }, 141_359],
-        [algebra_ark_bn254_g2_proj_generator: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_generator" }, 209],
-        [algebra_ark_bn254_g2_proj_infinity: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_infinity" }, 209],
-        [algebra_ark_bn254_g2_proj_neg: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_neg" }, 209],
-        [algebra_ark_bn254_g2_proj_scalar_mul: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_scalar_mul" }, 76_395_801],
-        [algebra_ark_bn254_g2_proj_sub: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_sub" }, 321_727],
-        [algebra_ark_bn254_g2_proj_to_affine: InternalGas, { 12.. => "algebra.ark_bn254_g2_proj_to_affine" }, 1_251_909],
-        [algebra_ark_bn254_multi_pairing_base: InternalGas, { 12.. => "algebra.ark_bn254_multi_pairing_base" }, 127_794_596],
-        [algebra_ark_bn254_multi_pairing_per_pair: InternalGasPerArg, { 12.. => "algebra.ark_bn254_multi_pairing_per_pair" }, 67_624_587],
-        [algebra_ark_bn254_pairing: InternalGas, { 12.. => "algebra.ark_bn254_pairing" }, 209_703_839],
+        [algebra_ark_bn254_fq12_add: InternalGas, { 13.. => "algebra.ark_bn254_fq12_add" }, 4_406],
+        [algebra_ark_bn254_fq12_clone: InternalGas, { 13.. => "algebra.ark_bn254_fq12_clone" }, 4_392],
+        [algebra_ark_bn254_fq12_deser: InternalGas, { 13.. => "algebra.ark_bn254_fq12_deser" }, 129_063],
+        [algebra_ark_bn254_fq12_div: InternalGas, { 13.. => "algebra.ark_bn254_fq12_div" }, 2_813_602],
+        [algebra_ark_bn254_fq12_eq: InternalGas, { 13.. => "algebra.ark_bn254_fq12_eq" }, 12_142],
+        [algebra_ark_bn254_fq12_from_u64: InternalGas, { 13.. => "algebra.ark_bn254_fq12_from_u64" }, 14_463],
+        [algebra_ark_bn254_fq12_inv: InternalGas, { 13.. => "algebra.ark_bn254_fq12_inv" }, 2_168_418],
+        [algebra_ark_bn254_fq12_mul: InternalGas, { 13.. => "algebra.ark_bn254_fq12_mul" }, 643_914],
+        [algebra_ark_bn254_fq12_neg: InternalGas, { 13.. => "algebra.ark_bn254_fq12_neg" }, 13_311],
+        [algebra_ark_bn254_fq12_one: InternalGas, { 13.. => "algebra.ark_bn254_fq12_one" }, 209],
+        [algebra_ark_bn254_fq12_pow_u256: InternalGas, { 13.. => "algebra.ark_bn254_fq12_pow_u256" }, 192_871_746],
+        [algebra_ark_bn254_fq12_serialize: InternalGas, { 13.. => "algebra.ark_bn254_fq12_serialize" }, 117_336],
+        [algebra_ark_bn254_fq12_square: InternalGas, { 13.. => "algebra.ark_bn254_fq12_square" }, 468_955],
+        [algebra_ark_bn254_fq12_sub: InternalGas, { 13.. => "algebra.ark_bn254_fq12_sub" }, 30_497],
+        [algebra_ark_bn254_fq12_zero: InternalGas, { 13.. => "algebra.ark_bn254_fq12_zero" }, 209],
+        [algebra_ark_bn254_fq_add: InternalGas, { 13.. => "algebra.ark_bn254_fq_add" }, 4_373],
+        [algebra_ark_bn254_fq_clone: InternalGas, { 13.. => "algebra.ark_bn254_fq_clone" }, 4_313],
+        [algebra_ark_bn254_fq_deser: InternalGas, { 13.. => "algebra.ark_bn254_fq_deser" }, 17_588],
+        [algebra_ark_bn254_fq_div: InternalGas, { 13.. => "algebra.ark_bn254_fq_div" }, 1_140_544],
+        [algebra_ark_bn254_fq_eq: InternalGas, { 13.. => "algebra.ark_bn254_fq_eq" }, 4_373],
+        [algebra_ark_bn254_fq_from_u64: InternalGas, { 13.. => "algebra.ark_bn254_fq_from_u64" }, 14_137],
+        [algebra_ark_bn254_fq_inv: InternalGas, { 13.. => "algebra.ark_bn254_fq_inv" }, 1_136_577],
+        [algebra_ark_bn254_fq_mul: InternalGas, { 13.. => "algebra.ark_bn254_fq_mul" }, 10_050],
+        [algebra_ark_bn254_fq_neg: InternalGas, { 13.. => "algebra.ark_bn254_fq_neg" }, 4_314],
+        [algebra_ark_bn254_fq_one: InternalGas, { 13.. => "algebra.ark_bn254_fq_one" }, 209],
+        [algebra_ark_bn254_fq_pow_u256: InternalGas, { 13.. => "algebra.ark_bn254_fq_pow_u256" }, 2_081_451],
+        [algebra_ark_bn254_fq_serialize: InternalGas, { 13.. => "algebra.ark_bn254_fq_serialize" }, 25_938],
+        [algebra_ark_bn254_fq_square: InternalGas, { 13.. => "algebra.ark_bn254_fq_square" }, 4_314],
+        [algebra_ark_bn254_fq_sub: InternalGas, { 13.. => "algebra.ark_bn254_fq_sub" }, 6_148],
+        [algebra_ark_bn254_fq_zero: InternalGas, { 13.. => "algebra.ark_bn254_fq_zero" }, 209],
+        [algebra_ark_bn254_fr_add: InternalGas, { 13.. => "algebra.ark_bn254_fr_add" }, 4_377],
+        [algebra_ark_bn254_fr_deser: InternalGas, { 13.. => "algebra.ark_bn254_fr_deser" }, 16_722],
+        [algebra_ark_bn254_fr_div: InternalGas, { 13.. => "algebra.ark_bn254_fr_div" }, 1_217_943],
+        [algebra_ark_bn254_fr_eq: InternalGas, { 13.. => "algebra.ark_bn254_fr_eq" }, 4_396],
+        [algebra_ark_bn254_fr_from_u64: InternalGas, { 13.. => "algebra.ark_bn254_fr_from_u64" }, 13_485],
+        [algebra_ark_bn254_fr_inv: InternalGas, { 13.. => "algebra.ark_bn254_fr_inv" }, 1_209_015],
+        [algebra_ark_bn254_fr_mul: InternalGas, { 13.. => "algebra.ark_bn254_fr_mul" }, 9_867],
+        [algebra_ark_bn254_fr_neg: InternalGas, { 13.. => "algebra.ark_bn254_fr_neg" }, 4_314],
+        [algebra_ark_bn254_fr_one: InternalGas, { 13.. => "algebra.ark_bn254_fr_one" }, 0],
+        [algebra_ark_bn254_fr_serialize: InternalGas, { 13.. => "algebra.ark_bn254_fr_serialize" }, 25_749],
+        [algebra_ark_bn254_fr_square: InternalGas, { 13.. => "algebra.ark_bn254_fr_square" }, 4_311],
+        [algebra_ark_bn254_fr_sub: InternalGas, { 13.. => "algebra.ark_bn254_fr_sub" }, 10_370],
+        [algebra_ark_bn254_fr_zero: InternalGas, { 13.. => "algebra.ark_bn254_fr_zero" }, 209],
+        [algebra_ark_bn254_g1_affine_deser_comp: InternalGas, { 13.. => "algebra.ark_bn254_g1_affine_deser_comp" }, 23_497_333],
+        [algebra_ark_bn254_g1_affine_deser_uncomp: InternalGas, { 13.. => "algebra.ark_bn254_g1_affine_deser_uncomp" }, 21_528_706],
+        [algebra_ark_bn254_g1_affine_serialize_comp: InternalGas, { 13.. => "algebra.ark_bn254_g1_affine_serialize_comp" }, 44_924],
+        [algebra_ark_bn254_g1_affine_serialize_uncomp: InternalGas, { 13.. => "algebra.ark_bn254_g1_affine_serialize_uncomp" }, 58_820],
+        [algebra_ark_bn254_g1_proj_add: InternalGas, { 13.. => "algebra.ark_bn254_g1_proj_add" }, 106_501],
+        [algebra_ark_bn254_g1_proj_double: InternalGas, { 13.. => "algebra.ark_bn254_g1_proj_double" }, 63_682],
+        [algebra_ark_bn254_g1_proj_eq: InternalGas, { 13.. => "algebra.ark_bn254_g1_proj_eq" }, 53_021],
+        [algebra_ark_bn254_g1_proj_generator: InternalGas, { 13.. => "algebra.ark_bn254_g1_proj_generator" }, 209],
+        [algebra_ark_bn254_g1_proj_infinity: InternalGas, { 13.. => "algebra.ark_bn254_g1_proj_infinity" }, 209],
+        [algebra_ark_bn254_g1_proj_neg: InternalGas, { 13.. => "algebra.ark_bn254_g1_proj_neg" }, 209],
+        [algebra_ark_bn254_g1_proj_scalar_mul: InternalGas, { 13.. => "algebra.ark_bn254_g1_proj_scalar_mul" }, 26_456_386],
+        [algebra_ark_bn254_g1_proj_sub: InternalGas, { 13.. => "algebra.ark_bn254_g1_proj_sub" }, 106_903],
+        [algebra_ark_bn254_g1_proj_to_affine: InternalGas, { 13.. => "algebra.ark_bn254_g1_proj_to_affine" }, 6_340],
+        [algebra_ark_bn254_g2_affine_deser_comp: InternalGas, { 13.. => "algebra.ark_bn254_g2_affine_deser_comp" }, 67_710_223],
+        [algebra_ark_bn254_g2_affine_deser_uncomp: InternalGas, { 13.. => "algebra.ark_bn254_g2_affine_deser_uncomp" }, 60_677_591],
+        [algebra_ark_bn254_g2_affine_serialize_comp: InternalGas, { 13.. => "algebra.ark_bn254_g2_affine_serialize_comp" }, 69_214],
+        [algebra_ark_bn254_g2_affine_serialize_uncomp: InternalGas, { 13.. => "algebra.ark_bn254_g2_affine_serialize_uncomp" }, 98_505],
+        [algebra_ark_bn254_g2_proj_add: InternalGas, { 13.. => "algebra.ark_bn254_g2_proj_add" }, 318_234],
+        [algebra_ark_bn254_g2_proj_double: InternalGas, { 13.. => "algebra.ark_bn254_g2_proj_double" }, 158_874],
+        [algebra_ark_bn254_g2_proj_eq: InternalGas, { 13.. => "algebra.ark_bn254_g2_proj_eq" }, 141_359],
+        [algebra_ark_bn254_g2_proj_generator: InternalGas, { 13.. => "algebra.ark_bn254_g2_proj_generator" }, 209],
+        [algebra_ark_bn254_g2_proj_infinity: InternalGas, { 13.. => "algebra.ark_bn254_g2_proj_infinity" }, 209],
+        [algebra_ark_bn254_g2_proj_neg: InternalGas, { 13.. => "algebra.ark_bn254_g2_proj_neg" }, 209],
+        [algebra_ark_bn254_g2_proj_scalar_mul: InternalGas, { 13.. => "algebra.ark_bn254_g2_proj_scalar_mul" }, 76_395_801],
+        [algebra_ark_bn254_g2_proj_sub: InternalGas, { 13.. => "algebra.ark_bn254_g2_proj_sub" }, 321_727],
+        [algebra_ark_bn254_g2_proj_to_affine: InternalGas, { 13.. => "algebra.ark_bn254_g2_proj_to_affine" }, 1_251_909],
+        [algebra_ark_bn254_multi_pairing_base: InternalGas, { 13.. => "algebra.ark_bn254_multi_pairing_base" }, 127_794_596],
+        [algebra_ark_bn254_multi_pairing_per_pair: InternalGasPerArg, { 13.. => "algebra.ark_bn254_multi_pairing_per_pair" }, 67_624_587],
+        [algebra_ark_bn254_pairing: InternalGas, { 13.. => "algebra.ark_bn254_pairing" }, 209_703_839],
         // BN254 algebra gas parameters end.
 
         // BLS12-381 algebra gas parameters begin.
-        // Generated at time 1680606720.0709136 by `scripts/algebra-gas/update_algebra_gas_params.py` with gas_per_ns=10.23.
+        // Generated at time 1680606720.0709136 by `scripts/algebra-gas/update_algebra_gas_params.py` with gas_per_ns=204.6.
         [algebra_ark_bls12_381_fq12_add: InternalGas, { 8.. => "algebra.ark_bls12_381_fq12_add" }, 36380],
         [algebra_ark_bls12_381_fq12_clone: InternalGas, { 8.. => "algebra.ark_bls12_381_fq12_clone" }, 4220],
         [algebra_ark_bls12_381_fq12_deser: InternalGas, { 8.. => "algebra.ark_bls12_381_fq12_deser" }, 223600],
diff --git a/aptos-move/aptos-gas-schedule/src/ver.rs b/aptos-move/aptos-gas-schedule/src/ver.rs
index 17b5acdc9792f..a4eb546261f77 100644
--- a/aptos-move/aptos-gas-schedule/src/ver.rs
+++ b/aptos-move/aptos-gas-schedule/src/ver.rs
@@ -8,6 +8,8 @@
 ///   - Changing how gas is calculated in any way
 ///
 /// Change log:
+/// - V13
+///   - Added BN254 operations.
 /// - V12
 ///   - Making resource group charge on first read independent of BTreeMap serialization.
 /// - V11
@@ -44,4 +46,4 @@
 ///       global operations.
 /// - V1
 ///   - TBA
-pub const LATEST_GAS_FEATURE_VERSION: u64 = 12;
+pub const LATEST_GAS_FEATURE_VERSION: u64 = 13;
diff --git a/scripts/algebra-gas/update_bn254_algebra_gas_params.py b/scripts/algebra-gas/update_bn254_algebra_gas_params.py
index 3bafa05900f77..69bc488cf6854 100755
--- a/scripts/algebra-gas/update_bn254_algebra_gas_params.py
+++ b/scripts/algebra-gas/update_bn254_algebra_gas_params.py
@@ -17,7 +17,7 @@
 
 # Typically you are making a new version of gas schedule,
 # so this should be larger than `LATEST_GAS_FEATURE_VERSION` in `aptos-move/aptos-gas/src/gas_meter.rs`.
-TARGET_GAS_VERSION = 12
+TARGET_GAS_VERSION = 13
 
 def get_bench_ns_linear(bench_path):
     datapoints = load_bench_datapoints.main(bench_path)

From ef67f4e45bb9470ad5f6ced5401afdafdfbc336a Mon Sep 17 00:00:00 2001
From: "zhoujun.ma" 
Date: Mon, 11 Dec 2023 16:46:10 -0800
Subject: [PATCH 21/21] lint

---
 aptos-move/framework/src/natives/cryptography/algebra/mod.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/aptos-move/framework/src/natives/cryptography/algebra/mod.rs b/aptos-move/framework/src/natives/cryptography/algebra/mod.rs
index 919e983b44f01..c66346647691d 100644
--- a/aptos-move/framework/src/natives/cryptography/algebra/mod.rs
+++ b/aptos-move/framework/src/natives/cryptography/algebra/mod.rs
@@ -25,9 +25,8 @@ use arithmetics::{
     inv::inv_internal,
     scalar_mul::{multi_scalar_mul_internal, scalar_mul_internal},
 };
-use ark_ec::{pairing::Pairing, AffineRepr};
 use ark_ff::{BigInteger, PrimeField};
-use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
+use ark_serialize::CanonicalDeserialize;
 use better_any::{Tid, TidAble};
 use move_binary_format::errors::PartialVMError;
 use move_core_types::{language_storage::TypeTag, vm_status::StatusCode};