@aztec/noir-protocol-circuits-types 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +1 -0
  2. package/dest/index.d.ts +69 -0
  3. package/dest/index.d.ts.map +1 -0
  4. package/dest/index.js +268 -0
  5. package/dest/scripts/generate_ts_from_abi.d.ts +2 -0
  6. package/dest/scripts/generate_ts_from_abi.d.ts.map +1 -0
  7. package/dest/scripts/generate_ts_from_abi.js +180 -0
  8. package/dest/target/private_kernel_init.json +1 -0
  9. package/dest/target/private_kernel_init_simulated.json +1 -0
  10. package/dest/target/private_kernel_inner.json +1 -0
  11. package/dest/target/private_kernel_inner_simulated.json +1 -0
  12. package/dest/target/private_kernel_tail.json +1 -0
  13. package/dest/target/private_kernel_tail_simulated.json +1 -0
  14. package/dest/target/public_kernel_app_logic.json +1 -0
  15. package/dest/target/public_kernel_app_logic_simulated.json +1 -0
  16. package/dest/target/public_kernel_setup.json +1 -0
  17. package/dest/target/public_kernel_setup_simulated.json +1 -0
  18. package/dest/target/rollup_base.json +1 -0
  19. package/dest/target/rollup_base_simulated.json +1 -0
  20. package/dest/target/rollup_merge.json +1 -0
  21. package/dest/target/rollup_root.json +1 -0
  22. package/dest/type_conversion.d.ts +574 -0
  23. package/dest/type_conversion.d.ts.map +1 -0
  24. package/dest/type_conversion.js +1115 -0
  25. package/dest/types/private_kernel_init_types.d.ts +232 -0
  26. package/dest/types/private_kernel_init_types.d.ts.map +1 -0
  27. package/dest/types/private_kernel_init_types.js +3 -0
  28. package/dest/types/private_kernel_inner_types.d.ts +233 -0
  29. package/dest/types/private_kernel_inner_types.d.ts.map +1 -0
  30. package/dest/types/private_kernel_inner_types.js +3 -0
  31. package/dest/types/private_kernel_tail_types.d.ts +182 -0
  32. package/dest/types/private_kernel_tail_types.d.ts.map +1 -0
  33. package/dest/types/private_kernel_tail_types.js +3 -0
  34. package/dest/types/public_kernel_app_logic_types.d.ts +212 -0
  35. package/dest/types/public_kernel_app_logic_types.d.ts.map +1 -0
  36. package/dest/types/public_kernel_app_logic_types.js +3 -0
  37. package/dest/types/public_kernel_setup_types.d.ts +212 -0
  38. package/dest/types/public_kernel_setup_types.d.ts.map +1 -0
  39. package/dest/types/public_kernel_setup_types.js +3 -0
  40. package/dest/types/rollup_base_types.d.ts +220 -0
  41. package/dest/types/rollup_base_types.d.ts.map +1 -0
  42. package/dest/types/rollup_base_types.js +3 -0
  43. package/dest/types/rollup_merge_types.d.ts +71 -0
  44. package/dest/types/rollup_merge_types.d.ts.map +1 -0
  45. package/dest/types/rollup_merge_types.js +3 -0
  46. package/dest/types/rollup_root_types.d.ts +92 -0
  47. package/dest/types/rollup_root_types.d.ts.map +1 -0
  48. package/dest/types/rollup_root_types.js +3 -0
  49. package/package.json +60 -0
  50. package/src/fixtures/nested-call-private-kernel-init.hex +1 -0
  51. package/src/fixtures/nested-call-private-kernel-inner.hex +1 -0
  52. package/src/fixtures/nested-call-private-kernel-ordering.hex +1 -0
  53. package/src/index.ts +438 -0
  54. package/src/scripts/generate_ts_from_abi.ts +233 -0
  55. package/src/target/private_kernel_init.json +1 -0
  56. package/src/target/private_kernel_init_simulated.json +1 -0
  57. package/src/target/private_kernel_inner.json +1 -0
  58. package/src/target/private_kernel_inner_simulated.json +1 -0
  59. package/src/target/private_kernel_tail.json +1 -0
  60. package/src/target/private_kernel_tail_simulated.json +1 -0
  61. package/src/target/public_kernel_app_logic.json +1 -0
  62. package/src/target/public_kernel_app_logic_simulated.json +1 -0
  63. package/src/target/public_kernel_setup.json +1 -0
  64. package/src/target/public_kernel_setup_simulated.json +1 -0
  65. package/src/target/rollup_base.json +1 -0
  66. package/src/target/rollup_base_simulated.json +1 -0
  67. package/src/target/rollup_merge.json +1 -0
  68. package/src/target/rollup_root.json +1 -0
  69. package/src/type_conversion.ts +1673 -0
  70. package/src/types/private_kernel_init_types.ts +272 -0
  71. package/src/types/private_kernel_inner_types.ts +273 -0
  72. package/src/types/private_kernel_tail_types.ts +214 -0
  73. package/src/types/public_kernel_app_logic_types.ts +250 -0
  74. package/src/types/public_kernel_setup_types.ts +250 -0
  75. package/src/types/rollup_base_types.ts +259 -0
  76. package/src/types/rollup_merge_types.ts +85 -0
  77. package/src/types/rollup_root_types.ts +109 -0
@@ -0,0 +1 @@
1
+ { "noir_version": "0.23.0+5f5843e35052b9d3599b8ab4f7633db0a225e82f", "hash": 2150028161626137511, "abi": { "parameters": [{ "name": "inputs", "type": { "kind": "struct", "path": "rollup_lib::merge::merge_rollup_inputs::MergeRollupInputs", "fields": [{ "name": "previous_rollup_data", "type": { "kind": "array", "length": 2, "type": { "kind": "struct", "path": "rollup_lib::abis::previous_rollup_data::PreviousRollupData", "fields": [{ "name": "base_or_merge_rollup_public_inputs", "type": { "kind": "struct", "path": "rollup_lib::abis::base_or_merge_rollup_public_inputs::BaseOrMergeRollupPublicInputs", "fields": [{ "name": "rollup_type", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }, { "name": "height_in_block_tree", "type": { "kind": "field" } }, { "name": "aggregation_object", "type": { "kind": "struct", "path": "rollup_lib::types::mocked::AggregationObject", "fields": [] } }, { "name": "constants", "type": { "kind": "struct", "path": "rollup_lib::abis::constant_rollup_data::ConstantRollupData", "fields": [{ "name": "last_archive", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "private_kernel_vk_tree_root", "type": { "kind": "field" } }, { "name": "public_kernel_vk_tree_root", "type": { "kind": "field" } }, { "name": "base_rollup_vk_hash", "type": { "kind": "field" } }, { "name": "merge_rollup_vk_hash", "type": { "kind": "field" } }, { "name": "global_variables", "type": { "kind": "struct", "path": "rollup_lib::types::abis::global_variables::GlobalVariables", "fields": [{ "name": "chain_id", "type": { "kind": "field" } }, { "name": "version", "type": { "kind": "field" } }, { "name": "block_number", "type": { "kind": "field" } }, { "name": "timestamp", "type": { "kind": "field" } }, { "name": "coinbase", "type": { "kind": "struct", "path": "rollup_lib::types::address::EthAddress", "fields": [{ "name": "inner", "type": { "kind": "field" } }] } }, { "name": "fee_recipient", "type": { "kind": "struct", "path": "rollup_lib::types::address::AztecAddress", "fields": [{ "name": "inner", "type": { "kind": "field" } }] } }] } }] } }, { "name": "start", "type": { "kind": "struct", "path": "rollup_lib::types::partial_state_reference::PartialStateReference", "fields": [{ "name": "note_hash_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "nullifier_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "contract_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "public_data_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }] } }, { "name": "end", "type": { "kind": "struct", "path": "rollup_lib::types::partial_state_reference::PartialStateReference", "fields": [{ "name": "note_hash_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "nullifier_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "contract_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "public_data_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }] } }, { "name": "calldata_hash", "type": { "kind": "array", "length": 2, "type": { "kind": "field" } } }] } }, { "name": "proof", "type": { "kind": "struct", "path": "rollup_lib::types::mocked::Proof", "fields": [] } }, { "name": "vk", "type": { "kind": "struct", "path": "rollup_lib::types::mocked::VerificationKey", "fields": [] } }, { "name": "vk_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }, { "name": "vk_sibling_path", "type": { "kind": "struct", "path": "rollup_lib::types::abis::membership_witness::VKMembershipWitness", "fields": [{ "name": "leaf_index", "type": { "kind": "field" } }, { "name": "sibling_path", "type": { "kind": "array", "length": 8, "type": { "kind": "field" } } }] } }] } } }] }, "visibility": "private" }], "param_witnesses": { "inputs": [{ "start": 0, "end": 84 }] }, "return_type": { "abi_type": { "kind": "struct", "path": "rollup_lib::abis::base_or_merge_rollup_public_inputs::BaseOrMergeRollupPublicInputs", "fields": [{ "name": "rollup_type", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }, { "name": "height_in_block_tree", "type": { "kind": "field" } }, { "name": "aggregation_object", "type": { "kind": "struct", "path": "rollup_lib::types::mocked::AggregationObject", "fields": [] } }, { "name": "constants", "type": { "kind": "struct", "path": "rollup_lib::abis::constant_rollup_data::ConstantRollupData", "fields": [{ "name": "last_archive", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "private_kernel_vk_tree_root", "type": { "kind": "field" } }, { "name": "public_kernel_vk_tree_root", "type": { "kind": "field" } }, { "name": "base_rollup_vk_hash", "type": { "kind": "field" } }, { "name": "merge_rollup_vk_hash", "type": { "kind": "field" } }, { "name": "global_variables", "type": { "kind": "struct", "path": "rollup_lib::types::abis::global_variables::GlobalVariables", "fields": [{ "name": "chain_id", "type": { "kind": "field" } }, { "name": "version", "type": { "kind": "field" } }, { "name": "block_number", "type": { "kind": "field" } }, { "name": "timestamp", "type": { "kind": "field" } }, { "name": "coinbase", "type": { "kind": "struct", "path": "rollup_lib::types::address::EthAddress", "fields": [{ "name": "inner", "type": { "kind": "field" } }] } }, { "name": "fee_recipient", "type": { "kind": "struct", "path": "rollup_lib::types::address::AztecAddress", "fields": [{ "name": "inner", "type": { "kind": "field" } }] } }] } }] } }, { "name": "start", "type": { "kind": "struct", "path": "rollup_lib::types::partial_state_reference::PartialStateReference", "fields": [{ "name": "note_hash_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "nullifier_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "contract_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "public_data_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }] } }, { "name": "end", "type": { "kind": "struct", "path": "rollup_lib::types::partial_state_reference::PartialStateReference", "fields": [{ "name": "note_hash_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "nullifier_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "contract_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "public_data_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }] } }, { "name": "calldata_hash", "type": { "kind": "array", "length": 2, "type": { "kind": "field" } } }] }, "visibility": "public" }, "return_witnesses": [232, 233, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 64, 65, 66, 67, 68, 69, 70, 71, 234, 235] }, "bytecode": "H4sIAAAAAAAA/+2dB5AUVRrH3+7CiglRFEkLY0YQnTd5MKIo6N0Z0fNExZ6ZHna9ZWfdnSWZCAbMOSfMmHPOOeecFQmeWpZlcZx3daX39Wy/tecxB/T2/6PmVdFV/+r9dl9/+75fv37859HdO6FGiAaSszm72s4vRcgT12nxBlq8oRb31eJNtHhTLR6gxYO0uEGLQ1o8XItHanFai3fU4p21eFctHq3Fe2jxnlo8Vov3cWPvpjjv5u7DwTbpzRUNJ2IxOxmxZVRa4Ug6k4qHY/FMIiVTMp6K5yKpaNROxVLJdCadDKdlLGrLfDwdzbvJhuP6FeasuQZY8whDaq4F1rydITXXAWseaUjNvYA1RwypeW1gzVFDal4HWHPMkJrXBdYcN6Tm9YA1JwypeX1gzUlDau4BrHl7Q2ruCax5B0NqrgfWHDak5rWANUtDau4HrDllSM2bAmtOG1Jzf2DNowypeQCw5h0NqXkgsOadDKl5ELDmnQ2peTCw5l0MqbkBWPOuwJrVOugQ0kzRuZ5cK5bfasA8hgie8yaC9VPq3/CyGO/uDybVu1/Xi+XHjJeZ+p7z2eN37WdqX+M5/nfPMZXa1PyfPOtW6EefCt+rEdq2m7sPB9ukKtaB9KSn+IM9v0NtdeDf7R1MPi+usHZxyfECd6EeLMyYnJA1H7KCXKmkncknY1ErHMtnKE8ib0etSFrmU1FKH43JjGWHc7FMMhFLpPLJcJ2oMGAFfjI6RGAnVLX9ldTT/bq+Qv/VVlfh616edr8Ba9V/r96XPhX6yTZpeJOjch7igkfnPVTgLhKuug/Fn6OKfUVMjIcy5P1R8Ey4Qf/B0vuJHEt/w9UskfyUAXD6N1r8YQiGitXrNIcKnjEhgvVzhU7zMHc/QaxxmsuBU8U6kLxOc4Lgd5rewRTUaR4mcJPABMEzyNFOE1nz4cI8p3m4wE6wajtCrHGaK+0Mx8k8giHvkaK6naZT95H4c8TiNCe4fUXn/UnwTLhop4kcSxNxNUskP2UAnP55neY4sXqd5jjBMyZEsH6u0Gke5e4tscZpLgdOFXuUKHealuB3mt7BFNRpHiVwk4AleAY52mkia84I85xmRmAnWLVlxRqnudLOcJzMLEPenKhup+nUncOfIxanabl9Ref9WfBMuGiniRxLNq5mieSnDIDTP6/T3FusXqe5t+AZEyJYP1foNPPufpJY4zSXA6eKdSB5neYkwe80vYMpqNPMC9wkMEnwDHK000TW3CjMc5qNAjvBqq1JrHGaK+0Mx8lsYsh7tKhup+nUfTT+HLE4zUluX9F5fxE8Ey7aaSLH0t9xNUskP2UAnP6NFpXdURCmet+Rt6r1cvM0kyaTWkgFUivpGFIbqd0tQtXptFWTdq17nDdu0eKCFrdq8TFa3KbF7W6MHKcrYhp0nDYDcy0Vq+c6724/7byzheVkUC7nXLQA+f2z6vmVUstC8FwRZexbgfyWVTO/2B8fZo4Jlivs/WDUBuT3r2rlFyn/MNiO66dcCuT362riFw62SeA8I5cB+f3bEH7A60QCx4xE8tN9ob64EYnlEhkrnMwnLSuVD8cykRztEvlkMh+PWOlo1oolU7mMbWWi2XQkm4vk6NSH41E7mk7YdixX9pxOJpVLxxKWTUsRUkbi4XgyGY/HaIikspFcNh3P2dm4lUpn7WQ2l8vGZMKKJuOxcDibSEuZiXF4zCKpgzSFNJU0jTSdNIN0rNPA4zGdtl4P2KHFU7R4qhZP0+LpWjxDi48VK/eY1Xp+An9Gr6luj6T6WQTkUn61A9ivmirnp3z1FEiuUjflVCC/2urm1+WrpwXN5fGr04H86qqXX5mvnhEkl+ZXjwXy67Ga+IWDbRI4T0vvnBWUX09D+AHnGVkH5FdvCD/gdSKBY0Yi+XGv3SIf/lB+9TjS8aQTSCeKzrsbZpFmk+a4RSif67T1+t7jtfgELT5Ri2dq8Swtnq3FcwT/2q2XadBr8Thgrt4G+ELHCx8PyuWcixOA/Daoen6l1PLE4Lm6POZMIL8+1czP44VnBctV5jFnA/ltWK38NC88R+Dm0t5AX7ORIb4GOM/IPkB+fQ3hB7xOJHDMyL6MvhC9dlv25HvAtUEOj3kS6WTSKaRTSXNJp5FOJ53hNPB4TKet1wOerMWnaPGpWjxXi0/T4tO1+AzBv3bLdX6CzhEDDVm7PQmQS/nVk4H9GmTI2u0pkFylbspTgfwGG7J2OzdoLo9fPQ3Ir8GQtdvTg+TS/OoZQH5DDPFIwHlaDgJ6zKGG8APOM7IByC9kCD/gdSKBY0aGGD06eu3WwuXq8tVnks4inU06h3Qu6TzS+aQL3CKUz3Xaen3vWVp8thafo8XnavF5Wny+Fl8g+NduvUyDXotnAnMNM2Tt9ixQLudcnA3kt60ha7fnBM/V5THPBfIbbsja7XnBcpV5zPOB/EYYsnZ7gcDNpcOAvmY7Q3wNcJ6Rw4H8RhrCD3idSOCYkSMZfSF67XacwK0NcnjMC0kXkS4mXUK6lHQZ6XLSFU4Dj8d02no94EVafLEWX6LFl2rxZVp8uRZfIfjXbrnOT+C/M2jI2u2FgFzKr14E7FfckLXbiyG5St2UlwD5JQxZu700aC6PX70MyC9pyNrt5UFyaX71CiC/lCEeCThPyzjQY6YN4QecZ2QSyG+UIfyA14kEjhk5itGjo9dukS8oUn71StJVpKtJ15Dmka4lXUe63i1C+Vynrdf3XqXFV2vxNVo8T4uv1eLrtPh6wb9262Ua9Fq8Ephrd0PWbq8C5XLOxdVAfnsYsnZ7TfBcXR5zHpDfGEPWbq8NlqvMY14H5LenIWu31wvcXLo70NfsZYivAc4zcgyQ31hD+AGvEwkcM3Isoy9Er92WvZ014Nogh8e8gXQj6SbSzaT5pFtIt5Jucxp4PKbT1usBb9Tim7T4Zi2er8W3aPGtWnyb4F+75To/QeeIfQ1Zu70BkEv51RuB/drPkLXbmyC5St2UNwP57W/I2u38oLk8fvUWIL8DDFm7vTVILs2v3gbkd6AhHgk4T8v9gB7zIEP4AecZeQCQ33hD+AGvEwkcMxLJr8blpvKpd2mpd2ypd2+pd3Kpd3Wpd3ipd3upd36p972q98Cq98O2unv1Pln1nln1/ln1Xlr1PJh6Tkw9PzbX3avnzdRzaOr5NPXc2hx3P9vdz3L3M929eieCeleCeoeCereCuqdB3eug7oFQ90aoeybUvRTqHgt174W671bdj6vu01X376r7etX9vuo+YHV/sPLlyq8rHz/f3Svfrz4PqM8J6vODWjtWa8pqrXmeu1dr02rNWq1lqzXukOjcbifdQbqTdBfpbtI9pHtJ95HuJz1AepD0EOlh0iOkR0mPkR4nPSE6/8jCU6SnSc+QniU9R3qe9ALpRdJLpJdJr5BeJb0myrfA17X29zJuF4Gun7JsdwjcvPi6wF7Xzuc8b04Yz3A5hTtx/ZavA3m+wcDzDS6eHqJ3AXm+AeT5JgPPN/l4dhG9G8jzTSDPtxh4vsXJ0yV6D5DnW0CebzPwfJuXZ4novUCebwN5vsPA8x1unsTgPmCud4A832Xg+S4HT80v3R+s32XZHgDyfI+B53uCaXx6KDyI67d8D8jzfQae7wu2672L6ENAnu8DeX7AwPMDPp5dRB8G8vwAyPNDBp4fcvJ0iT4C5PkhkOdHDDw/4uVZIvookOdHQJ4fM/D8mJsnMXgMmOtjIM9PGHh+wsFT80uPB+t3WbYngDw/ZeD5qWAanx4KT+L6LT8F8vyMgedngu167yL6FJDnZ0CenzPw/JyPZxfRp4E8Pwfy/IKB5xecPF2izwB5fgHk+SUDzy95eZaIPgvk+SWQ51cMPL/i5kkMngPm+grI82sGnl9z8NT80vPB+l2W7QUgz28YeH4jmManh8KLuH7Lb4A8FzDwXCDYrvcuoi8BeS4A8vyWgee3fDy7iL4M5PktkOdCBp4LOXm6RF8B8lwI5LmIgeciXp4loq8CeS4C8lzMwHMxN09i8Bow12IgzyUMPJdU4Kk/Dx20398BeXr7WQs+7zXAmv/BVHPAsS71bwD/j1d+AuT3Pa5fyHtul+P3NZDfEiC/HwR2rlDcxntYqjnE+VkPUk9SPWkt0Xlv5tqkdUjrktYjrU/qTdqA1Ie0IWkjUl/SxqRNSP1Im5L6kwaQBpIGkQaTGkjO37V1/j5CiLQZaXPSFqQtSVuRtiZtQxpG2pY0nDSCtB1pJGl70g4OE5JzYUUc1qQYKU5KkJKkFClNGkXakbQTaWfSLqRdXbajSbuT9iCNIe1J2os0ljSO5DxPtg/pT6Q/k/5C2pe0H2l/0gGkA0kHeZiG3D2a624r6a8zRztzlnPd/eByUFs/dz/c3Te1tHYUQ61thUK+PWS12aFCPpRryuftNrulGGorNDd3tIaK01tt5+bq0tkU7hlY5aMb7aZJjcXS8f3d47aqdHyjNcX2HJ0ttLQXrZbOAwd098CB3T1wUHcPHNzdAxu6e+CQ7h44tLsHhrp74GbdPXDz7h64RXcP3NI9ILYKB7YUijZ9r70xVGyz7VB7i9Xa3ljozLMVKM/WfvJ0NDc35Zvstgp5tgHlGeYeH101sMU2K1uskGZbTBo1nyVWIU1rR6a5KRvKWUWrQqYRsExqllRTSdZqbg4VCyGrvd1uK06cbE2bmGkqTmxvmmE7P075az7GX/P9/TVf4DZTs5lVLNqTW4ulI3K50NSmYmOoMMVuyzcXnMdySmsNftov9tn+O5/tv/fZ/kef7X/y2f5nn+1/8dl+qc/2y3y2/9Vn+//4bP9fn+1/89lefRBe1fa1Ptv38Nm+3mf7Xj7br+Oz/Xo+2/f22b6Pz/Yb+Wy/sc/2/Xy27++n/f8AOvMkzNXPAAA=", "debug_symbols": "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", "file_map": { "19": { "source": "mod bn254;\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n pub fn to_le_bits(self: Self, bit_size: u32) -> [u1] {\n crate::assert_constant(bit_size);\n self.__to_le_bits(bit_size)\n }\n \n pub fn to_be_bits(self: Self, bit_size: u32) -> [u1] {\n crate::assert_constant(bit_size);\n self.__to_be_bits(bit_size)\n }\n\n #[builtin(to_le_bits)]\n fn __to_le_bits(self, _bit_size: u32) -> [u1] {}\n \n #[builtin(to_be_bits)]\n fn __to_be_bits(self, bit_size: u32) -> [u1] {}\n\n #[builtin(apply_range_constraint)]\n fn __assert_max_bit_size(self, bit_size: u32) {}\n\n pub fn assert_max_bit_size(self: Self, bit_size: u32) {\n crate::assert_constant(bit_size);\n assert(bit_size < modulus_num_bits() as u32);\n self.__assert_max_bit_size(bit_size);\n }\n\n pub fn to_le_bytes(self: Self, byte_size: u32) -> [u8] {\n self.to_le_radix(256, byte_size)\n }\n\n pub fn to_be_bytes(self: Self, byte_size: u32) -> [u8] {\n self.to_be_radix(256, byte_size)\n }\n\n\n pub fn to_le_radix(self: Self, radix: u32, result_len: u32) -> [u8] {\n crate::assert_constant(radix);\n crate::assert_constant(result_len);\n self.__to_le_radix(radix, result_len)\n }\n\n pub fn to_be_radix(self: Self, radix: u32, result_len: u32) -> [u8] {\n crate::assert_constant(radix);\n crate::assert_constant(result_len);\n self.__to_be_radix(radix, result_len)\n }\n\n\n\n // decompose `_self` into a `_result_len` vector over the `_radix` basis\n // `_radix` must be less than 256\n #[builtin(to_le_radix)]\n fn __to_le_radix(self, radix: u32, result_len: u32) -> [u8] {}\n \n #[builtin(to_be_radix)]\n fn __to_be_radix(self, radix: u32, result_len: u32) -> [u8] {}\n\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b = exponent.to_le_bits(32);\n\n for i in 1..33 {\n r *= r;\n r = (b[32-i] as Field) * (r * self) + (1 - b[32-i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x ∈ {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n}\n\n#[builtin(modulus_num_bits)]\npub fn modulus_num_bits() -> Field {}\n\n#[builtin(modulus_be_bits)]\npub fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub fn modulus_le_bytes() -> [u8] {}\n// Convert a 32 byte array to a field element\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n let num_bytes = (modulus_num_bits() as u32 + 7) / 8;\n let x_bytes = x.to_le_bytes(num_bytes);\n let y_bytes = y.to_le_bytes(num_bytes);\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..num_bytes {\n if (!done) {\n let x_byte = x_bytes[num_bytes - 1 - i] as u8;\n let y_byte = y_bytes[num_bytes - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n}\n\n", "path": "std/field.nr" }, "40": { "source": "use crate::ops::{Add, Sub, Mul, Div, Rem, BitOr, BitAnd, BitXor, Shl, Shr};\nuse crate::cmp::{Eq, Ord, Ordering};\n\nglobal pow64 : Field = 18446744073709551616; //2^64;\n\nstruct U128 {\n lo: Field,\n hi: Field,\n}\n\nimpl U128 {\n\n pub fn from_u64s_le(lo: u64, hi: u64) -> U128 {\n // in order to handle multiplication, we need to represent the product of two u64 without overflow\n assert(crate::field::modulus_num_bits() as u32 > 128);\n U128 {\n lo: lo as Field,\n hi: hi as Field,\n }\n }\n\n pub fn from_u64s_be(hi: u64, lo: u64) -> U128 {\n U128::from_u64s_le(lo,hi)\n }\n\n pub fn from_le_bytes(bytes: [u8; 16]) -> U128 {\n let mut lo = 0;\n let mut base = 1;\n for i in 0..8 {\n lo += (bytes[i] as Field)*base;\n base *= 256;\n }\n let mut hi = 0;\n base = 1;\n for i in 8..16 {\n hi += (bytes[i] as Field)*base;\n base *= 256;\n }\n U128 {\n lo,\n hi,\n }\n }\n\n pub fn to_be_bytes(self: Self) -> [u8; 16] {\n let lo = self.lo.to_be_bytes(8);\n let hi = self.hi.to_be_bytes(8);\n let mut bytes = [0;16];\n for i in 0..8 {\n bytes[i] = hi[i];\n bytes[i+8] = lo[i];\n }\n bytes\n }\n\n pub fn to_le_bytes(self: Self) -> [u8; 16] {\n let lo = self.lo.to_le_bytes(8);\n let hi = self.hi.to_le_bytes(8);\n let mut bytes = [0;16];\n for i in 0..8 {\n bytes[i] = lo[i];\n bytes[i+8] = hi[i];\n }\n bytes\n }\n\n pub fn from_hex<N>(hex: str<N>) -> U128 {\n let N = N as u32;\n let bytes = hex.as_bytes();\n // string must starts with \"0x\"\n assert((bytes[0] == 48) & (bytes[1] == 120), \"Invalid hexadecimal string\");\n assert(N < 35, \"Input does not fit into a U128\");\n\n let mut lo = 0;\n let mut hi = 0;\n let mut base = 1; \n if N <= 18 {\n for i in 0..N-2 {\n lo += U128::decode_ascii(bytes[N-i-1])*base;\n base = base*16;\n }\n } else {\n for i in 0..16 {\n lo += U128::decode_ascii(bytes[N-i-1])*base;\n base = base*16;\n }\n base = 1;\n for i in 17..N-1 { \n hi += U128::decode_ascii(bytes[N-i])*base;\n base = base*16;\n }\n }\n U128 {\n lo: lo as Field,\n hi: hi as Field,\n }\n }\n\n fn decode_ascii(ascii: u8) -> Field {\n if ascii < 58 {\n ascii - 48\n } else {\n if ascii < 71 {\n ascii - 55\n } else {\n ascii - 87\n }\n \n } as Field\n }\n\n unconstrained fn unconstrained_div(self: Self, b: U128) -> (U128, U128) {\n if self < b {\n (U128::from_u64s_le(0, 0), self)\n } else {\n //TODO check if this can overflow?\n let (q,r) = self.unconstrained_div(b * U128::from_u64s_le(2,0));\n let q_mul_2 = q * U128::from_u64s_le(2,0);\n if r < b {\n (q_mul_2, r)\n } else {\n (q_mul_2 + U128::from_u64s_le(1,0), r - b)\n }\n\n } \n }\n\n pub fn from_integer<T>(i: T) -> U128 {\n let f = crate::as_field(i);\n // Reject values which would overflow a u128\n f.assert_max_bit_size(128);\n let lo = f as u64 as Field;\n let hi = (f-lo) / pow64;\n U128 {\n lo,\n hi,\n }\n }\n\n pub fn to_integer<T>(self) -> T {\n crate::from_field(self.lo+self.hi*pow64)\n }\n\n fn wrapping_mul(self: Self, b: U128) -> U128 {\n let low = self.lo*b.lo;\n let lo = low as u64 as Field;\n let carry = (low - lo) / pow64;\n let high = if crate::field::modulus_num_bits() as u32 > 196 {\n (self.lo+self.hi)*(b.lo+b.hi) - low + carry\n } else {\n self.lo*b.hi + self.hi*b.lo + carry\n };\n let hi = high as u64 as Field;\n U128 {\n lo,\n hi,\n }\n }\n}\n\nimpl Add for U128 {\n fn add(self: Self, b: U128) -> U128 {\n let low = self.lo + b.lo;\n let lo = low as u64 as Field;\n let carry = (low - lo) / pow64; \n let high = self.hi + b.hi + carry;\n let hi = high as u64 as Field;\n assert(hi == high, \"attempt to add with overflow\");\n U128 {\n lo,\n hi,\n }\n }\n}\n\nimpl Sub for U128 {\n fn sub(self: Self, b: U128) -> U128 {\n let low = pow64 + self.lo - b.lo;\n let lo = low as u64 as Field;\n let borrow = (low == lo) as Field;\n let high = self.hi - b.hi - borrow;\n let hi = high as u64 as Field;\n assert(hi == high, \"attempt to subtract with overflow\");\n U128 {\n lo,\n hi,\n }\n }\n}\n\nimpl Mul for U128 {\n fn mul(self: Self, b: U128) -> U128 {\n assert(self.hi*b.hi == 0, \"attempt to multiply with overflow\");\n let low = self.lo*b.lo;\n let lo = low as u64 as Field;\n let carry = (low - lo) / pow64;\n let high = if crate::field::modulus_num_bits() as u32 > 196 {\n (self.lo+self.hi)*(b.lo+b.hi) - low + carry\n } else {\n self.lo*b.hi + self.hi*b.lo + carry\n };\n let hi = high as u64 as Field;\n assert(hi == high, \"attempt to multiply with overflow\");\n U128 {\n lo,\n hi,\n }\n }\n}\n\nimpl Div for U128 {\n fn div(self: Self, b: U128) -> U128 {\n let (q,r) = self.unconstrained_div(b);\n let a = b * q + r;\n assert_eq(self, a);\n assert(r < b);\n q\n }\n}\n\nimpl Rem for U128 {\n fn rem(self: Self, b: U128) -> U128 {\n let (q,r) = self.unconstrained_div(b);\n let a = b * q + r;\n assert_eq(self, a);\n assert(r < b);\n r\n }\n}\n\nimpl Eq for U128 {\n fn eq(self: Self, b: U128) -> bool {\n (self.lo == b.lo) & (self.hi == b.hi)\n }\n}\n\nimpl Ord for U128 {\n fn cmp(self, other: Self) -> Ordering {\n let hi_ordering = (self.hi as u64).cmp((other.hi as u64));\n let lo_ordering = (self.lo as u64).cmp((other.lo as u64));\n \n if hi_ordering == Ordering::equal() {\n lo_ordering\n } else {\n hi_ordering\n }\n }\n}\n\nimpl BitOr for U128 { \n fn bitor(self, other: U128) -> U128 {\n U128 {\n lo: ((self.lo as u64) | (other.lo as u64)) as Field,\n hi: ((self.hi as u64) | (other.hi as u64))as Field\n }\n }\n}\n\nimpl BitAnd for U128 {\n fn bitand(self, other: U128) -> U128 { \n U128 {\n lo: ((self.lo as u64) & (other.lo as u64)) as Field,\n hi: ((self.hi as u64) & (other.hi as u64)) as Field\n }\n }\n}\n\nimpl BitXor for U128 {\n fn bitxor(self, other: U128) -> U128 { \n U128 {\n lo: ((self.lo as u64) ^ (other.lo as u64)) as Field,\n hi: ((self.hi as u64) ^ (other.hi as u64)) as Field\n }\n }\n}\n\nimpl Shl for U128 { \n fn shl(self, other: U128) -> U128 { \n assert(other < U128::from_u64s_le(128,0), \"attempt to shift left with overflow\");\n let exp_bits = other.lo.to_be_bits(7);\n\n let mut r: Field = 2;\n let mut y: Field = 1;\n for i in 1..8 {\n y = (exp_bits[7-i] as Field) * (r * y) + (1 - exp_bits[7-i] as Field) * y;\n r *= r;\n }\n self.wrapping_mul(U128::from_integer(y))\n } \n}\n\nimpl Shr for U128 { \n fn shr(self, other: U128) -> U128 { \n assert(other < U128::from_u64s_le(128,0), \"attempt to shift right with overflow\");\n let exp_bits = other.lo.to_be_bits(7);\n\n let mut r: Field = 2;\n let mut y: Field = 1;\n for i in 1..8 {\n y = (exp_bits[7-i] as Field) * (r * y) + (1 - exp_bits[7-i] as Field) * y;\n r *= r;\n }\n self / U128::from_integer(y)\n } \n}\n", "path": "std/uint128.nr" }, "49": { "source": "use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::{ContractClassFunctionLeafPreimage, FunctionLeafPreimage};\nuse crate::contract_class::ContractClassId;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT, ARGS_HASH_CHUNK_LENGTH, CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT,\n NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_COMMITMENT,\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__VK, GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__COMMITMENT_NONCE, GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__FUNCTION_ARGS\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field<N>(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args<N>(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership<N>(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path<N>(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n contract_class_id: ContractClassId,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, contract_class_id };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path)\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_commitment(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_COMMITMENT\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key<CT::bn254>::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec<u8, 160> = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__COMMITMENT_NONCE\n )\n}\n\npub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_commitment\n ],\n GENERATOR_INDEX__UNIQUE_COMMITMENT\n )\n}\n\npub fn compute_unique_siloed_commitments<N>(\n first_nullifier: Field,\n siloed_commitments: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_commitments = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_commitment = siloed_commitments[i];\n if siloed_commitment.value != 0 {\n let nonce = compute_commitment_nonce(first_nullifier, i);\n unique_siloed_commitments[i] = SideEffect {\n value: compute_unique_siloed_commitment(nonce, siloed_commitment.value),\n counter: siloed_commitment.counter\n };\n }\n }\n unique_siloed_commitments\n}\n\npub fn pedersen_hash<N>(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n", "path": "/usr/src/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr" }, "81": { "source": "// This is a quick struct made to pack 32 bytes into 4 u64s\n// and then pack those into two u128s.\n//\n// Creating a u256 was made for convenience.\n//\n// This is needed because in the cpp code, we have accumulate_sha256\n// which returns 2 field elements, one for the high and low limb.\nstruct U256 {\n // This is in big-endian order, typically because\n // sha256 is usually in big endian order.\n // Note: this means that inner[0] has the most significant 64 bits.\n inner : [u64; 4]\n}\n\nimpl U256 {\n pub fn from_bytes32(bytes: [u8; 32]) -> U256 {\n // We use addition rather than a bitwise OR as the bitshifts ensure that none of the bytes overlap each other.\n let high_0 = ((bytes[0] as u64) << 56)\n + ((bytes[1] as u64) << 48)\n + ((bytes[2] as u64) << 40)\n + ((bytes[3] as u64) << 32)\n + ((bytes[4] as u64) << 24)\n + ((bytes[5] as u64) << 16)\n + ((bytes[6] as u64) << 8)\n + (bytes[7] as u64);\n\n let high_1 = ((bytes[8] as u64) << 56)\n + ((bytes[9] as u64) << 48)\n + ((bytes[10] as u64) << 40)\n + ((bytes[11] as u64) << 32)\n + ((bytes[12] as u64) << 24)\n + ((bytes[13] as u64) << 16)\n + ((bytes[14] as u64) << 8)\n + (bytes[15] as u64);\n\n let low_0 = ((bytes[16] as u64) << 56)\n + ((bytes[17] as u64) << 48)\n + ((bytes[18] as u64) << 40)\n + ((bytes[19] as u64) << 32)\n + ((bytes[20] as u64) << 24)\n + ((bytes[21] as u64) << 16)\n + ((bytes[22] as u64) << 8)\n + (bytes[23] as u64);\n\n let low_1 = ((bytes[24] as u64) << 56)\n + ((bytes[25] as u64) << 48)\n + ((bytes[26] as u64) << 40)\n + ((bytes[27] as u64) << 32)\n + ((bytes[28] as u64) << 24)\n + ((bytes[29] as u64) << 16)\n + ((bytes[30] as u64) << 8)\n + (bytes[31] as u64);\n\n U256 { inner: [high_0, high_1, low_0, low_1] }\n }\n\n // We cannot represent u128 in the type system\n // so we cannot return a u128 type.\n // \n // This as conversion assumes that Field can store 128 bits of information\n // or else the conversion is lossy.\n //\n // TODO: Add a test for this.\n pub fn to_u128_limbs(self) -> [Field; 2] {\n let two_pow_64 = 2.pow_32(64);\n\n let high = (self.inner[0] as Field) * two_pow_64 + self.inner[1] as Field;\n let low = (self.inner[2] as Field) * two_pow_64 + self.inner[3] as Field;\n\n [high, low]\n }\n}\n\n#[test]\nfn smoke_u256_from_bytes32_all_zeroes() {\n let input = [0; 32];\n let result = U256::from_bytes32(input);\n assert(result.inner[0] == 0);\n assert(result.inner[1] == 0);\n assert(result.inner[2] == 0);\n assert(result.inner[3] == 0);\n}\n\n#[test]\nfn smoke_u256_from_bytes32_one_zero_zero_zero() {\n // We want to output [1,0,0,0]\n let input = [\n 0, 0, 0, 0, 0, 0, 0, 1,\n 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0\n ];\n let result = U256::from_bytes32(input);\n\n assert(result.inner[0] == 1);\n assert(result.inner[1] == 0);\n assert(result.inner[2] == 0);\n assert(result.inner[3] == 0);\n}\n\n#[test]\nfn smoke_u256_from_bytes32_test() {\n /*\n input: [ 0xAA, 0xBB, 0xCC, 0xDD, \n 0xEE, 0xFF, 0x00, 0x11, \n 0x22, 0x33, 0x44, 0x55, \n 0x66, 0x77, 0x88, 0x99, \n 0x11, 0x22, 0x33, 0x44, \n 0x55, 0x66, 0x77, 0x88, \n 0x99, 0xAA, 0xBB, 0xCC, \n 0xDD, 0xEE, 0xFF, 0x00\n ]\n output: inner[0]: 0xAABBCCDDEEFF0011\n inner[1]: 0x2233445566778899\n inner[2]: 0x1122334455667788\n inner[3]: 0x99AABBCCDDEEFF00\n */\n let input : [u8;32] = [\n 0xAA, 0xBB, 0xCC, 0xDD,\n 0xEE, 0xFF, 0x00, 0x11,\n 0x22, 0x33, 0x44, 0x55,\n 0x66, 0x77, 0x88, 0x99,\n 0x11, 0x22, 0x33, 0x44,\n 0x55, 0x66, 0x77, 0x88,\n 0x99, 0xAA, 0xBB, 0xCC,\n 0xDD, 0xEE, 0xFF, 0x00\n ];\n let result = U256::from_bytes32(input);\n\n assert(result.inner[0] == 0xAABBCCDDEEFF0011);\n assert(result.inner[1] == 0x2233445566778899);\n assert(result.inner[2] == 0x1122334455667788);\n assert(result.inner[3] == 0x99AABBCCDDEEFF00);\n}\n", "path": "/usr/src/noir-projects/noir-protocol-circuits/src/crates/types/src/utils/uint256.nr" }, "146": { "source": "use crate::abis::base_or_merge_rollup_public_inputs::BaseOrMergeRollupPublicInputs;\nuse dep::types::mocked::AggregationObject;\nuse dep::types::hash::{accumulate_sha256, assert_check_membership, root_from_sibling_path};\nuse dep::types::constants::NUM_FIELDS_PER_SHA256;\nuse crate::abis::previous_rollup_data::PreviousRollupData;\nuse dep::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot;\n\n/**\n * Create an aggregation object for the proofs that are provided\n * - We add points P0 for each of our proofs\n * - We add points P1 for each of our proofs\n * - We concat our public inputs\n * TODO(Kev): This seems similar to the aggregate_proof method in the private-kernel-lib\n */\npub fn aggregate_proofs(\n left: BaseOrMergeRollupPublicInputs,\n _right: BaseOrMergeRollupPublicInputs\n) -> AggregationObject {\n // TODO: Similar to cpp code this does not do anything.\n left.aggregation_object\n}\n\n/**\n * Asserts that the rollup types are the same. \n * Either both merge or both base\n */\npub fn assert_both_input_proofs_of_same_rollup_type(\n left: BaseOrMergeRollupPublicInputs,\n right: BaseOrMergeRollupPublicInputs\n) {\n assert(left.rollup_type == right.rollup_type, \"input proofs are of different rollup types\");\n}\n\n/**\n * Asserts that the rollup subtree heights are the same and returns the height\n * Returns the height of the rollup subtrees\n */\npub fn assert_both_input_proofs_of_same_height_and_return(\n left: BaseOrMergeRollupPublicInputs,\n right: BaseOrMergeRollupPublicInputs\n) -> Field {\n assert(\n left.height_in_block_tree == right.height_in_block_tree, \"input proofs are of different rollup heights\"\n );\n left.height_in_block_tree\n}\n\n/**\n * Asserts that the constants used in the left and right child are identical\n *\n */\npub fn assert_equal_constants(\n left: BaseOrMergeRollupPublicInputs,\n right: BaseOrMergeRollupPublicInputs\n) {\n assert(left.constants.eq(right.constants), \"input proofs have different constants\");\n}\n\n// asserts that the end snapshot of previous_rollup 0 equals the start snapshot of previous_rollup 1 (i.e. ensure they\n// follow on from one-another). Ensures that right uses the tres that was updated by left.\npub fn assert_prev_rollups_follow_on_from_each_other(\n left: BaseOrMergeRollupPublicInputs,\n right: BaseOrMergeRollupPublicInputs\n) {\n assert(\n left.end.note_hash_tree.eq(right.start.note_hash_tree), \"input proofs have different note hash tree snapshots\"\n );\n assert(\n left.end.nullifier_tree.eq(right.start.nullifier_tree), \"input proofs have different nullifier tree snapshots\"\n );\n assert(\n left.end.contract_tree.eq(right.start.contract_tree), \"input proofs have different contract tree snapshots\"\n );\n assert(\n left.end.public_data_tree.eq(right.start.public_data_tree), \"input proofs have different public data tree snapshots\"\n );\n}\n\n/**\n * @brief From two previous rollup data, compute a single calldata hash\n *\n * @param previous_rollup_data\n * @return calldata hash stored in 2 fields\n */\npub fn compute_calldata_hash(previous_rollup_data: [PreviousRollupData; 2]) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_rollup_data[0].base_or_merge_rollup_public_inputs.calldata_hash[0]),\n U128::from_integer(previous_rollup_data[0].base_or_merge_rollup_public_inputs.calldata_hash[1]),\n U128::from_integer(previous_rollup_data[1].base_or_merge_rollup_public_inputs.calldata_hash[0]),\n U128::from_integer(previous_rollup_data[1].base_or_merge_rollup_public_inputs.calldata_hash[1])\n ]\n )\n}\n\npub fn insert_subtree_to_snapshot_tree<N>(\n snapshot: AppendOnlyTreeSnapshot,\n siblingPath: [Field; N],\n emptySubtreeRoot: Field,\n subtreeRootToInsert: Field,\n subtreeDepth: u8\n) -> AppendOnlyTreeSnapshot {\n // TODO(Lasse): Sanity check len of siblingPath > height of subtree\n // TODO(Lasse): Ensure height of subtree is correct (eg 3 for commitments, 1 for contracts)\n let leafIndexAtDepth = snapshot.next_available_leaf_index >> (subtreeDepth as u32);\n\n // Check that the current root is correct and that there is an empty subtree at the insertion location\n assert_check_membership(\n emptySubtreeRoot,\n leafIndexAtDepth as Field,\n siblingPath,\n snapshot.root\n );\n\n // if index of leaf is x, index of its parent is x/2 or x >> 1. We need to find the parent `subtreeDepth` levels up.\n let new_root = root_from_sibling_path(subtreeRootToInsert, leafIndexAtDepth as Field, siblingPath);\n\n // 2^subtreeDepth is the number of leaves added. 2^x = 1 << x\n let new_next_available_leaf_index = (snapshot.next_available_leaf_index as u64) + (1 << (subtreeDepth as u64));\n\n AppendOnlyTreeSnapshot { root: new_root, next_available_leaf_index: new_next_available_leaf_index as u32 }\n}\n", "path": "/usr/src/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/components.nr" }, "148": { "source": "use crate::abis::previous_rollup_data::PreviousRollupData;\nuse crate::abis::base_or_merge_rollup_public_inputs::{BaseOrMergeRollupPublicInputs, MERGE_ROLLUP_TYPE};\nuse crate::components;\n\nstruct MergeRollupInputs{\n // TODO(Kev): Why is this 2?\n previous_rollup_data : [PreviousRollupData; 2]\n}\n\nimpl MergeRollupInputs {\n pub fn merge_rollup_circuit(self) -> BaseOrMergeRollupPublicInputs {\n // TODO(Lasse): Verify the previous rollup proofs\n // TODO(Lasse): Check both previous rollup vks (in previous_rollup_data) against the permitted set of kernel vks.\n // we don't have a set of permitted kernel vks yet.\n\n let left = self.previous_rollup_data[0].base_or_merge_rollup_public_inputs;\n let right = self.previous_rollup_data[1].base_or_merge_rollup_public_inputs;\n\n // check that both input proofs are either both \"BASE\" or \"MERGE\" and not a mix!\n // this prevents having wonky commitment, nullifier and contract subtrees.\n let aggregation_object = components::aggregate_proofs(left, right);\n components::assert_both_input_proofs_of_same_rollup_type(left, right);\n let current_height = components::assert_both_input_proofs_of_same_height_and_return(left, right);\n components::assert_equal_constants(left, right);\n components::assert_prev_rollups_follow_on_from_each_other(left, right);\n\n // compute calldata hash:\n let new_calldata_hash = components::compute_calldata_hash(self.previous_rollup_data);\n\n let public_inputs = BaseOrMergeRollupPublicInputs {\n rollup_type: MERGE_ROLLUP_TYPE,\n height_in_block_tree: current_height + 1,\n aggregation_object,\n constants: left.constants,\n start: left.start,\n end: right.end,\n calldata_hash: new_calldata_hash\n };\n\n public_inputs\n }\n}\n\nmod tests {\n use crate::{\n merge::merge_rollup_inputs::MergeRollupInputs,\n tests::merge_rollup_inputs::default_merge_rollup_inputs\n };\n use dep::types::hash::accumulate_sha256;\n\n #[test(should_fail_with=\"input proofs are of different rollup types\")]\n fn different_rollup_type_fails() {\n let mut inputs = default_merge_rollup_inputs();\n inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.rollup_type = 0;\n inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.rollup_type = 1;\n let _output = inputs.merge_rollup_circuit();\n }\n\n #[test(should_fail_with=\"input proofs are of different rollup heights\")]\n fn different_height_fails() {\n let mut inputs = default_merge_rollup_inputs();\n inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.height_in_block_tree = 0;\n inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.height_in_block_tree = 1;\n let _output = inputs.merge_rollup_circuit();\n }\n\n #[test(should_fail_with=\"input proofs have different constants\")]\n fn constants_different_fails() {\n let mut inputs = default_merge_rollup_inputs();\n inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.public_kernel_vk_tree_root = 1;\n inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.public_kernel_vk_tree_root = 0;\n let _output = inputs.merge_rollup_circuit();\n }\n\n #[test(should_fail_with=\"input proofs have different constants\")]\n fn constants_different_chain_id_fails() {\n let mut inputs = default_merge_rollup_inputs();\n inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.global_variables.chain_id = 1;\n inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.global_variables.chain_id = 0;\n let _output = inputs.merge_rollup_circuit();\n }\n\n #[test(should_fail_with=\"input proofs have different note hash tree snapshots\")]\n fn previous_rollups_dont_follow_note_hash() {\n let mut inputs = default_merge_rollup_inputs();\n inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.note_hash_tree.root = 0;\n inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.note_hash_tree.root = 1;\n let _output = inputs.merge_rollup_circuit();\n }\n\n #[test(should_fail_with=\"input proofs have different nullifier tree snapshots\")]\n fn previous_rollups_dont_follow_nullifier() {\n let mut inputs = default_merge_rollup_inputs();\n inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.nullifier_tree.root = 0;\n inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.nullifier_tree.root = 1;\n let _output = inputs.merge_rollup_circuit();\n }\n\n #[test(should_fail_with=\"input proofs have different contract tree snapshots\")]\n fn previous_rollups_dont_follow_contracts() {\n let mut inputs = default_merge_rollup_inputs();\n inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.end.contract_tree.root = 0;\n inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.start.contract_tree.root = 1;\n let _output = inputs.merge_rollup_circuit();\n }\n\n #[test]\n fn rollup_fields_are_set_correctly() {\n let mut inputs = default_merge_rollup_inputs();\n let mut outputs = inputs.merge_rollup_circuit();\n assert_eq(outputs.rollup_type, 1);\n assert_eq(\n outputs.height_in_block_tree, inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.height_in_block_tree + 1\n );\n\n // set inputs to have a merge rollup type and set the rollup height and test again.\n inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.rollup_type = 1;\n inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.height_in_block_tree = 1;\n\n inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.rollup_type = 1;\n inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.height_in_block_tree = 1;\n\n outputs = inputs.merge_rollup_circuit();\n assert_eq(outputs.rollup_type, 1);\n assert_eq(outputs.height_in_block_tree, 2);\n }\n\n #[test]\n fn start_and_end_partial_states() {\n let mut inputs = default_merge_rollup_inputs();\n let outputs = inputs.merge_rollup_circuit();\n\n assert(outputs.start.eq(inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.start));\n assert(outputs.end.eq(inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.end));\n }\n\n #[test]\n fn calldata_hash() {\n let mut inputs = default_merge_rollup_inputs();\n let expected_calldata_hash = accumulate_sha256(\n [\n U128::from_integer(0),\n U128::from_integer(1),\n U128::from_integer(2),\n U128::from_integer(3)\n ]\n );\n let outputs = inputs.merge_rollup_circuit();\n\n assert_eq(outputs.calldata_hash, expected_calldata_hash);\n }\n\n #[test]\n fn constants_dont_change() {\n let mut inputs = default_merge_rollup_inputs();\n let outputs = inputs.merge_rollup_circuit();\n\n assert(\n inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.eq(outputs.constants)\n );\n assert(\n inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.eq(outputs.constants)\n );\n }\n}\n", "path": "/usr/src/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/merge/merge_rollup_inputs.nr" }, "153": { "source": "use dep::rollup_lib::merge::{MergeRollupInputs, BaseOrMergeRollupPublicInputs};\n\nfn main(inputs: MergeRollupInputs) -> pub BaseOrMergeRollupPublicInputs {\n inputs.merge_rollup_circuit()\n}\n", "path": "/usr/src/noir-projects/noir-protocol-circuits/src/crates/rollup-merge/src/main.nr" } } }
@@ -0,0 +1 @@
1
+ { "noir_version": "0.23.0+5f5843e35052b9d3599b8ab4f7633db0a225e82f", "hash": 14595151934097994213, "abi": { "parameters": [{ "name": "inputs", "type": { "kind": "struct", "path": "rollup_lib::root::root_rollup_inputs::RootRollupInputs", "fields": [{ "name": "previous_rollup_data", "type": { "kind": "array", "length": 2, "type": { "kind": "struct", "path": "rollup_lib::abis::previous_rollup_data::PreviousRollupData", "fields": [{ "name": "base_or_merge_rollup_public_inputs", "type": { "kind": "struct", "path": "rollup_lib::abis::base_or_merge_rollup_public_inputs::BaseOrMergeRollupPublicInputs", "fields": [{ "name": "rollup_type", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }, { "name": "height_in_block_tree", "type": { "kind": "field" } }, { "name": "aggregation_object", "type": { "kind": "struct", "path": "rollup_lib::types::mocked::AggregationObject", "fields": [] } }, { "name": "constants", "type": { "kind": "struct", "path": "rollup_lib::abis::constant_rollup_data::ConstantRollupData", "fields": [{ "name": "last_archive", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "private_kernel_vk_tree_root", "type": { "kind": "field" } }, { "name": "public_kernel_vk_tree_root", "type": { "kind": "field" } }, { "name": "base_rollup_vk_hash", "type": { "kind": "field" } }, { "name": "merge_rollup_vk_hash", "type": { "kind": "field" } }, { "name": "global_variables", "type": { "kind": "struct", "path": "rollup_lib::types::abis::global_variables::GlobalVariables", "fields": [{ "name": "chain_id", "type": { "kind": "field" } }, { "name": "version", "type": { "kind": "field" } }, { "name": "block_number", "type": { "kind": "field" } }, { "name": "timestamp", "type": { "kind": "field" } }, { "name": "coinbase", "type": { "kind": "struct", "path": "rollup_lib::types::address::EthAddress", "fields": [{ "name": "inner", "type": { "kind": "field" } }] } }, { "name": "fee_recipient", "type": { "kind": "struct", "path": "rollup_lib::types::address::AztecAddress", "fields": [{ "name": "inner", "type": { "kind": "field" } }] } }] } }] } }, { "name": "start", "type": { "kind": "struct", "path": "rollup_lib::types::partial_state_reference::PartialStateReference", "fields": [{ "name": "note_hash_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "nullifier_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "contract_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "public_data_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }] } }, { "name": "end", "type": { "kind": "struct", "path": "rollup_lib::types::partial_state_reference::PartialStateReference", "fields": [{ "name": "note_hash_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "nullifier_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "contract_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "public_data_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }] } }, { "name": "calldata_hash", "type": { "kind": "array", "length": 2, "type": { "kind": "field" } } }] } }, { "name": "proof", "type": { "kind": "struct", "path": "rollup_lib::types::mocked::Proof", "fields": [] } }, { "name": "vk", "type": { "kind": "struct", "path": "rollup_lib::types::mocked::VerificationKey", "fields": [] } }, { "name": "vk_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }, { "name": "vk_sibling_path", "type": { "kind": "struct", "path": "rollup_lib::types::abis::membership_witness::VKMembershipWitness", "fields": [{ "name": "leaf_index", "type": { "kind": "field" } }, { "name": "sibling_path", "type": { "kind": "array", "length": 8, "type": { "kind": "field" } } }] } }] } } }, { "name": "new_l1_to_l2_messages", "type": { "kind": "array", "length": 16, "type": { "kind": "field" } } }, { "name": "new_l1_to_l2_message_tree_root_sibling_path", "type": { "kind": "array", "length": 12, "type": { "kind": "field" } } }, { "name": "start_l1_to_l2_message_tree_snapshot", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "start_archive_snapshot", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "new_archive_sibling_path", "type": { "kind": "array", "length": 16, "type": { "kind": "field" } } }] }, "visibility": "private" }], "param_witnesses": { "inputs": [{ "start": 0, "end": 132 }] }, "return_type": { "abi_type": { "kind": "struct", "path": "rollup_lib::root::root_rollup_public_inputs::RootRollupPublicInputs", "fields": [{ "name": "aggregation_object", "type": { "kind": "struct", "path": "rollup_lib::types::mocked::AggregationObject", "fields": [] } }, { "name": "archive", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "header", "type": { "kind": "struct", "path": "rollup_lib::types::header::Header", "fields": [{ "name": "last_archive", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "body_hash", "type": { "kind": "array", "length": 2, "type": { "kind": "field" } } }, { "name": "state", "type": { "kind": "struct", "path": "rollup_lib::types::state_reference::StateReference", "fields": [{ "name": "l1_to_l2_message_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "partial", "type": { "kind": "struct", "path": "rollup_lib::types::partial_state_reference::PartialStateReference", "fields": [{ "name": "note_hash_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "nullifier_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "contract_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }, { "name": "public_data_tree", "type": { "kind": "struct", "path": "rollup_lib::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot", "fields": [{ "name": "root", "type": { "kind": "field" } }, { "name": "next_available_leaf_index", "type": { "kind": "integer", "sign": "unsigned", "width": 32 } }] } }] } }] } }, { "name": "global_variables", "type": { "kind": "struct", "path": "rollup_lib::types::abis::global_variables::GlobalVariables", "fields": [{ "name": "chain_id", "type": { "kind": "field" } }, { "name": "version", "type": { "kind": "field" } }, { "name": "block_number", "type": { "kind": "field" } }, { "name": "timestamp", "type": { "kind": "field" } }, { "name": "coinbase", "type": { "kind": "struct", "path": "rollup_lib::types::address::EthAddress", "fields": [{ "name": "inner", "type": { "kind": "field" } }] } }, { "name": "fee_recipient", "type": { "kind": "struct", "path": "rollup_lib::types::address::AztecAddress", "fields": [{ "name": "inner", "type": { "kind": "field" } }] } }] } }] } }, { "name": "l1_to_l2_messages_hash", "type": { "kind": "array", "length": 2, "type": { "kind": "field" } } }] }, "visibility": "public" }, "return_witnesses": [582, 585, 2, 3, 420, 421, 268, 271, 64, 65, 66, 67, 68, 69, 70, 71, 8, 9, 10, 11, 12, 13, 1158, 1159] }, "bytecode": "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", "debug_symbols": "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", "file_map": { "19": { "source": "mod bn254;\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n pub fn to_le_bits(self: Self, bit_size: u32) -> [u1] {\n crate::assert_constant(bit_size);\n self.__to_le_bits(bit_size)\n }\n \n pub fn to_be_bits(self: Self, bit_size: u32) -> [u1] {\n crate::assert_constant(bit_size);\n self.__to_be_bits(bit_size)\n }\n\n #[builtin(to_le_bits)]\n fn __to_le_bits(self, _bit_size: u32) -> [u1] {}\n \n #[builtin(to_be_bits)]\n fn __to_be_bits(self, bit_size: u32) -> [u1] {}\n\n #[builtin(apply_range_constraint)]\n fn __assert_max_bit_size(self, bit_size: u32) {}\n\n pub fn assert_max_bit_size(self: Self, bit_size: u32) {\n crate::assert_constant(bit_size);\n assert(bit_size < modulus_num_bits() as u32);\n self.__assert_max_bit_size(bit_size);\n }\n\n pub fn to_le_bytes(self: Self, byte_size: u32) -> [u8] {\n self.to_le_radix(256, byte_size)\n }\n\n pub fn to_be_bytes(self: Self, byte_size: u32) -> [u8] {\n self.to_be_radix(256, byte_size)\n }\n\n\n pub fn to_le_radix(self: Self, radix: u32, result_len: u32) -> [u8] {\n crate::assert_constant(radix);\n crate::assert_constant(result_len);\n self.__to_le_radix(radix, result_len)\n }\n\n pub fn to_be_radix(self: Self, radix: u32, result_len: u32) -> [u8] {\n crate::assert_constant(radix);\n crate::assert_constant(result_len);\n self.__to_be_radix(radix, result_len)\n }\n\n\n\n // decompose `_self` into a `_result_len` vector over the `_radix` basis\n // `_radix` must be less than 256\n #[builtin(to_le_radix)]\n fn __to_le_radix(self, radix: u32, result_len: u32) -> [u8] {}\n \n #[builtin(to_be_radix)]\n fn __to_be_radix(self, radix: u32, result_len: u32) -> [u8] {}\n\n\n // Returns self to the power of the given exponent value.\n // Caution: we assume the exponent fits into 32 bits\n // using a bigger bit size impacts negatively the performance and should be done only if the exponent does not fit in 32 bits\n pub fn pow_32(self, exponent: Field) -> Field {\n let mut r: Field = 1;\n let b = exponent.to_le_bits(32);\n\n for i in 1..33 {\n r *= r;\n r = (b[32-i] as Field) * (r * self) + (1 - b[32-i] as Field) * r;\n }\n r\n }\n\n // Parity of (prime) Field element, i.e. sgn0(x mod p) = 0 if x ∈ {0, ..., p-1} is even, otherwise sgn0(x mod p) = 1.\n pub fn sgn0(self) -> u1 {\n self as u1\n }\n\n pub fn lt(self, another: Field) -> bool {\n if crate::compat::is_bn254() {\n bn254_lt(self, another)\n } else {\n lt_fallback(self, another)\n }\n }\n\n}\n\n#[builtin(modulus_num_bits)]\npub fn modulus_num_bits() -> Field {}\n\n#[builtin(modulus_be_bits)]\npub fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub fn modulus_le_bytes() -> [u8] {}\n// Convert a 32 byte array to a field element\npub fn bytes32_to_field(bytes32: [u8; 32]) -> Field {\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (bytes32[15 - i] as Field) * v;\n low = low + (bytes32[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n low + high * v\n}\n\nfn lt_fallback(x: Field, y: Field) -> bool {\n let num_bytes = (modulus_num_bits() as u32 + 7) / 8;\n let x_bytes = x.to_le_bytes(num_bytes);\n let y_bytes = y.to_le_bytes(num_bytes);\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..num_bytes {\n if (!done) {\n let x_byte = x_bytes[num_bytes - 1 - i] as u8;\n let y_byte = y_bytes[num_bytes - 1 - i] as u8;\n let bytes_match = x_byte == y_byte;\n if !bytes_match {\n x_is_lt = x_byte < y_byte;\n done = true;\n }\n }\n }\n x_is_lt\n}\n\n", "path": "std/field.nr" }, "27": { "source": "mod poseidon;\nmod mimc;\n\n#[foreign(sha256)]\n// docs:start:sha256\npub fn sha256<N>(input: [u8; N]) -> [u8; 32]\n// docs:end:sha256\n{}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s<N>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n#[foreign(blake3)]\n// docs:start:blake3\npub fn blake3<N>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{}\n\n// docs:start:pedersen_commitment\nstruct PedersenPoint {\n x : Field,\n y : Field,\n}\n\npub fn pedersen_commitment<N>(input: [Field; N]) -> PedersenPoint\n// docs:end:pedersen_commitment\n{\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[foreign(pedersen_commitment)]\npub fn __pedersen_commitment_with_separator<N>(input: [Field; N], separator: u32) -> [Field; 2] {}\n\npub fn pedersen_commitment_with_separator<N>(input: [Field; N], separator: u32) -> PedersenPoint {\n let values = __pedersen_commitment_with_separator(input, separator);\n PedersenPoint { x: values[0], y: values[1] }\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash<N>(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[foreign(pedersen_hash)]\npub fn pedersen_hash_with_separator<N>(input: [Field; N], separator: u32) -> Field {}\n\npub fn hash_to_field<N>(input: [Field; N]) -> Field {\n let mut inputs_as_bytes = [];\n\n for i in 0..N {\n let input_bytes = input[i].to_le_bytes(32);\n for i in 0..32 {\n inputs_as_bytes = inputs_as_bytes.push_back(input_bytes[i]);\n }\n }\n\n let hashed_input = blake2s(inputs_as_bytes);\n crate::field::bytes32_to_field(hashed_input)\n}\n\n#[foreign(keccak256)]\n// docs:start:keccak256\npub fn keccak256<N>(input: [u8; N], message_size: u32) -> [u8; 32]\n// docs:end:keccak256\n{}\n\n#[foreign(poseidon2_permutation)]\npub fn poseidon2_permutation<N>(_input: [u8; N], _state_length: u32) -> [u8; N] {}\n\n#[foreign(sha256_compression)]\npub fn sha256_compression(_input: [u32; 16], _state: [u32; 8]) -> [u32; 8] {}\n", "path": "std/hash.nr" }, "40": { "source": "use crate::ops::{Add, Sub, Mul, Div, Rem, BitOr, BitAnd, BitXor, Shl, Shr};\nuse crate::cmp::{Eq, Ord, Ordering};\n\nglobal pow64 : Field = 18446744073709551616; //2^64;\n\nstruct U128 {\n lo: Field,\n hi: Field,\n}\n\nimpl U128 {\n\n pub fn from_u64s_le(lo: u64, hi: u64) -> U128 {\n // in order to handle multiplication, we need to represent the product of two u64 without overflow\n assert(crate::field::modulus_num_bits() as u32 > 128);\n U128 {\n lo: lo as Field,\n hi: hi as Field,\n }\n }\n\n pub fn from_u64s_be(hi: u64, lo: u64) -> U128 {\n U128::from_u64s_le(lo,hi)\n }\n\n pub fn from_le_bytes(bytes: [u8; 16]) -> U128 {\n let mut lo = 0;\n let mut base = 1;\n for i in 0..8 {\n lo += (bytes[i] as Field)*base;\n base *= 256;\n }\n let mut hi = 0;\n base = 1;\n for i in 8..16 {\n hi += (bytes[i] as Field)*base;\n base *= 256;\n }\n U128 {\n lo,\n hi,\n }\n }\n\n pub fn to_be_bytes(self: Self) -> [u8; 16] {\n let lo = self.lo.to_be_bytes(8);\n let hi = self.hi.to_be_bytes(8);\n let mut bytes = [0;16];\n for i in 0..8 {\n bytes[i] = hi[i];\n bytes[i+8] = lo[i];\n }\n bytes\n }\n\n pub fn to_le_bytes(self: Self) -> [u8; 16] {\n let lo = self.lo.to_le_bytes(8);\n let hi = self.hi.to_le_bytes(8);\n let mut bytes = [0;16];\n for i in 0..8 {\n bytes[i] = lo[i];\n bytes[i+8] = hi[i];\n }\n bytes\n }\n\n pub fn from_hex<N>(hex: str<N>) -> U128 {\n let N = N as u32;\n let bytes = hex.as_bytes();\n // string must starts with \"0x\"\n assert((bytes[0] == 48) & (bytes[1] == 120), \"Invalid hexadecimal string\");\n assert(N < 35, \"Input does not fit into a U128\");\n\n let mut lo = 0;\n let mut hi = 0;\n let mut base = 1; \n if N <= 18 {\n for i in 0..N-2 {\n lo += U128::decode_ascii(bytes[N-i-1])*base;\n base = base*16;\n }\n } else {\n for i in 0..16 {\n lo += U128::decode_ascii(bytes[N-i-1])*base;\n base = base*16;\n }\n base = 1;\n for i in 17..N-1 { \n hi += U128::decode_ascii(bytes[N-i])*base;\n base = base*16;\n }\n }\n U128 {\n lo: lo as Field,\n hi: hi as Field,\n }\n }\n\n fn decode_ascii(ascii: u8) -> Field {\n if ascii < 58 {\n ascii - 48\n } else {\n if ascii < 71 {\n ascii - 55\n } else {\n ascii - 87\n }\n \n } as Field\n }\n\n unconstrained fn unconstrained_div(self: Self, b: U128) -> (U128, U128) {\n if self < b {\n (U128::from_u64s_le(0, 0), self)\n } else {\n //TODO check if this can overflow?\n let (q,r) = self.unconstrained_div(b * U128::from_u64s_le(2,0));\n let q_mul_2 = q * U128::from_u64s_le(2,0);\n if r < b {\n (q_mul_2, r)\n } else {\n (q_mul_2 + U128::from_u64s_le(1,0), r - b)\n }\n\n } \n }\n\n pub fn from_integer<T>(i: T) -> U128 {\n let f = crate::as_field(i);\n // Reject values which would overflow a u128\n f.assert_max_bit_size(128);\n let lo = f as u64 as Field;\n let hi = (f-lo) / pow64;\n U128 {\n lo,\n hi,\n }\n }\n\n pub fn to_integer<T>(self) -> T {\n crate::from_field(self.lo+self.hi*pow64)\n }\n\n fn wrapping_mul(self: Self, b: U128) -> U128 {\n let low = self.lo*b.lo;\n let lo = low as u64 as Field;\n let carry = (low - lo) / pow64;\n let high = if crate::field::modulus_num_bits() as u32 > 196 {\n (self.lo+self.hi)*(b.lo+b.hi) - low + carry\n } else {\n self.lo*b.hi + self.hi*b.lo + carry\n };\n let hi = high as u64 as Field;\n U128 {\n lo,\n hi,\n }\n }\n}\n\nimpl Add for U128 {\n fn add(self: Self, b: U128) -> U128 {\n let low = self.lo + b.lo;\n let lo = low as u64 as Field;\n let carry = (low - lo) / pow64; \n let high = self.hi + b.hi + carry;\n let hi = high as u64 as Field;\n assert(hi == high, \"attempt to add with overflow\");\n U128 {\n lo,\n hi,\n }\n }\n}\n\nimpl Sub for U128 {\n fn sub(self: Self, b: U128) -> U128 {\n let low = pow64 + self.lo - b.lo;\n let lo = low as u64 as Field;\n let borrow = (low == lo) as Field;\n let high = self.hi - b.hi - borrow;\n let hi = high as u64 as Field;\n assert(hi == high, \"attempt to subtract with overflow\");\n U128 {\n lo,\n hi,\n }\n }\n}\n\nimpl Mul for U128 {\n fn mul(self: Self, b: U128) -> U128 {\n assert(self.hi*b.hi == 0, \"attempt to multiply with overflow\");\n let low = self.lo*b.lo;\n let lo = low as u64 as Field;\n let carry = (low - lo) / pow64;\n let high = if crate::field::modulus_num_bits() as u32 > 196 {\n (self.lo+self.hi)*(b.lo+b.hi) - low + carry\n } else {\n self.lo*b.hi + self.hi*b.lo + carry\n };\n let hi = high as u64 as Field;\n assert(hi == high, \"attempt to multiply with overflow\");\n U128 {\n lo,\n hi,\n }\n }\n}\n\nimpl Div for U128 {\n fn div(self: Self, b: U128) -> U128 {\n let (q,r) = self.unconstrained_div(b);\n let a = b * q + r;\n assert_eq(self, a);\n assert(r < b);\n q\n }\n}\n\nimpl Rem for U128 {\n fn rem(self: Self, b: U128) -> U128 {\n let (q,r) = self.unconstrained_div(b);\n let a = b * q + r;\n assert_eq(self, a);\n assert(r < b);\n r\n }\n}\n\nimpl Eq for U128 {\n fn eq(self: Self, b: U128) -> bool {\n (self.lo == b.lo) & (self.hi == b.hi)\n }\n}\n\nimpl Ord for U128 {\n fn cmp(self, other: Self) -> Ordering {\n let hi_ordering = (self.hi as u64).cmp((other.hi as u64));\n let lo_ordering = (self.lo as u64).cmp((other.lo as u64));\n \n if hi_ordering == Ordering::equal() {\n lo_ordering\n } else {\n hi_ordering\n }\n }\n}\n\nimpl BitOr for U128 { \n fn bitor(self, other: U128) -> U128 {\n U128 {\n lo: ((self.lo as u64) | (other.lo as u64)) as Field,\n hi: ((self.hi as u64) | (other.hi as u64))as Field\n }\n }\n}\n\nimpl BitAnd for U128 {\n fn bitand(self, other: U128) -> U128 { \n U128 {\n lo: ((self.lo as u64) & (other.lo as u64)) as Field,\n hi: ((self.hi as u64) & (other.hi as u64)) as Field\n }\n }\n}\n\nimpl BitXor for U128 {\n fn bitxor(self, other: U128) -> U128 { \n U128 {\n lo: ((self.lo as u64) ^ (other.lo as u64)) as Field,\n hi: ((self.hi as u64) ^ (other.hi as u64)) as Field\n }\n }\n}\n\nimpl Shl for U128 { \n fn shl(self, other: U128) -> U128 { \n assert(other < U128::from_u64s_le(128,0), \"attempt to shift left with overflow\");\n let exp_bits = other.lo.to_be_bits(7);\n\n let mut r: Field = 2;\n let mut y: Field = 1;\n for i in 1..8 {\n y = (exp_bits[7-i] as Field) * (r * y) + (1 - exp_bits[7-i] as Field) * y;\n r *= r;\n }\n self.wrapping_mul(U128::from_integer(y))\n } \n}\n\nimpl Shr for U128 { \n fn shr(self, other: U128) -> U128 { \n assert(other < U128::from_u64s_le(128,0), \"attempt to shift right with overflow\");\n let exp_bits = other.lo.to_be_bits(7);\n\n let mut r: Field = 2;\n let mut y: Field = 1;\n for i in 1..8 {\n y = (exp_bits[7-i] as Field) * (r * y) + (1 - exp_bits[7-i] as Field) * y;\n r *= r;\n }\n self / U128::from_integer(y)\n } \n}\n", "path": "std/uint128.nr" }, "48": { "source": "use crate::{\n abis::{\n append_only_tree_snapshot::{AppendOnlyTreeSnapshot, APPEND_ONLY_TREE_SNAPSHOT_LENGTH},\n global_variables::{GlobalVariables, GLOBAL_VARIABLES_LENGTH}\n},\n constants::{GENERATOR_INDEX__BLOCK_HASH, HEADER_LENGTH, NUM_FIELDS_PER_SHA256, STATE_REFERENCE_LENGTH},\n hash::pedersen_hash, state_reference::StateReference, traits::{Deserialize, Empty, Hash, Serialize},\n utils::{arr_copy_slice}\n};\n\n// docs:start:header\nstruct Header {\n last_archive: AppendOnlyTreeSnapshot,\n body_hash: [Field; NUM_FIELDS_PER_SHA256],\n state: StateReference,\n global_variables: GlobalVariables,\n}\n// docs:end:header\n\nimpl Eq for Header {\n fn eq(self, other: Self) -> bool {\n self.last_archive.eq(other.last_archive) &\n (self.body_hash == other.body_hash) &\n self.state.eq(other.state) &\n self.global_variables.eq(other.global_variables)\n }\n}\n\nimpl Serialize<HEADER_LENGTH> for Header {\n fn serialize(self) -> [Field; HEADER_LENGTH] {\n let mut fields: BoundedVec<Field, HEADER_LENGTH> = BoundedVec::new(0);\n\n fields.extend_from_array(self.last_archive.serialize());\n fields.extend_from_array(self.body_hash);\n fields.extend_from_array(self.state.serialize());\n fields.extend_from_array(self.global_variables.serialize());\n\n fields.storage\n }\n}\n\nimpl Deserialize<HEADER_LENGTH> for Header {\n fn deserialize(serialized: [Field; HEADER_LENGTH]) -> Self {\n let mut offset = 0;\n\n let last_archive_fields = arr_copy_slice(serialized, [0; APPEND_ONLY_TREE_SNAPSHOT_LENGTH], offset);\n offset = offset + APPEND_ONLY_TREE_SNAPSHOT_LENGTH;\n\n let body_hash = arr_copy_slice(serialized, [0; NUM_FIELDS_PER_SHA256], offset);\n offset = offset + NUM_FIELDS_PER_SHA256;\n\n let state_fields = arr_copy_slice(serialized, [0; STATE_REFERENCE_LENGTH], offset);\n offset = offset + STATE_REFERENCE_LENGTH;\n\n let global_variables_fields = arr_copy_slice(serialized, [0; GLOBAL_VARIABLES_LENGTH], offset);\n\n Header {\n last_archive: AppendOnlyTreeSnapshot::deserialize(last_archive_fields),\n body_hash,\n state: StateReference::deserialize(state_fields),\n global_variables: GlobalVariables::deserialize(global_variables_fields),\n }\n }\n}\n\nimpl Empty for Header {\n fn empty() -> Self {\n Self {\n last_archive: AppendOnlyTreeSnapshot::zero(),\n body_hash: [0; NUM_FIELDS_PER_SHA256],\n state: StateReference::empty(),\n global_variables: GlobalVariables::empty(),\n }\n }\n}\n\nimpl Hash for Header {\n fn hash(self) -> Field {\n pedersen_hash(self.serialize(), GENERATOR_INDEX__BLOCK_HASH)\n }\n}\n\n#[test]\nfn serialization_of_empty() {\n let header: Header = dep::std::unsafe::zeroed();\n let serialized = header.serialize();\n let deserialized = Header::deserialize(serialized);\n assert(header.eq(deserialized));\n}\n\n#[test]\nfn hash_smoke() {\n let header: Header = dep::std::unsafe::zeroed();\n let _hashed = header.hash();\n}\n", "path": "/usr/src/noir-projects/noir-protocol-circuits/src/crates/types/src/header.nr" }, "49": { "source": "use crate::address::{AztecAddress, EthAddress};\nuse crate::mocked::VerificationKey;\nuse crate::abis::function_selector::FunctionSelector;\nuse crate::abis::function_leaf_preimage::{ContractClassFunctionLeafPreimage, FunctionLeafPreimage};\nuse crate::contract_class::ContractClassId;\nuse crate::abis::new_contract_data::NewContractData as ContractLeafPreimage;\nuse crate::abis::function_data::FunctionData;\nuse crate::abis::side_effect::{SideEffect};\nuse crate::utils::uint256::U256;\nuse crate::constants::{\n ARGS_HASH_CHUNK_COUNT, ARGS_HASH_CHUNK_LENGTH, CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT,\n NOTE_HASH_TREE_HEIGHT, NUM_FIELDS_PER_SHA256, GENERATOR_INDEX__SILOED_COMMITMENT,\n GENERATOR_INDEX__OUTER_NULLIFIER, GENERATOR_INDEX__VK, GENERATOR_INDEX__CONSTRUCTOR,\n GENERATOR_INDEX__PARTIAL_ADDRESS, GENERATOR_INDEX__CONTRACT_ADDRESS,\n GENERATOR_INDEX__COMMITMENT_NONCE, GENERATOR_INDEX__UNIQUE_COMMITMENT,\n GENERATOR_INDEX__FUNCTION_ARGS\n};\n\nuse dep::std::hash::{pedersen_hash_with_separator, sha256};\n\npub fn sha256_to_field<N>(bytes_to_hash: [u8; N]) -> Field {\n let sha256_hashed = sha256(bytes_to_hash);\n\n // Convert it to a field element\n let mut v = 1;\n let mut high = 0 as Field;\n let mut low = 0 as Field;\n\n for i in 0..16 {\n high = high + (sha256_hashed[15 - i] as Field) * v;\n low = low + (sha256_hashed[16 + 15 - i] as Field) * v;\n v = v * 256;\n }\n\n // Abuse that a % p + b % p = (a + b) % p and that low < p\n let hash_in_a_field = low + high * v;\n\n hash_in_a_field\n}\n\npub fn hash_args<N>(args: [Field; N]) -> Field {\n if args.len() == 0 {\n 0\n } else {\n let mut chunks_hashes = [0; ARGS_HASH_CHUNK_COUNT];\n for i in 0..ARGS_HASH_CHUNK_COUNT {\n let mut chunk_hash = 0;\n let start_chunk_index = i * ARGS_HASH_CHUNK_LENGTH;\n if start_chunk_index < (args.len() as u32) {\n let mut chunk_args = [0; ARGS_HASH_CHUNK_LENGTH];\n for j in 0..ARGS_HASH_CHUNK_LENGTH {\n let item_index = i * ARGS_HASH_CHUNK_LENGTH + j;\n if item_index < (args.len() as u32) {\n chunk_args[j] = args[item_index];\n }\n }\n chunk_hash = pedersen_hash(chunk_args, GENERATOR_INDEX__FUNCTION_ARGS);\n }\n chunks_hashes[i] = chunk_hash;\n }\n pedersen_hash(chunks_hashes, GENERATOR_INDEX__FUNCTION_ARGS)\n }\n}\n\n// Checks that `value` is a member of a merkle tree with root `root` at position `index`\n// The witness being the `sibling_path`\npub fn assert_check_membership<N>(value: Field, index: Field, sibling_path: [Field; N], root: Field) {\n let calculated_root = root_from_sibling_path(value, index, sibling_path);\n assert(calculated_root == root, \"membership check failed\");\n}\n\n// Calculate the Merkle tree root from the sibling path and leaf.\n//\n// The leaf is hashed with its sibling, and then the result is hashed\n// with the next sibling etc in the path. The last hash is the root.\n//\n// TODO(David/Someone): The cpp code is using a uint256, whereas its\n// TODO a bit simpler in Noir to just have a bit array.\n// TODO: I'd generally like to avoid u256 for algorithms like \n// this because it means we never even need to consider cases where \n// the index is greater than p.\npub fn root_from_sibling_path<N>(leaf: Field, leaf_index: Field, sibling_path: [Field; N]) -> Field {\n let mut node = leaf;\n let indices = leaf_index.to_le_bits(N);\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] == 1 {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = merkle_hash(hash_left, hash_right);\n }\n node\n}\n\n// Calculate the function tree root from the sibling path and leaf preimage.\n//\n// TODO: The cpp code passes in components of the FunctionLeafPreimage and then \n// builds it up. We should build it up and then pass the leaf preimage as a parameter.\n// We can then choose to have a general method that takes in anything hashable\n// and deduplicate the logic in `contract_tree_root_from_siblings`\npub fn function_tree_root_from_siblings(\n selector: FunctionSelector,\n is_internal: bool,\n is_private: bool,\n vk_hash: Field,\n acir_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = FunctionLeafPreimage { selector, is_internal, is_private, vk_hash, acir_hash };\n\n let function_leaf = function_leaf_preimage.hash();\n\n let function_tree_root = root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path);\n\n function_tree_root\n}\n\n// Calculate the contract tree root from the sibling path and leaf preimage.\npub fn contract_tree_root_from_siblings(\n contract_class_id: ContractClassId,\n storage_contract_address: AztecAddress,\n portal_contract_address: EthAddress,\n contract_leaf_index: Field,\n contract_leaf_sibling_path: [Field; CONTRACT_TREE_HEIGHT]\n) -> Field {\n //TODO(Kev): if we use shorthand syntax here, we get an error as expected,\n // since variable name is `storage_contract_address` but the span is incorrect.\n let contract_leaf_preimage = ContractLeafPreimage { contract_address: storage_contract_address, portal_contract_address, contract_class_id };\n\n let contract_leaf = contract_leaf_preimage.hash();\n\n let computed_contract_tree_root = root_from_sibling_path(contract_leaf, contract_leaf_index, contract_leaf_sibling_path);\n\n computed_contract_tree_root\n}\n\npub fn private_functions_root_from_siblings(\n selector: FunctionSelector,\n vk_hash: Field,\n function_leaf_index: Field,\n function_leaf_sibling_path: [Field; FUNCTION_TREE_HEIGHT]\n) -> Field {\n let function_leaf_preimage = ContractClassFunctionLeafPreimage { selector, vk_hash };\n let function_leaf = function_leaf_preimage.hash();\n root_from_sibling_path(function_leaf, function_leaf_index, function_leaf_sibling_path)\n}\n\npub fn read_request_root_from_siblings(\n read_request: Field,\n leaf_index: Field,\n sibling_path: [Field; NOTE_HASH_TREE_HEIGHT]\n) -> Field {\n root_from_sibling_path(read_request, leaf_index, sibling_path)\n}\n\npub fn silo_commitment(address: AztecAddress, inner_commitment: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n inner_commitment\n ],\n GENERATOR_INDEX__SILOED_COMMITMENT\n )\n}\n\npub fn silo_nullifier(address: AztecAddress, nullifier: Field) -> Field {\n pedersen_hash(\n [\n address.to_field(),\n nullifier\n ],\n GENERATOR_INDEX__OUTER_NULLIFIER\n )\n}\n\nfn merkle_hash(left: Field, right: Field) -> Field {\n pedersen_hash([left, right], 0)\n}\n\npub fn stdlib_recursion_verification_key_compress_native_vk(_vk: VerificationKey) -> Field {\n // Original cpp code\n // stdlib::recursion::verification_key<CT::bn254>::compress_native(private_call.vk, GeneratorIndex::VK);\n // The above cpp method is only ever called on verification key, so it has been special cased here\n let _hash_index = GENERATOR_INDEX__VK;\n 0\n}\n\n// TODO CPP uses blake2s for this\npub fn compute_new_contract_address_hash(new_contract_address: AztecAddress) -> Field {\n dep::std::hash::pedersen_hash([new_contract_address.to_field()])\n}\n\npub fn compute_l2_to_l1_hash(\n contract_address: AztecAddress,\n rollup_version_id: Field,\n portal_contract_address: EthAddress,\n chain_id: Field,\n content: Field\n) -> Field {\n let mut bytes: BoundedVec<u8, 160> = BoundedVec::new(0);\n\n let inputs = [\n contract_address.to_field(), rollup_version_id, portal_contract_address.to_field(), chain_id, content\n ];\n for i in 0..inputs.len() {\n // TODO are bytes be in fr.to_buffer() ?\n let item_bytes = inputs[i].to_be_bytes(32);\n for j in 0..32 {\n bytes.push(item_bytes[j]);\n }\n }\n\n sha256_to_field(bytes.storage)\n}\n\npub fn compute_constructor_hash(\n function_data: FunctionData,\n args_hash: Field,\n constructor_vk_hash: Field\n) -> Field {\n let function_data_hash = function_data.hash();\n\n pedersen_hash(\n [\n function_data_hash,\n args_hash,\n constructor_vk_hash\n ],\n GENERATOR_INDEX__CONSTRUCTOR\n )\n}\n\n// Computes sha256 hash of 2 input hashes stored in 4 fields.\n// \n// This method is bn254 specific. Two fields is needed in order to \n// encode the sha256 output. It can be abstracted away with any 4-2 hash function.\n//\n// TODO(Jan and David): This is used for the encrypted_log hashes.\n// Can we check to see if we can just use hash_to_field or pedersen_compress here?\n//\n// Returning a Field would be desirable because then this can be replaced with \n// poseidon without changing the rest of the code\n//\npub fn accumulate_sha256(input: [U128; 4]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // This is a note about the cpp code, since it takes an array of Fields\n // instead of a U128.\n // 4 Field elements when converted to bytes will usually \n // occupy 4 * 32 = 128 bytes.\n // However, this function is making the assumption that each Field \n // only occupies 128 bits.\n //\n // TODO(David): This does not seem to be getting guaranteed anywhere in the code?\n //\n // Concatenate 4 u128 bit integers into a byte array.\n let mut hash_input_flattened = [0; 64];\n for offset in 0..4 {\n let input_as_bytes = input[offset].to_be_bytes();\n for byte_index in 0..16 {\n hash_input_flattened[offset * 16 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\npub fn compute_logs_hash(\n previous_log_hash: [Field; 2],\n current_log_hash: [Field; 2]\n) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_log_hash[0]),\n U128::from_integer(previous_log_hash[1]),\n U128::from_integer(current_log_hash[0]),\n U128::from_integer(current_log_hash[1])\n ]\n )\n}\n\npub fn compute_commitment_nonce(first_nullifier: Field, commitment_index: Field) -> Field {\n pedersen_hash(\n [\n first_nullifier,\n commitment_index\n ],\n GENERATOR_INDEX__COMMITMENT_NONCE\n )\n}\n\npub fn compute_unique_siloed_commitment(nonce: Field, siloed_commitment: Field) -> Field {\n pedersen_hash(\n [\n nonce,\n siloed_commitment\n ],\n GENERATOR_INDEX__UNIQUE_COMMITMENT\n )\n}\n\npub fn compute_unique_siloed_commitments<N>(\n first_nullifier: Field,\n siloed_commitments: [SideEffect; N]\n) -> [SideEffect; N] {\n let mut unique_siloed_commitments = [SideEffect::empty(); N];\n for i in 0..N {\n let siloed_commitment = siloed_commitments[i];\n if siloed_commitment.value != 0 {\n let nonce = compute_commitment_nonce(first_nullifier, i);\n unique_siloed_commitments[i] = SideEffect {\n value: compute_unique_siloed_commitment(nonce, siloed_commitment.value),\n counter: siloed_commitment.counter\n };\n }\n }\n unique_siloed_commitments\n}\n\npub fn pedersen_hash<N>(inputs: [Field; N], hash_index: u32) -> Field {\n dep::std::hash::pedersen_hash_with_separator(inputs, hash_index)\n}\n", "path": "/usr/src/noir-projects/noir-protocol-circuits/src/crates/types/src/hash.nr" }, "81": { "source": "// This is a quick struct made to pack 32 bytes into 4 u64s\n// and then pack those into two u128s.\n//\n// Creating a u256 was made for convenience.\n//\n// This is needed because in the cpp code, we have accumulate_sha256\n// which returns 2 field elements, one for the high and low limb.\nstruct U256 {\n // This is in big-endian order, typically because\n // sha256 is usually in big endian order.\n // Note: this means that inner[0] has the most significant 64 bits.\n inner : [u64; 4]\n}\n\nimpl U256 {\n pub fn from_bytes32(bytes: [u8; 32]) -> U256 {\n // We use addition rather than a bitwise OR as the bitshifts ensure that none of the bytes overlap each other.\n let high_0 = ((bytes[0] as u64) << 56)\n + ((bytes[1] as u64) << 48)\n + ((bytes[2] as u64) << 40)\n + ((bytes[3] as u64) << 32)\n + ((bytes[4] as u64) << 24)\n + ((bytes[5] as u64) << 16)\n + ((bytes[6] as u64) << 8)\n + (bytes[7] as u64);\n\n let high_1 = ((bytes[8] as u64) << 56)\n + ((bytes[9] as u64) << 48)\n + ((bytes[10] as u64) << 40)\n + ((bytes[11] as u64) << 32)\n + ((bytes[12] as u64) << 24)\n + ((bytes[13] as u64) << 16)\n + ((bytes[14] as u64) << 8)\n + (bytes[15] as u64);\n\n let low_0 = ((bytes[16] as u64) << 56)\n + ((bytes[17] as u64) << 48)\n + ((bytes[18] as u64) << 40)\n + ((bytes[19] as u64) << 32)\n + ((bytes[20] as u64) << 24)\n + ((bytes[21] as u64) << 16)\n + ((bytes[22] as u64) << 8)\n + (bytes[23] as u64);\n\n let low_1 = ((bytes[24] as u64) << 56)\n + ((bytes[25] as u64) << 48)\n + ((bytes[26] as u64) << 40)\n + ((bytes[27] as u64) << 32)\n + ((bytes[28] as u64) << 24)\n + ((bytes[29] as u64) << 16)\n + ((bytes[30] as u64) << 8)\n + (bytes[31] as u64);\n\n U256 { inner: [high_0, high_1, low_0, low_1] }\n }\n\n // We cannot represent u128 in the type system\n // so we cannot return a u128 type.\n // \n // This as conversion assumes that Field can store 128 bits of information\n // or else the conversion is lossy.\n //\n // TODO: Add a test for this.\n pub fn to_u128_limbs(self) -> [Field; 2] {\n let two_pow_64 = 2.pow_32(64);\n\n let high = (self.inner[0] as Field) * two_pow_64 + self.inner[1] as Field;\n let low = (self.inner[2] as Field) * two_pow_64 + self.inner[3] as Field;\n\n [high, low]\n }\n}\n\n#[test]\nfn smoke_u256_from_bytes32_all_zeroes() {\n let input = [0; 32];\n let result = U256::from_bytes32(input);\n assert(result.inner[0] == 0);\n assert(result.inner[1] == 0);\n assert(result.inner[2] == 0);\n assert(result.inner[3] == 0);\n}\n\n#[test]\nfn smoke_u256_from_bytes32_one_zero_zero_zero() {\n // We want to output [1,0,0,0]\n let input = [\n 0, 0, 0, 0, 0, 0, 0, 1,\n 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0,\n 0, 0, 0, 0, 0, 0, 0, 0\n ];\n let result = U256::from_bytes32(input);\n\n assert(result.inner[0] == 1);\n assert(result.inner[1] == 0);\n assert(result.inner[2] == 0);\n assert(result.inner[3] == 0);\n}\n\n#[test]\nfn smoke_u256_from_bytes32_test() {\n /*\n input: [ 0xAA, 0xBB, 0xCC, 0xDD, \n 0xEE, 0xFF, 0x00, 0x11, \n 0x22, 0x33, 0x44, 0x55, \n 0x66, 0x77, 0x88, 0x99, \n 0x11, 0x22, 0x33, 0x44, \n 0x55, 0x66, 0x77, 0x88, \n 0x99, 0xAA, 0xBB, 0xCC, \n 0xDD, 0xEE, 0xFF, 0x00\n ]\n output: inner[0]: 0xAABBCCDDEEFF0011\n inner[1]: 0x2233445566778899\n inner[2]: 0x1122334455667788\n inner[3]: 0x99AABBCCDDEEFF00\n */\n let input : [u8;32] = [\n 0xAA, 0xBB, 0xCC, 0xDD,\n 0xEE, 0xFF, 0x00, 0x11,\n 0x22, 0x33, 0x44, 0x55,\n 0x66, 0x77, 0x88, 0x99,\n 0x11, 0x22, 0x33, 0x44,\n 0x55, 0x66, 0x77, 0x88,\n 0x99, 0xAA, 0xBB, 0xCC,\n 0xDD, 0xEE, 0xFF, 0x00\n ];\n let result = U256::from_bytes32(input);\n\n assert(result.inner[0] == 0xAABBCCDDEEFF0011);\n assert(result.inner[1] == 0x2233445566778899);\n assert(result.inner[2] == 0x1122334455667788);\n assert(result.inner[3] == 0x99AABBCCDDEEFF00);\n}\n", "path": "/usr/src/noir-projects/noir-protocol-circuits/src/crates/types/src/utils/uint256.nr" }, "135": { "source": "struct MerkleTree<N> {\n leaves: [Field; N],\n nodes: [Field; N],\n}\n\nimpl<N> MerkleTree<N> {\n pub fn new(leaves: [Field; N]) -> Self {\n let mut nodes = [0; N];\n\n // We need one less node than leaves, but we cannot have computed array lengths\n let total_nodes = N - 1;\n let half_size = N / 2;\n\n // hash base layer\n for i in 0..half_size {\n nodes[i] = dep::std::hash::pedersen_hash([leaves[2*i], leaves[2*i+1]]);\n }\n\n // hash the other layers\n for i in 0..(total_nodes - half_size) {\n nodes[half_size+i] = dep::std::hash::pedersen_hash([nodes[2*i], nodes[2*i+1]]);\n }\n\n MerkleTree { leaves, nodes }\n }\n\n fn get_root(self) -> Field {\n self.nodes[N - 2]\n }\n}\n\npub fn calculate_subtree<N>(leaves: [Field; N]) -> Field {\n MerkleTree::new(leaves).get_root()\n}\n\n// These values are precomputed and we run tests to ensure that they\n// are correct. The values themselves were computed from the cpp code.\n//\n// Would be good if we could use width since the compute_subtree\n// algorithm uses depth.\npub fn calculate_empty_tree_root(depth: Field) -> Field {\n if depth == 0 {\n 0\n } else if depth == 1 {\n 0x27b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed\n } else if depth == 2 {\n 0x21dbfd1d029bf447152fcf89e355c334610d1632436ba170f738107266a71550\n } else if depth == 3 {\n 0x0bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb\n } else if depth == 4 {\n 0x06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d\n } else if depth == 5 {\n 0x03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa0\n } else if depth == 6 {\n 0x15d28cad4c0736decea8997cb324cf0a0e0602f4d74472cd977bce2c8dd9923f\n } else if depth == 7 {\n 0x268ed1e1c94c3a45a14db4108bc306613a1c23fab68e0466a002dfb0a3f8d2ab\n } else if depth == 8 {\n 0x0cd8d5695bc2dde99dd531671f76f1482f14ddba8eeca7cb9686d4a62359c257\n } else if depth == 9 {\n 0x047fbb7eb974155702149e58ea6ad91f4c6e953e693db35e953e250d8ceac9a9\n } else if depth == 10 {\n 0x00c5ae2526e665e2c7c698c11a06098b7159f720606d50e7660deb55758b0b02\n } else {\n assert(false, \"depth should be between 0 and 10\");\n 0\n }\n}\n\n#[test]\nfn test_merkle_root_interop_test() {\n // This is a test to ensure that we match the cpp implementation.\n // You can grep for `TEST_F(root_rollup_tests, noir_interop_test)`\n // to find the test that matches this.\n let root = calculate_subtree([1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]);\n assert(0x17e8bb70a11d0c946345950879484d2f4f9fef397ff6adbfdec3baab2d41faab == root);\n\n let empty_root = calculate_subtree([0; 16]);\n assert(0x06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d == empty_root);\n}\n\n#[test]\nfn test_empty_subroot() {\n assert(calculate_empty_tree_root(0) == 0);\n\n let expected_empty_root_2 = calculate_subtree([0; 2]);\n assert(calculate_empty_tree_root(1) == expected_empty_root_2);\n\n let expected_empty_root_4 = calculate_subtree([0; 4]);\n assert(calculate_empty_tree_root(2) == expected_empty_root_4);\n\n let expected_empty_root_8 = calculate_subtree([0; 8]);\n assert(calculate_empty_tree_root(3) == expected_empty_root_8);\n\n let expected_empty_root_16 = calculate_subtree([0; 16]);\n assert(calculate_empty_tree_root(4) == expected_empty_root_16);\n\n let expected_empty_root_32 = calculate_subtree([0; 32]);\n assert(calculate_empty_tree_root(5) == expected_empty_root_32);\n\n let expected_empty_root_64 = calculate_subtree([0; 64]);\n assert(calculate_empty_tree_root(6) == expected_empty_root_64);\n\n let expected_empty_root_128 = calculate_subtree([0; 128]);\n assert(calculate_empty_tree_root(7) == expected_empty_root_128);\n}\n", "path": "/usr/src/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/merkle_tree.nr" }, "136": { "source": "mod root_rollup_inputs;\nuse root_rollup_inputs::RootRollupInputs;\nmod root_rollup_public_inputs;\nuse root_rollup_public_inputs::RootRollupPublicInputs;\nuse dep::types::{\n abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot,\n constants::{NUM_FIELDS_PER_SHA256, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, L1_TO_L2_MSG_SUBTREE_HEIGHT},\n header::Header, state_reference::StateReference, utils::uint256::U256\n};\nuse crate::components;\nuse crate::merkle_tree::{calculate_subtree, calculate_empty_tree_root};\n\nimpl RootRollupInputs {\n pub fn root_rollup_circuit(self) -> RootRollupPublicInputs {\n let left = self.previous_rollup_data[0].base_or_merge_rollup_public_inputs;\n let right = self.previous_rollup_data[1].base_or_merge_rollup_public_inputs;\n\n let aggregation_object = components::aggregate_proofs(left, right);\n components::assert_both_input_proofs_of_same_rollup_type(left, right);\n let _ = components::assert_both_input_proofs_of_same_height_and_return(left, right);\n components::assert_equal_constants(left, right);\n components::assert_prev_rollups_follow_on_from_each_other(left, right);\n\n // Check correct l1 to l2 tree given\n // Compute subtree inserting l1 to l2 messages\n let l1_to_l2_subtree_root = calculate_subtree(self.new_l1_to_l2_messages);\n\n // Insert subtree into the l1 to l2 data tree\n let empty_l1_to_l2_subtree_root = calculate_empty_tree_root(L1_TO_L2_MSG_SUBTREE_HEIGHT);\n let new_l1_to_l2_message_tree_snapshot = components::insert_subtree_to_snapshot_tree(\n self.start_l1_to_l2_message_tree_snapshot,\n self.new_l1_to_l2_message_tree_root_sibling_path,\n empty_l1_to_l2_subtree_root,\n l1_to_l2_subtree_root,\n // TODO(Kev): For now we can add a test that this fits inside of \n // a u8.\n L1_TO_L2_MSG_SUBTREE_HEIGHT as u8\n );\n\n let state = StateReference { l1_to_l2_message_tree: new_l1_to_l2_message_tree_snapshot, partial: right.end };\n\n let header = Header {\n last_archive: left.constants.last_archive,\n body_hash: components::compute_calldata_hash(self.previous_rollup_data),\n state,\n global_variables: left.constants.global_variables\n };\n\n // Build the block hash for this by hashing the header and then insert the new leaf to archive tree.\n let block_hash = header.hash();\n\n // Update the archive\n let archive = components::insert_subtree_to_snapshot_tree(\n self.start_archive_snapshot,\n self.new_archive_sibling_path,\n 0,\n block_hash,\n 0\n );\n\n RootRollupPublicInputs {\n aggregation_object,\n archive,\n header,\n // TODO(#3938): Nuke this once body hash/calldata hash is updated\n l1_to_l2_messages_hash: compute_messages_hash(self.new_l1_to_l2_messages)\n }\n }\n}\n\n// See `test_message_input_flattened_length` on keeping this in sync,\n// why its here and how this constant was computed.\nglobal NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP_NUM_BYTES = 512;\n\n// Computes the messages hash from the leaves array\n//\n// Returns the hash split into two field elements\nfn compute_messages_hash(leaves: [Field; NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP]) -> [Field; NUM_FIELDS_PER_SHA256] {\n // Slice variation\n // let mut hash_input_flattened = [];\n // for leaf in leaves {\n // let input_as_bytes = leaf.to_be_bytes(32);\n // for i in 0..32 {\n // // TODO(Kev): should check the complexity of repeatedly pushing\n // hash_input_flattened.push(input_as_bytes[i]);\n // }\n // }\n\n // Convert each field element into a byte array and append the bytes to `hash_input_flattened`\n let mut hash_input_flattened = [0; NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP_NUM_BYTES];\n for offset in 0..NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP {\n let input_as_bytes = leaves[offset].to_be_bytes(32);\n for byte_index in 0..32 {\n hash_input_flattened[offset * 32 + byte_index] = input_as_bytes[byte_index];\n }\n }\n\n // Hash bytes and convert to 2 128 bit limbs\n let sha_digest = dep::std::hash::sha256(hash_input_flattened);\n // TODO(Kev): The CPP implementation is returning [high, low]\n // and so is `to_u128_limbs`, so this matches.\n // We should say why we are doing this vs [low, high]\n U256::from_bytes32(sha_digest).to_u128_limbs()\n}\n\n#[test]\nfn test_message_input_flattened_length() {\n // This is here so that the global doesn't become outdated.\n // \n // The short term solution to remove this is to use slices, though\n // those are a bit experimental right now, so TODO I'll add a test that the\n // slice version of compute_messages_hash is the same as the array version.\n // which uses the NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP_NUM_BYTES global.\n assert(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP * 32 == NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP_NUM_BYTES);\n}\n\nmod tests {\n use crate::{\n root::{root_rollup_inputs::RootRollupInputs, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP_NUM_BYTES},\n tests::root_rollup_inputs::default_root_rollup_inputs\n };\n use dep::types::utils::uint256::U256;\n use dep::types::hash::accumulate_sha256;\n\n #[test]\n fn check_block_hashes_empty_blocks() {\n let expected_messages_hash = U256::from_bytes32(dep::std::hash::sha256([0; NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP_NUM_BYTES])).to_u128_limbs();\n\n let expected_calldata_hash = accumulate_sha256(\n [\n U128::from_integer(0),\n U128::from_integer(1),\n U128::from_integer(2),\n U128::from_integer(3)\n ]\n );\n\n let inputs = default_root_rollup_inputs();\n let outputs = inputs.root_rollup_circuit();\n\n // check calldata hash\n assert_eq(outputs.header.body_hash, expected_calldata_hash);\n // Check messages hash\n assert_eq(outputs.l1_to_l2_messages_hash, expected_messages_hash);\n }\n\n #[test]\n fn end_state() {\n let inputs = default_root_rollup_inputs();\n let outputs = inputs.root_rollup_circuit();\n\n assert(\n outputs.header.state.partial.note_hash_tree.eq(inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.end.note_hash_tree)\n );\n\n assert(\n outputs.header.state.partial.nullifier_tree.eq(inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.end.nullifier_tree)\n );\n\n assert(\n outputs.header.state.partial.contract_tree.eq(inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.end.contract_tree)\n );\n\n assert(\n outputs.header.state.partial.public_data_tree.eq(inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.end.public_data_tree)\n );\n }\n}\n", "path": "/usr/src/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/root.nr" }, "146": { "source": "use crate::abis::base_or_merge_rollup_public_inputs::BaseOrMergeRollupPublicInputs;\nuse dep::types::mocked::AggregationObject;\nuse dep::types::hash::{accumulate_sha256, assert_check_membership, root_from_sibling_path};\nuse dep::types::constants::NUM_FIELDS_PER_SHA256;\nuse crate::abis::previous_rollup_data::PreviousRollupData;\nuse dep::types::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot;\n\n/**\n * Create an aggregation object for the proofs that are provided\n * - We add points P0 for each of our proofs\n * - We add points P1 for each of our proofs\n * - We concat our public inputs\n * TODO(Kev): This seems similar to the aggregate_proof method in the private-kernel-lib\n */\npub fn aggregate_proofs(\n left: BaseOrMergeRollupPublicInputs,\n _right: BaseOrMergeRollupPublicInputs\n) -> AggregationObject {\n // TODO: Similar to cpp code this does not do anything.\n left.aggregation_object\n}\n\n/**\n * Asserts that the rollup types are the same. \n * Either both merge or both base\n */\npub fn assert_both_input_proofs_of_same_rollup_type(\n left: BaseOrMergeRollupPublicInputs,\n right: BaseOrMergeRollupPublicInputs\n) {\n assert(left.rollup_type == right.rollup_type, \"input proofs are of different rollup types\");\n}\n\n/**\n * Asserts that the rollup subtree heights are the same and returns the height\n * Returns the height of the rollup subtrees\n */\npub fn assert_both_input_proofs_of_same_height_and_return(\n left: BaseOrMergeRollupPublicInputs,\n right: BaseOrMergeRollupPublicInputs\n) -> Field {\n assert(\n left.height_in_block_tree == right.height_in_block_tree, \"input proofs are of different rollup heights\"\n );\n left.height_in_block_tree\n}\n\n/**\n * Asserts that the constants used in the left and right child are identical\n *\n */\npub fn assert_equal_constants(\n left: BaseOrMergeRollupPublicInputs,\n right: BaseOrMergeRollupPublicInputs\n) {\n assert(left.constants.eq(right.constants), \"input proofs have different constants\");\n}\n\n// asserts that the end snapshot of previous_rollup 0 equals the start snapshot of previous_rollup 1 (i.e. ensure they\n// follow on from one-another). Ensures that right uses the tres that was updated by left.\npub fn assert_prev_rollups_follow_on_from_each_other(\n left: BaseOrMergeRollupPublicInputs,\n right: BaseOrMergeRollupPublicInputs\n) {\n assert(\n left.end.note_hash_tree.eq(right.start.note_hash_tree), \"input proofs have different note hash tree snapshots\"\n );\n assert(\n left.end.nullifier_tree.eq(right.start.nullifier_tree), \"input proofs have different nullifier tree snapshots\"\n );\n assert(\n left.end.contract_tree.eq(right.start.contract_tree), \"input proofs have different contract tree snapshots\"\n );\n assert(\n left.end.public_data_tree.eq(right.start.public_data_tree), \"input proofs have different public data tree snapshots\"\n );\n}\n\n/**\n * @brief From two previous rollup data, compute a single calldata hash\n *\n * @param previous_rollup_data\n * @return calldata hash stored in 2 fields\n */\npub fn compute_calldata_hash(previous_rollup_data: [PreviousRollupData; 2]) -> [Field; NUM_FIELDS_PER_SHA256] {\n accumulate_sha256(\n [\n U128::from_integer(previous_rollup_data[0].base_or_merge_rollup_public_inputs.calldata_hash[0]),\n U128::from_integer(previous_rollup_data[0].base_or_merge_rollup_public_inputs.calldata_hash[1]),\n U128::from_integer(previous_rollup_data[1].base_or_merge_rollup_public_inputs.calldata_hash[0]),\n U128::from_integer(previous_rollup_data[1].base_or_merge_rollup_public_inputs.calldata_hash[1])\n ]\n )\n}\n\npub fn insert_subtree_to_snapshot_tree<N>(\n snapshot: AppendOnlyTreeSnapshot,\n siblingPath: [Field; N],\n emptySubtreeRoot: Field,\n subtreeRootToInsert: Field,\n subtreeDepth: u8\n) -> AppendOnlyTreeSnapshot {\n // TODO(Lasse): Sanity check len of siblingPath > height of subtree\n // TODO(Lasse): Ensure height of subtree is correct (eg 3 for commitments, 1 for contracts)\n let leafIndexAtDepth = snapshot.next_available_leaf_index >> (subtreeDepth as u32);\n\n // Check that the current root is correct and that there is an empty subtree at the insertion location\n assert_check_membership(\n emptySubtreeRoot,\n leafIndexAtDepth as Field,\n siblingPath,\n snapshot.root\n );\n\n // if index of leaf is x, index of its parent is x/2 or x >> 1. We need to find the parent `subtreeDepth` levels up.\n let new_root = root_from_sibling_path(subtreeRootToInsert, leafIndexAtDepth as Field, siblingPath);\n\n // 2^subtreeDepth is the number of leaves added. 2^x = 1 << x\n let new_next_available_leaf_index = (snapshot.next_available_leaf_index as u64) + (1 << (subtreeDepth as u64));\n\n AppendOnlyTreeSnapshot { root: new_root, next_available_leaf_index: new_next_available_leaf_index as u32 }\n}\n", "path": "/usr/src/noir-projects/noir-protocol-circuits/src/crates/rollup-lib/src/components.nr" }, "156": { "source": "use dep::rollup_lib::root::{RootRollupInputs, RootRollupPublicInputs};\n\nfn main(inputs: RootRollupInputs) -> pub RootRollupPublicInputs {\n inputs.root_rollup_circuit()\n}\n", "path": "/usr/src/noir-projects/noir-protocol-circuits/src/crates/rollup-root/src/main.nr" } } }