diff --git a/crates/sui-framework/docs/sui/nitro_attestation.md b/crates/sui-framework/docs/sui/nitro_attestation.md new file mode 100644 index 00000000000000..196f0117d5b711 --- /dev/null +++ b/crates/sui-framework/docs/sui/nitro_attestation.md @@ -0,0 +1,71 @@ +--- +title: Module `0x2::nitro_attestation` +--- + + + +- [Function `verify_nitro_attestation_internal`](#0x2_nitro_attestation_verify_nitro_attestation_internal) +- [Function `verify_nitro_attestation`](#0x2_nitro_attestation_verify_nitro_attestation) + + +
use 0x2::clock;
+
+ + + + + +## Function `verify_nitro_attestation_internal` + +Internal native function + + +
fun verify_nitro_attestation_internal(attestation: &vector<u8>, current_timestamp: u64): vector<vector<u8>>
+
+ + + +
+Implementation + + +
native fun verify_nitro_attestation_internal(
+    attestation: &vector<u8>,
+    current_timestamp: u64
+): vector<vector<u8>>;
+
+ + + +
+ + + +## Function `verify_nitro_attestation` + +@param attestation: attesttaion documents bytes data. +@param clock: the clock object. + +Returns parsed pcrs after verifying the attestation. + + +
public fun verify_nitro_attestation(attestation: &vector<u8>, clock: &clock::Clock): vector<vector<u8>>
+
+ + + +
+Implementation + + +
public fun verify_nitro_attestation(
+    attestation: &vector<u8>,
+    clock: &Clock
+): vector<vector<u8>> {
+    verify_nitro_attestation_internal(attestation, clock::timestamp_ms(clock))
+}
+
+ + + +
diff --git a/crates/sui-framework/packages/sui-framework/sources/crypto/nitro_attestation.move b/crates/sui-framework/packages/sui-framework/sources/crypto/nitro_attestation.move new file mode 100644 index 00000000000000..b92a16dfb5f722 --- /dev/null +++ b/crates/sui-framework/packages/sui-framework/sources/crypto/nitro_attestation.move @@ -0,0 +1,23 @@ +// Copyright (c) Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +module sui::nitro_attestation; + +use sui::clock::{Self, Clock}; + +/// Internal native function +native fun verify_nitro_attestation_internal( + attestation: &vector, + current_timestamp: u64 +): vector>; + +/// @param attestation: attesttaion documents bytes data. +/// @param clock: the clock object. +/// +/// Returns parsed pcrs after verifying the attestation. +public fun verify_nitro_attestation( + attestation: &vector, + clock: &Clock +): vector> { + verify_nitro_attestation_internal(attestation, clock::timestamp_ms(clock)) +} \ No newline at end of file diff --git a/crates/sui-framework/packages/sui-framework/tests/crypto/nitro_attestation_test.move b/crates/sui-framework/packages/sui-framework/tests/crypto/nitro_attestation_test.move new file mode 100644 index 00000000000000..8e7f4339f6f314 --- /dev/null +++ b/crates/sui-framework/packages/sui-framework/tests/crypto/nitro_attestation_test.move @@ -0,0 +1,21 @@ +// Copyright (c) Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +#[test_only] +module sui::nitro_attestation_tests { + use sui::nitro_attestation; + use sui::test_scenario; + + #[test] + fun test_nitro_attestation() { + let mut scenario = test_scenario::begin(@0x0); + let ctx = scenario.ctx(); + let payload = x"8444a1013822a0591121a9696d6f64756c655f69647827692d30663733613462346362373463633966322d656e633031393265343138386665663738316466646967657374665348413338346974696d657374616d701b000001932d1239ca6470637273b0005830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000025830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035830639a8b65f68b0223cbb14a0032487e5656d260434e3d1a10e7ec1407fb86143860717fc8afee90df7a1604111709af460458309ab5a1aba055ee41ee254b9b251a58259b29fa1096859762744e9ac73b5869b25e51223854d9f86adbb37fe69f3e5d1c0558300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000658300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000758300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000858300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000958300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f58300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b636572746966696361746559027e3082027a30820201a00302010202100192e4188fef781d0000000067366a8d300a06082a8648ce3d04030330818e310b30090603550406130255533113301106035504080c0a57617368696e67746f6e3110300e06035504070c0753656174746c65310f300d060355040a0c06416d617a6f6e310c300a060355040b0c034157533139303706035504030c30692d30663733613462346362373463633966322e75732d656173742d312e6177732e6e6974726f2d656e636c61766573301e170d3234313131343231323432365a170d3234313131353030323432395a308193310b30090603550406130255533113301106035504080c0a57617368696e67746f6e3110300e06035504070c0753656174746c65310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753313e303c06035504030c35692d30663733613462346362373463633966322d656e63303139326534313838666566373831642e75732d656173742d312e6177733076301006072a8648ce3d020106052b810400220362000442e0526fc41af71feac64fc6f68a8ac8aae831a9e945ab7d482b842acaf05d6b762d00cbc2115da270187c44597b1c16dcf497c70e543b41612e9041ea143d11d58bd1c847496e5d41ec78a49fe445348cf9a47af9387e0451d9ec145b56ec12a31d301b300c0603551d130101ff04023000300b0603551d0f0404030206c0300a06082a8648ce3d0403030367003064023078001466c0c64293b9bde3d0834edb67ff18417f6075a8f7d137701e10164ce6cf45c508bf383ed0d8d41c51a5977a43023033cb8e4a6ad2686b86c2533accbab5dd5e98cf25d3612b1a48502f327ce00acc921641242d5a3a27d222df1f7dfc3e2c68636162756e646c65845902153082021130820196a003020102021100f93175681b90afe11d46ccb4e4e7f856300a06082a8648ce3d0403033049310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753311b301906035504030c126177732e6e6974726f2d656e636c61766573301e170d3139313032383133323830355a170d3439313032383134323830355a3049310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753311b301906035504030c126177732e6e6974726f2d656e636c617665733076301006072a8648ce3d020106052b8104002203620004fc0254eba608c1f36870e29ada90be46383292736e894bfff672d989444b5051e534a4b1f6dbe3c0bc581a32b7b176070ede12d69a3fea211b66e752cf7dd1dd095f6f1370f4170843d9dc100121e4cf63012809664487c9796284304dc53ff4a3423040300f0603551d130101ff040530030101ff301d0603551d0e041604149025b50dd90547e796c396fa729dcf99a9df4b96300e0603551d0f0101ff040403020186300a06082a8648ce3d0403030369003066023100a37f2f91a1c9bd5ee7b8627c1698d255038e1f0343f95b63a9628c3d39809545a11ebcbf2e3b55d8aeee71b4c3d6adf3023100a2f39b1605b27028a5dd4ba069b5016e65b4fbde8fe0061d6a53197f9cdaf5d943bc61fc2beb03cb6fee8d2302f3dff65902c2308202be30820245a003020102021100ab314210a819b4842e3be045e7daddbe300a06082a8648ce3d0403033049310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c03415753311b301906035504030c126177732e6e6974726f2d656e636c61766573301e170d3234313131333037333235355a170d3234313230333038333235355a3064310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c034157533136303406035504030c2d343834633637303131656563376235332e75732d656173742d312e6177732e6e6974726f2d656e636c617665733076301006072a8648ce3d020106052b8104002203620004cbd3e3fe8793852d952a214ee1c7f17e13eff238c5952ffc6c48f2b8e70beec10194585089829f4818d012a6061cdc9f4d8c5a67aada1233f75b65d3f7704e1c02460cfcc74f0e94193c8d4030f6d1662de0427836c1d32c571c919230fae73aa381d53081d230120603551d130101ff040830060101ff020102301f0603551d230418301680149025b50dd90547e796c396fa729dcf99a9df4b96301d0603551d0e04160414b5f0f617140aa7057c7977f361eee896fd9a58b4300e0603551d0f0101ff040403020186306c0603551d1f046530633061a05fa05d865b687474703a2f2f6177732d6e6974726f2d656e636c617665732d63726c2e73332e616d617a6f6e6177732e636f6d2f63726c2f61623439363063632d376436332d343262642d396539662d3539333338636236376638342e63726c300a06082a8648ce3d04030303670030640230038362cf11e189755d6a2306d728a7f356740eefe623d5e0e9e7c33c1b061ade2224127ac3a2e4bce60b43fc8c53326902306aceccf6f45a8d5c066bd10ce3ffaeeebdee56eedb86deb18ea22172c07196750924dd8f4656c70bd95eb6714cb8ecdd59031a308203163082029ba0030201020211009a0f4f29c1649826edb5b5f9f93b6326300a06082a8648ce3d0403033064310b3009060355040613025553310f300d060355040a0c06416d617a6f6e310c300a060355040b0c034157533136303406035504030c2d343834633637303131656563376235332e75732d656173742d312e6177732e6e6974726f2d656e636c61766573301e170d3234313131343034323230325a170d3234313132303033323230325a308189313c303a06035504030c33373532313933346262636164353432622e7a6f6e616c2e75732d656173742d312e6177732e6e6974726f2d656e636c61766573310c300a060355040b0c03415753310f300d060355040a0c06416d617a6f6e310b3009060355040613025553310b300906035504080c0257413110300e06035504070c0753656174746c653076301006072a8648ce3d020106052b810400220362000496f4565c489625767e8e2d3006ba06bd48ba3e384027a205b93d1ad4958128887c38ddbb2f4922888708ef0985e1e5d3bd73b33f86785ac66a204eed3a6b663686434f64e19fb39cd7b33068edb2108b79774a961e7080cb1b4eaa60a5e63e22a381ea3081e730120603551d130101ff040830060101ff020101301f0603551d23041830168014b5f0f617140aa7057c7977f361eee896fd9a58b4301d0603551d0e0416041484b6dc9994365b56081f5d1bc8ee21f58e45d7df300e0603551d0f0101ff0404030201863081800603551d1f047930773075a073a071866f687474703a2f2f63726c2d75732d656173742d312d6177732d6e6974726f2d656e636c617665732e73332e75732d656173742d312e616d617a6f6e6177732e636f6d2f63726c2f34396230376261342d303533622d346435622d616434612d3364626533653065396637652e63726c300a06082a8648ce3d0403030369003066023100d00c2999e66fbcce624d91aedf41f5532b04c300c86a61d78ed968716a7f7ff565e2c361f4f46fe5c5486a9d2bfe0d60023100bc46872a45820fb552b926d420d4f6a1be831bb26821d374e95bff5ed042b3313465b5b4cde79f16f6a57bd5b541353c5902c3308202bf30820245a003020102021500eaa3f0b662c2a61c96f94194fa33d5baf26eeb84300a06082a8648ce3d040303308189313c303a06035504030c33373532313933346262636164353432622e7a6f6e616c2e75732d656173742d312e6177732e6e6974726f2d656e636c61766573310c300a060355040b0c03415753310f300d060355040a0c06416d617a6f6e310b3009060355040613025553310b300906035504080c0257413110300e06035504070c0753656174746c65301e170d3234313131343130313032345a170d3234313131353130313032345a30818e310b30090603550406130255533113301106035504080c0a57617368696e67746f6e3110300e06035504070c0753656174746c65310f300d060355040a0c06416d617a6f6e310c300a060355040b0c034157533139303706035504030c30692d30663733613462346362373463633966322e75732d656173742d312e6177732e6e6974726f2d656e636c617665733076301006072a8648ce3d020106052b81040022036200040fe46adf864a558a00a9ca4b64ece5ba124ed1d29656a1f16ca71d0dc8fca56b0fb15aafd309f6258374e8c7b4a5b0521c76d1812a7873474dae9322aef1cd782db19fc2ece4d36fa08acbe65e4bec2a3cfe70960d179778ea7e7711f827b36ea366306430120603551d130101ff040830060101ff020100300e0603551d0f0101ff040403020204301d0603551d0e041604143e40d423bf86e9565c378487843389bd2f471a56301f0603551d2304183016801484b6dc9994365b56081f5d1bc8ee21f58e45d7df300a06082a8648ce3d0403030368003065023100c2767f29cc6e40e087617cf680d81e3b77962c29d8ace426b3c4a62a560354da73de6f80986d44da2593a3c268fea94302306056e2f3c88c30170c4940f578acc279a01fe689123e81def4f8c313e1f0cbc44a562a171d12810e847e441aee233f676a7075626c69635f6b6579f669757365725f6461746158205a264748a62368075d34b9494634a3e096e0e48f6647f965b81d2a653de684f2656e6f6e6365f65860284d57f029e1b3beb76455a607b9a86360d6451370f718a0d7bdcad729eea248c25461166ab684ad31fb52713918ee3e401d1b56251d6f9d85bf870e850e0b47559d17091778dbafc3d1989a94bd54c0991053675dcc3686402b189172aae196"; + let mut clock = sui::clock::create_for_testing(ctx); + clock.set_for_testing(1731627987382); + let res = nitro_attestation::verify_nitro_attestation(&payload, &clock); + assert!(vector::length(&res) == 16); + scenario.end(); + clock.destroy_for_testing(); + } +} diff --git a/crates/sui-framework/packages_compiled/sui-framework b/crates/sui-framework/packages_compiled/sui-framework index e008cceb39c5aa..06426565c58360 100644 Binary files a/crates/sui-framework/packages_compiled/sui-framework and b/crates/sui-framework/packages_compiled/sui-framework differ diff --git a/crates/sui-framework/published_api.txt b/crates/sui-framework/published_api.txt index 775880de57e609..8dcaa5e2942f5d 100644 --- a/crates/sui-framework/published_api.txt +++ b/crates/sui-framework/published_api.txt @@ -2788,6 +2788,12 @@ sqrt_u128 divide_and_round_up public fun 0x2::math +verify_nitro_attestation_internal + fun + 0x2::nitro_attestation +verify_nitro_attestation + public fun + 0x2::nitro_attestation ObjectBag public struct 0x2::object_bag diff --git a/crates/sui-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap b/crates/sui-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap index 4b150ff1097249..752f4896f2bdb0 100644 --- a/crates/sui-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap +++ b/crates/sui-swarm-config/tests/snapshots/snapshot_tests__populated_genesis_snapshot_matches-2.snap @@ -1,6 +1,7 @@ --- source: crates/sui-swarm-config/tests/snapshot_tests.rs expression: genesis.sui_system_object().into_genesis_version_for_tooling() +snapshot_kind: text --- epoch: 0 protocol_version: 72 @@ -240,13 +241,13 @@ validators: next_epoch_worker_address: ~ extra_fields: id: - id: "0xe1736cf478d38b4e97ac9cff325aedd9d71c156d43cf1e49a821a8b20dfe877a" + id: "0x6b9519d549ce6946d20ace22c5325a01e0c2b604b76b52bd27d18b7bd1257910" size: 0 voting_power: 10000 - operation_cap_id: "0x92ca0c15c751ed16f4ba61cf7a2561bcdacea7c14ff8734bb187c305bee96176" + operation_cap_id: "0x81a3e2b4c5cb950d7a8fb82260cf31ea5f82742ffc78bbbd6f76b6e76f8cab78" gas_price: 1000 staking_pool: - id: "0x65826f03944fd73127bd792daed69eddbc1ddc147f8c99da50324c64a90df0e0" + id: "0x4d46cc19f159de39a8421b7e1855b1a1a4df12b10aa714908b1e52439f3bd8a1" activation_epoch: 0 deactivation_epoch: ~ sui_balance: 20000000000000000 @@ -254,14 +255,14 @@ validators: value: 0 pool_token_balance: 20000000000000000 exchange_rates: - id: "0xae8b647a4c501c2b62396ff783139eb9d60594dcdb68f8b53aa6e612fde7ad55" + id: "0x3303a9b548b4ca3d0c67025cea60cc496e078e310f6542150b352b300440b181" size: 1 pending_stake: 0 pending_total_sui_withdraw: 0 pending_pool_token_withdraw: 0 extra_fields: id: - id: "0x9074457c10ce082304550f2edb9e55fc0ec12e5b0ade37806debfb378d9a1b9d" + id: "0x4ca2230585b23b5b03587ecfe8d29cfb9444e342d312b4ee42c4af429f611f70" size: 0 commission_rate: 200 next_epoch_stake: 20000000000000000 @@ -269,27 +270,27 @@ validators: next_epoch_commission_rate: 200 extra_fields: id: - id: "0x3307d52632bb86f142fa40561bb2b46365a5612225a0b0891a63809fcdcb691f" + id: "0x8439885d5e80c15835f67b1dea087c1e0ae4672b39ad7711491847aaf2cd0ef3" size: 0 pending_active_validators: contents: - id: "0x60cea2865bd42d6a782798762fa70c2d717be27f8873c1a512882a190629e254" + id: "0x8a4748ce2eaf5fc5f4cd3b5dd8a15782b4abfd1885818f862820e2d883d791cb" size: 0 pending_removals: [] staking_pool_mappings: - id: "0xbcdff2f0bca8d3c90783a19a68012d10c6c52c187817395fe91b220957ae65dd" + id: "0x6015e1edaec640adcfb74e2a60571ec1558e75a9c36891583197dff3d37fc4b8" size: 1 inactive_validators: - id: "0xb126b6b0efdfd66f0a14c159a5828b7844065267efb83637e59922dd28a2dec9" + id: "0x2d3479e08fc3802090272b22e8d9bee0a87edb67f5893e4e5e5955ca56c8de12" size: 0 validator_candidates: - id: "0x35e1d26ec23453bfb7007fb2882ced97a1d19a102d2320bfbd136a6e35220688" + id: "0x88107f2c31161269c29e65ff3cbf555b6647a55e3db1aaae39cf30ea7fb8433b" size: 0 at_risk_validators: contents: [] extra_fields: id: - id: "0x30f3634e8f7220afff05b96d87ab9020bc62538f5b0910b9c5d5e12646d944ea" + id: "0x8a316b068fe4452177d9333acd479e216e26518aa76c04685959c71490fdc782" size: 0 storage_fund: total_object_storage_rebates: @@ -306,7 +307,7 @@ parameters: validator_low_stake_grace_period: 7 extra_fields: id: - id: "0x8f0219b14d05d238a48c0f75c3cc9c675acb9b5f6c50e0b7a9b9bbecaaaea232" + id: "0x17688697efa33d4e503e9b2e35623dee777add49e4d1768c8e3f076e2184920c" size: 0 reference_gas_price: 1000 validator_report_records: @@ -320,7 +321,7 @@ stake_subsidy: stake_subsidy_decrease_rate: 1000 extra_fields: id: - id: "0x3e45c6ab50494f16b32675da9b00233b08f0ca281c2f763ed5838518045a13b6" + id: "0x4a59e2082c239d5aa2bf50b2a66e4374c671579528e42d3078958b9037a74b8d" size: 0 safe_mode: false safe_mode_storage_rewards: @@ -332,6 +333,5 @@ safe_mode_non_refundable_storage_fee: 0 epoch_start_timestamp_ms: 10 extra_fields: id: - id: "0xf741efb1558fc976c1b7ba102a1c0ad5b814a15913c08fe18c3abf20f74547a2" + id: "0x27767762fce0685db078584b6d5e20bd121eb317eba327acc96d404bd41bd769" size: 0 - diff --git a/sui-execution/latest/sui-move-natives/src/crypto/mod.rs b/sui-execution/latest/sui-move-natives/src/crypto/mod.rs index c77afbd81f24ea..6303f68c5a05bf 100644 --- a/sui-execution/latest/sui-move-natives/src/crypto/mod.rs +++ b/sui-execution/latest/sui-move-natives/src/crypto/mod.rs @@ -10,6 +10,7 @@ pub mod groth16; pub mod group_ops; pub mod hash; pub mod hmac; +pub mod nitro_attestation; pub mod poseidon; pub mod vdf; pub mod zklogin; diff --git a/sui-execution/latest/sui-move-natives/src/crypto/nitro_attestation.rs b/sui-execution/latest/sui-move-natives/src/crypto/nitro_attestation.rs new file mode 100644 index 00000000000000..84edefe1e030a0 --- /dev/null +++ b/sui-execution/latest/sui-move-natives/src/crypto/nitro_attestation.rs @@ -0,0 +1,112 @@ +// Copyright (c) Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +use move_binary_format::errors::PartialVMResult; +use move_core_types::gas_algebra::InternalGas; +use move_vm_runtime::native_functions::NativeContext; +use move_vm_types::{ + loaded_data::runtime_types::Type, + natives::function::NativeResult, + pop_arg, + values::{Value, VectorRef}, +}; +use smallvec::smallvec; +use std::collections::VecDeque; +use sui_types::nitro_attestation::{parse_nitro_attestation, verify_nitro_attestation}; + +use crate::{object_runtime::ObjectRuntime, NativesCostTable}; +use move_vm_runtime::native_charge_gas_early_exit; + +pub const NOT_SUPPORTED_ERROR: u64 = 0; +pub const PARSE_ERROR: u64 = 1; +pub const VERIFY_ERROR: u64 = 2; +// Gas related structs and functions. + +#[derive(Clone)] +pub struct NitroAttestationCostParams { + pub parse_base_cost: Option, + pub parse_cost_per_byte: Option, + pub verify_base_cost: Option, + pub verify_cost_per_cert: Option, +} + +macro_rules! native_charge_gas_early_exit_option { + ($native_context:ident, $cost:expr) => {{ + use move_binary_format::errors::PartialVMError; + use move_core_types::vm_status::StatusCode; + native_charge_gas_early_exit!( + $native_context, + $cost.ok_or_else(|| { + PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR) + .with_message("Gas cost for group ops is missing".to_string()) + })? + ); + }}; +} + +fn is_supported(context: &NativeContext) -> bool { + context + .extensions() + .get::() + .protocol_config + .enable_nitro_attestation() +} + +pub fn verify_nitro_attestation_internal( + context: &mut NativeContext, + ty_args: Vec, + mut args: VecDeque, +) -> PartialVMResult { + debug_assert!(ty_args.is_empty()); + debug_assert!(args.len() == 2); + + let cost = context.gas_used(); + if !is_supported(context) { + return Ok(NativeResult::err(cost, NOT_SUPPORTED_ERROR)); + } + + let current_timestamp = pop_arg!(args, u64); + let attestation_ref = pop_arg!(args, VectorRef); + let attestation_bytes = attestation_ref.as_bytes_ref(); + + let cost_params = &context + .extensions() + .get::() + .nitro_attestation_cost_params + .clone(); + + native_charge_gas_early_exit_option!( + context, + cost_params.parse_base_cost.and_then(|base_cost| cost_params + .parse_cost_per_byte + .map(|per_byte| base_cost + per_byte * (attestation_bytes.len() as u64).into())) + ); + match parse_nitro_attestation(&attestation_bytes) { + Ok((signature, signed_message, payload)) => { + let cert_chain_length = payload.get_cert_chain_length(); + native_charge_gas_early_exit_option!( + context, + cost_params + .verify_base_cost + .and_then(|base_cost| cost_params + .verify_cost_per_cert + .map(|per_byte| base_cost + per_byte * (cert_chain_length as u64).into())) + ); + match verify_nitro_attestation(&signature, &signed_message, &payload, current_timestamp) + { + Ok(()) => Ok(NativeResult::ok( + context.gas_used(), + smallvec![Value::vector_for_testing_only( + payload + .get_pcrs() + .iter() + .map(|pcr| Value::vector_u8(pcr.to_vec())) + .collect::>() + )], + )), + Err(_) => Ok(NativeResult::err(context.gas_used(), VERIFY_ERROR)), + } + } + Err(_) => Ok(NativeResult::err(context.gas_used(), PARSE_ERROR)), + } +} diff --git a/sui-execution/latest/sui-move-natives/src/lib.rs b/sui-execution/latest/sui-move-natives/src/lib.rs index 193d2f1d51935b..263271b4723f15 100644 --- a/sui-execution/latest/sui-move-natives/src/lib.rs +++ b/sui-execution/latest/sui-move-natives/src/lib.rs @@ -41,6 +41,7 @@ use crate::crypto::poseidon::PoseidonBN254CostParams; use crate::crypto::zklogin; use crate::crypto::zklogin::{CheckZkloginIdCostParams, CheckZkloginIssuerCostParams}; use better_any::{Tid, TidAble}; +use crypto::nitro_attestation::{self, NitroAttestationCostParams}; use crypto::vdf::{self, VDFCostParams}; use move_binary_format::errors::{PartialVMError, PartialVMResult}; use move_core_types::{ @@ -167,6 +168,9 @@ pub struct NativesCostTable { // Receive object pub transfer_receive_object_internal_cost_params: TransferReceiveObjectInternalCostParams, + + // nitro attestation + pub nitro_attestation_cost_params: NitroAttestationCostParams, } impl NativesCostTable { @@ -651,6 +655,20 @@ impl NativesCostTable { .vdf_hash_to_input_cost_as_option() .map(Into::into), }, + nitro_attestation_cost_params: NitroAttestationCostParams { + parse_base_cost: protocol_config + .nitro_attestation_parse_base_cost_as_option() + .map(Into::into), + parse_cost_per_byte: protocol_config + .nitro_attestation_parse_cost_per_byte_as_option() + .map(Into::into), + verify_base_cost: protocol_config + .nitro_attestation_verify_base_cost_as_option() + .map(Into::into), + verify_cost_per_cert: protocol_config + .nitro_attestation_verify_cost_per_cert_as_option() + .map(Into::into), + }, } } } @@ -1063,6 +1081,11 @@ pub fn all_natives(silent: bool, protocol_config: &ProtocolConfig) -> NativeFunc "secp256k1_keypair_from_seed", make_native!(ecdsa_k1::secp256k1_keypair_from_seed), ), + ( + "nitro_attestation", + "verify_nitro_attestation_internal", + make_native!(nitro_attestation::verify_nitro_attestation_internal), + ), ]; let sui_framework_natives_iter = sui_framework_natives