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