@aztec/protocol-contracts 0.0.1-commit.2d9cb6034 → 0.0.1-commit.2e20a94
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.
- package/artifacts/AuthRegistry.json +864 -884
- package/artifacts/ContractClassRegistry.json +304 -336
- package/artifacts/ContractInstanceRegistry.json +556 -654
- package/artifacts/FeeJuice.json +488 -710
- package/artifacts/MultiCallEntrypoint.json +664 -578
- package/artifacts/PublicChecks.json +752 -666
- package/dest/protocol_contract_data.js +40 -40
- package/package.json +4 -4
- package/src/protocol_contract_data.ts +39 -39
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"transpiled": true,
|
|
3
|
-
"noir_version": "1.0.0-beta.
|
|
3
|
+
"noir_version": "1.0.0-beta.20+04a373ed8e9cf67ac4f7efea14009f3c3a856d58",
|
|
4
4
|
"name": "ContractInstanceRegistry",
|
|
5
5
|
"functions": [
|
|
6
6
|
{
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
|
-
"bytecode": "
|
|
35
|
-
"debug_symbols": "
|
|
34
|
+
"bytecode": "JwACBAEoAAABBIBEJwAABEQnAgIEACcCAwQAHwoAAgADAEMlAAAAPC0CAkMnAgMEQycCBAQBOw4ABAADHgIAAwknAgQBASQCAAMAAABTJQAAAngeAgADASkCAAQA71JTTScCBQABKwIABgAAAAAAAAAAAwAAAAAAAAAALQgBBycCCAQFAAgBCAEnAwcEAQAiBwIILQoICS0OBAkAIgkCCS0OBQkAIgkCCS0OAwkAIgkCCS0OBgktCAEDJwIEBAUACAEEAScDAwQBACIHAgQAIgMCBT8PAAQABScCBAQBACoDBAUtCwUFJwIDAAAKKgUDBCcCAwEACioEAwYkAgAGAAABCCUAAAKKHgIAAwYeAgAEAC8qAAUABAAGHAoGBQQcCgUEAAIqBgQFLAIABAAtXgmLgro3tDuZoTFhGP0g1C9RZsnp8T+16mWpbR4KbQQqBQQGHAoGBwQcCgcFAAIqBgUHBCoHBAYcCgYIAhwKCAcAHAoHCAIcCggJARwKCQcCJwIIAgAKKgcICRYKCQccCgcKAAIqBgoLLAIABgAwM+okblBuiY6X9XDK/9cEywu0YDE/tyCynhOeXBAAAQQqCwYKHAoKDAQcCgwLAAIqCgsMBCoMBAocCgoMAhwKDAQAHAoEDAIcCgwNARwKDQQCCioECAwWCgwEHAoECAACKgoIDQQqDQYIHAoICgQcCgoGABwKBggFHAoMBgUcCgQKBQQqCggEHAoLCAUcCgkKBRwKBwkFBCoJCAccCgUIBQwqAwgFKQIAAwUAAVGAJAIABQAAAmgjAAACWQQqCgMEACoHBAIjAAACdwQqBgMFACoEBQIjAAACdyYqAQABBU/fSorXz/DTPAQCASYqAQABBbq7IdeCMxhkPAQCASY=",
|
|
35
|
+
"debug_symbols": "rVhbbuM4ELyLvv3BfvGRqwwGgZMoAwOGE3jsBRaB777dtpqyByB3lrM/VrlklYrNYlPW1/Q2v5x/PO8O7x8/p6dvX9PLcbff73487z9et6fdx0HZrynYR9RP2kxRpifeTCncDvl6yDQ9RT3oN9DflHQ7QsAFIDnwU+SnyBl2hp0RcCALMBM3wA7KApLfIi0uIJugGIgLKOBgYTCAA2fAGTAbOipEdOAM2W+ygbgAdoadEWekLMA8IxpQBo1JylBQYFbJTuW0gGIMGTBGa0zEDvRyUofE7MAYNUZiTDJgjN6C7KY34Mz1psVAWUBWhoOBsoDiTLEJhs3EQcvLaMAYNcYsCxDLAhuQBdg0sRgwRo3xNS/JgCwgO5ONUWNcggNj1JiE4ED9SDCgDkX9CBiDBoxRG4LswBi1IVaxG3CGnbGKiToUq9gNOBOdsYqJmhermOTLZTP5sng+HefZVsXdOtHV87k9zofT9HQ47/eb6a/t/nz90c/P7eF6PG2PelbHMR/e9KiC77v9bOiyWa8O7UsB2YZ4vVxxkiohjxrQ1igRYJEokXBVyA8K2HERcnQTEEpVSDA6jtQaR1cjhlUjQmxpSFuDLF1XBV0oQ+PQcKweArY8pH4tqkRZZzTLg0JuK2D2SOl6rdcj4INA6USCglsoxOsgIJXHVHVKUQL7bJRQQlsDetPhEpTvBkK/KHSiqV3bo4mQeUwDyW0gxo4PbmswJJ8TxrDGG/Jv26CSoE5rKk0bvWhB8XwDhdiKFnQkEqJLJN3cVgkeXCPU7lmdhOqGz14NxZFaRrDjJOvGtGhkTrHZ+ToJjbWgCVKrYfzLQJKsAympORDqiGQM2UWyxrUpwr0ujlTbeNBJataj00BLKalqBOCmRuzUVJ/dFo0IuW2jk1JMXg4szT7eH4c9TPg4MDdNdKaWROqCvd8KfrXRn9hYfWTtyq2JpU5G9dlRajUo33Vi+A8adamQzuughtTdNYAMaWgJak1DhEGNuuIIgEY1uGpgGtMASVUjxlGNWDUS/A8aoz5K1UAc9VHCn2vkmjEkHtPQh8eqMVpTzDVjBKM+cs0Y4di6JVozRqMZozUfNFqPB41RH2vG9CFqVCP8ucaaMabB/sFrL+RYxjQS+96gJcUxjXz3X2Gwr+ufDM8YB2j3wt9/DBKA1kYnvV0/1D+AGPjeiGp816/b193x4VXWxcSOu+3Lfl6+vp8Pr3dnT39/+hl/FfZ5/Hid387H2ZTW92H2nugb6L8Z3VK+X+x+/wA="
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
"name": "public_dispatch",
|
|
@@ -52,10 +52,6 @@
|
|
|
52
52
|
],
|
|
53
53
|
"return_type": null,
|
|
54
54
|
"error_types": {
|
|
55
|
-
"361444214588792908": {
|
|
56
|
-
"error_kind": "string",
|
|
57
|
-
"string": "attempt to multiply with overflow"
|
|
58
|
-
},
|
|
59
55
|
"1998584279744703196": {
|
|
60
56
|
"error_kind": "string",
|
|
61
57
|
"string": "attempt to subtract with overflow"
|
|
@@ -68,7 +64,7 @@
|
|
|
68
64
|
"error_kind": "string",
|
|
69
65
|
"string": "New update delay is too low"
|
|
70
66
|
},
|
|
71
|
-
"
|
|
67
|
+
"11194752367584870169": {
|
|
72
68
|
"error_kind": "fmtstring",
|
|
73
69
|
"length": 27,
|
|
74
70
|
"item_types": [
|
|
@@ -99,8 +95,8 @@
|
|
|
99
95
|
}
|
|
100
96
|
}
|
|
101
97
|
},
|
|
102
|
-
"bytecode": "
|
|
103
|
-
"debug_symbols": "
|
|
98
|
+
"bytecode": "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",
|
|
99
|
+
"debug_symbols": "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"
|
|
104
100
|
},
|
|
105
101
|
{
|
|
106
102
|
"name": "publish_for_public_execution",
|
|
@@ -614,7 +610,7 @@
|
|
|
614
610
|
"name": "inner",
|
|
615
611
|
"type": {
|
|
616
612
|
"kind": "struct",
|
|
617
|
-
"path": "
|
|
613
|
+
"path": "aztec::protocol_types::point::Point",
|
|
618
614
|
"fields": [
|
|
619
615
|
{
|
|
620
616
|
"name": "x",
|
|
@@ -650,7 +646,7 @@
|
|
|
650
646
|
"name": "inner",
|
|
651
647
|
"type": {
|
|
652
648
|
"kind": "struct",
|
|
653
|
-
"path": "
|
|
649
|
+
"path": "aztec::protocol_types::point::Point",
|
|
654
650
|
"fields": [
|
|
655
651
|
{
|
|
656
652
|
"name": "x",
|
|
@@ -686,7 +682,7 @@
|
|
|
686
682
|
"name": "inner",
|
|
687
683
|
"type": {
|
|
688
684
|
"kind": "struct",
|
|
689
|
-
"path": "
|
|
685
|
+
"path": "aztec::protocol_types::point::Point",
|
|
690
686
|
"fields": [
|
|
691
687
|
{
|
|
692
688
|
"name": "x",
|
|
@@ -722,7 +718,7 @@
|
|
|
722
718
|
"name": "inner",
|
|
723
719
|
"type": {
|
|
724
720
|
"kind": "struct",
|
|
725
|
-
"path": "
|
|
721
|
+
"path": "aztec::protocol_types::point::Point",
|
|
726
722
|
"fields": [
|
|
727
723
|
{
|
|
728
724
|
"name": "x",
|
|
@@ -1432,7 +1428,7 @@
|
|
|
1432
1428
|
"name": "pk_m",
|
|
1433
1429
|
"type": {
|
|
1434
1430
|
"kind": "struct",
|
|
1435
|
-
"path": "
|
|
1431
|
+
"path": "aztec::protocol_types::point::Point",
|
|
1436
1432
|
"fields": [
|
|
1437
1433
|
{
|
|
1438
1434
|
"name": "x",
|
|
@@ -2068,23 +2064,39 @@
|
|
|
2068
2064
|
"error_kind": "string",
|
|
2069
2065
|
"string": "Point not on curve"
|
|
2070
2066
|
},
|
|
2067
|
+
"1560923443647584783": {
|
|
2068
|
+
"error_kind": "string",
|
|
2069
|
+
"string": "TpkM is the point at infinity"
|
|
2070
|
+
},
|
|
2071
|
+
"1911279422186654533": {
|
|
2072
|
+
"error_kind": "string",
|
|
2073
|
+
"string": "OvpkM is the point at infinity"
|
|
2074
|
+
},
|
|
2071
2075
|
"4135474769840782447": {
|
|
2072
2076
|
"error_kind": "string",
|
|
2073
2077
|
"string": "Point at infinity should have canonical representation (0 0)"
|
|
2074
2078
|
},
|
|
2079
|
+
"7264753475633835214": {
|
|
2080
|
+
"error_kind": "string",
|
|
2081
|
+
"string": "NpkM is the point at infinity"
|
|
2082
|
+
},
|
|
2075
2083
|
"12469291177396340830": {
|
|
2076
2084
|
"error_kind": "string",
|
|
2077
2085
|
"string": "call to assert_max_bit_size"
|
|
2078
2086
|
},
|
|
2087
|
+
"14483585040754951598": {
|
|
2088
|
+
"error_kind": "string",
|
|
2089
|
+
"string": "IvpkM is the point at infinity"
|
|
2090
|
+
},
|
|
2079
2091
|
"14990209321349310352": {
|
|
2080
2092
|
"error_kind": "string",
|
|
2081
2093
|
"string": "attempt to add with overflow"
|
|
2082
2094
|
}
|
|
2083
2095
|
}
|
|
2084
2096
|
},
|
|
2085
|
-
"bytecode": "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",
|
|
2086
|
-
"debug_symbols": "
|
|
2087
|
-
"verification_key": "
|
|
2097
|
+
"bytecode": "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",
|
|
2098
|
+
"debug_symbols": "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",
|
|
2099
|
+
"verification_key": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANsAAAAAAAAAAAAAAAAAAAAQ8H8yTson807GP+1v9Q3oXUAAAAAAAAAAAAAAAAAAAAAACh2D4ncGnzBIIM45//5JgAAAAAAAAAAAAAAAAAAAPNQCLUUDJG6y6PLRJ8NFUUCAAAAAAAAAAAAAAAAAAAAAAAJbZQRIYcnb8+OjdO8yQ0AAAAAAAAAAAAAAAAAAADbr3CkfP5j1U0H1EWax0qRyQAAAAAAAAAAAAAAAAAAAAAAEz/uSX2CG+r8jipdPaFZAAAAAAAAAAAAAAAAAAAAiEeh5BNBH2H66+gv3r04iFkAAAAAAAAAAAAAAAAAAAAAACKGj6XafmA0xwdOEk0F3QAAAAAAAAAAAAAAAAAAAMQlnrX4I4ap4KzET7ziFjlTAAAAAAAAAAAAAAAAAAAAAAAD1pnspO28xYIJbgI7xacAAAAAAAAAAAAAAAAAAAAkpywsBOUWPADbBfHff/ML+wAAAAAAAAAAAAAAAAAAAAAAHe8W1RHybhKtU3m9pUF6AAAAAAAAAAAAAAAAAAAA7H8KaStYGOH5t16yvqqwM1EAAAAAAAAAAAAAAAAAAAAAAAU1uoWRNAzsdHM3T4RxmAAAAAAAAAAAAAAAAAAAAB8xnP9jsKhdEAQsDMY8Kq4xAAAAAAAAAAAAAAAAAAAAAAAcJ1ld3vKLODs10/y2adoAAAAAAAAAAAAAAAAAAACY5xCYgEe3lA9KnnUJxwXBMgAAAAAAAAAAAAAAAAAAAAAALwxpUVAmLEhpkfLsTXRpAAAAAAAAAAAAAAAAAAAABM11Pqt6BN+LjCIPUN3Jfl0AAAAAAAAAAAAAAAAAAAAAABY1re0NYX6Zn4vRp51VRAAAAAAAAAAAAAAAAAAAAKRL2duk+bAUg1IR7sSzjhq3AAAAAAAAAAAAAAAAAAAAAAAZ35/YID7DJGdhdCO8A5kAAAAAAAAAAAAAAAAAAAC7d7aeGw1NOcLTLvLiXepyqwAAAAAAAAAAAAAAAAAAAAAAKebq0r+qfC0F2gGK9MjTAAAAAAAAAAAAAAAAAAAA0keFgXt5FOJa1FRGgAxYVSUAAAAAAAAAAAAAAAAAAAAAACKRtL5tI6UPJuhJdxShmQAAAAAAAAAAAAAAAAAAAJ/tqrZEtOwjVpiZTTg72iwPAAAAAAAAAAAAAAAAAAAAAAAZxnq60zGT9tq/8MzLh3gAAAAAAAAAAAAAAAAAAAAKqkPy4/OpejCszOmQz8W59QAAAAAAAAAAAAAAAAAAAAAAA9i+k7nZPFe1a95MIf/FAAAAAAAAAAAAAAAAAAAA1HlT90lD0eflyvrX/MoNLasAAAAAAAAAAAAAAAAAAAAAAC6eWtz86hE5NuBCecKeUgAAAAAAAAAAAAAAAAAAAKvK26jD3qim0PX2oIPYmOeCAAAAAAAAAAAAAAAAAAAAAAAsOqblCXQP9QEAGFQ+A4MAAAAAAAAAAAAAAAAAAACm6tWMgsgr/vB4YQKcmfk7qQAAAAAAAAAAAAAAAAAAAAAALxGO5hPwkCfNv43TeqQ+AAAAAAAAAAAAAAAAAAAA1fMThxtN0m5hbDHkYHuaHDUAAAAAAAAAAAAAAAAAAAAAACcllYMvgPdig3lnTa8R3AAAAAAAAAAAAAAAAAAAAEMdaCzlKpuOKMgcirI0eyR4AAAAAAAAAAAAAAAAAAAAAAAi5Q2RXim97Y9i66GrQSsAAAAAAAAAAAAAAAAAAADVn9+BZKwLyNd44lET23HAHgAAAAAAAAAAAAAAAAAAAAAADRgjtEuaKy+6URYyBiXFAAAAAAAAAAAAAAAAAAAAW3wdE9Bo6gVRbd4Ixu+cFJIAAAAAAAAAAAAAAAAAAAAAACeMSK7rwS5VwgbX+fF1KQAAAAAAAAAAAAAAAAAAAIp2c9u+EctMUg7PpfSK2laVAAAAAAAAAAAAAAAAAAAAAAASzheMC1uhF4UCYziSNBgAAAAAAAAAAAAAAAAAAAA3D2Ixv/KAgjwOrIW3Yzo5VwAAAAAAAAAAAAAAAAAAAAAACRWsMGDXv+s17tEeWEOSAAAAAAAAAAAAAAAAAAAALi0nFEq+onbcXfJBteYp+oUAAAAAAAAAAAAAAAAAAAAAAB70ycyD+eS2u6Vx0JtHFAAAAAAAAAAAAAAAAAAAANDk+SLQgGV2++AZ3fwj4cbnAAAAAAAAAAAAAAAAAAAAAAAgdC3RsdlGsEtLxvFpiZIAAAAAAAAAAAAAAAAAAAC7NO6eSoEi7YBCGTgwfHmYjgAAAAAAAAAAAAAAAAAAAAAAFomzRgBqVOFZc9dgPMKKAAAAAAAAAAAAAAAAAAAAgoI5EYHGGOzvjphAc4v5bcEAAAAAAAAAAAAAAAAAAAAAAAUEutHLlDROUQdw3FymMQAAAAAAAAAAAAAAAAAAAOPq+W6GFIoXpLeKBUR/RuISAAAAAAAAAAAAAAAAAAAAAAAbzzhIiUluNuG4jkdQ62gAAAAAAAAAAAAAAAAAAAC15jzB57EkwSTcaE80HldiBQAAAAAAAAAAAAAAAAAAAAAAHVMPW3nVfeAKRSwoM7ICAAAAAAAAAAAAAAAAAAAAOWIwQv7JkYSi6hVmGEPNaMsAAAAAAAAAAAAAAAAAAAAAABsFGQyi2Tt3cDJx+7ZOmwAAAAAAAAAAAAAAAAAAAIrszDdwY/e6TEfkVIQU9WHSAAAAAAAAAAAAAAAAAAAAAAASRinrkMLCmHjjQolTKGMAAAAAAAAAAAAAAAAAAABtynrndJeTb6oVre1YTVRzlAAAAAAAAAAAAAAAAAAAAAAAAYFsyq+WU99AfvKQogMuAAAAAAAAAAAAAAAAAAAA12EMowNUgHSUgmqxCGvBPUcAAAAAAAAAAAAAAAAAAAAAABCwTvYcq9zhaII7g5iEMQAAAAAAAAAAAAAAAAAAAFuA4zh3t2aQkxjm2eoNGuIIAAAAAAAAAAAAAAAAAAAAAAAHnd4x+XPzYiccph5y/BoAAAAAAAAAAAAAAAAAAABOrHrvRTNnXypyVhG6aJ49OAAAAAAAAAAAAAAAAAAAAAAAEbR7d6X4PYpZ8m/PlrgbAAAAAAAAAAAAAAAAAAAAAdhtSAMjR7BvH5mu+zhxCA0AAAAAAAAAAAAAAAAAAAAAAAgbvj0tho8UAZWKr4DXuAAAAAAAAAAAAAAAAAAAAA0+Q2BMIvB/xbBRvMGWgTZLAAAAAAAAAAAAAAAAAAAAAAACNeJUAJA2JBvvf0XzFucAAAAAAAAAAAAAAAAAAADGFYdHeZlMf28+Me5Pavj6DAAAAAAAAAAAAAAAAAAAAAAAIdj2tk9mhAsZtf27vFKxAAAAAAAAAAAAAAAAAAAARHNh/yxb8DshlPN0UcT9sPIAAAAAAAAAAAAAAAAAAAAAAAHiyo5fkiqBza0W2fUNygAAAAAAAAAAAAAAAAAAAEHjgc/FNuyEl5qxuB0QAVkiAAAAAAAAAAAAAAAAAAAAAAAL9SwcgaVnSVcOguit3DoAAAAAAAAAAAAAAAAAAADpOO1e5B3hTdHMXe7ZlB5KTgAAAAAAAAAAAAAAAAAAAAAADzndFiUC9efRV2HvuWD3AAAAAAAAAAAAAAAAAAAArWsmTy7p4/GNAKaqtm9xQcsAAAAAAAAAAAAAAAAAAAAAABcN8kK4TCyaUBwm5wY2DwAAAAAAAAAAAAAAAAAAAP5sNJj55fp9B33vrJu3xB1MAAAAAAAAAAAAAAAAAAAAAAAAmiEYJr+UlLrWENEEnCEAAAAAAAAAAAAAAAAAAAAjEIXmI4Np/Evauo4uFlvkIAAAAAAAAAAAAAAAAAAAAAAAGxIf/K+3yKuN6y4fRwZfAAAAAAAAAAAAAAAAAAAAgflfiWpQujsZy0ACyuOCWLUAAAAAAAAAAAAAAAAAAAAAAAi+wYX3T3RiypC+7Bz8eAAAAAAAAAAAAAAAAAAAAJW12Le0pjsF32UrDRDvFG0mAAAAAAAAAAAAAAAAAAAAAAAJnjvVoKAKt/4YBAEFubMAAAAAAAAAAAAAAAAAAAAhKa86Y39aYioyRA+GDR4qfwAAAAAAAAAAAAAAAAAAAAAAABW40lFdduLM7Jnc0ZRZAAAAAAAAAAAAAAAAAAAAIiuIgQjcJdGqRQ4LS8ISw34AAAAAAAAAAAAAAAAAAAAAABuRdReSC609i8AclZUJKgAAAAAAAAAAAAAAAAAAAEghQcfr5CAAodWMy3Q4H20ZAAAAAAAAAAAAAAAAAAAAAAAwXomSsUju2yLm6ZIHeoQAAAAAAAAAAAAAAAAAAAB8hoR2GGgdwp2Kk2OrfEDhwwAAAAAAAAAAAAAAAAAAAAAAFkZaXMu1UM0sY71YEW/kAAAAAAAAAAAAAAAAAAAAQ5lzrBLXynltb+mMpA5sprcAAAAAAAAAAAAAAAAAAAAAAC4k1CD7+VCO0x3mkttHewAAAAAAAAAAAAAAAAAAACjt0afkbIQNnJQ/30VSHGTOAAAAAAAAAAAAAAAAAAAAAAAEPQY7Ewrfs3NCr0XQFVoAAAAAAAAAAAAAAAAAAACTMJUq50xXPRaG2ctKAHM4VAAAAAAAAAAAAAAAAAAAAAAAJhUixAiTMGRq/5ZzYZSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACr5SgxcX07zJq6m2F4V9ZfOgAAAAAAAAAAAAAAAAAAAAAAHN/aEofJaCXp/AS9V3HrAAAAAAAAAAAAAAAAAAAA9Y6K+9ulXRbmXI5q4GiEO9AAAAAAAAAAAAAAAAAAAAAAAB7Jw2cOf5xQXb6hv3Q8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF6UyFPM7GtAJ5GGyaZJyGb4AAAAAAAAAAAAAAAAAAAAAABQQfUvkU8gEqOKRhpGbPgAAAAAAAAAAAAAAAAAAAJKHn2GoKCaTAlYbtX87FVfPAAAAAAAAAAAAAAAAAAAAAAAoRQUJTjXTtVikNALK2uI="
|
|
2088
2100
|
},
|
|
2089
2101
|
{
|
|
2090
2102
|
"name": "set_update_delay",
|
|
@@ -2106,10 +2118,6 @@
|
|
|
2106
2118
|
],
|
|
2107
2119
|
"return_type": null,
|
|
2108
2120
|
"error_types": {
|
|
2109
|
-
"361444214588792908": {
|
|
2110
|
-
"error_kind": "string",
|
|
2111
|
-
"string": "attempt to multiply with overflow"
|
|
2112
|
-
},
|
|
2113
2121
|
"1998584279744703196": {
|
|
2114
2122
|
"error_kind": "string",
|
|
2115
2123
|
"string": "attempt to subtract with overflow"
|
|
@@ -2136,8 +2144,8 @@
|
|
|
2136
2144
|
}
|
|
2137
2145
|
}
|
|
2138
2146
|
},
|
|
2139
|
-
"bytecode": "
|
|
2140
|
-
"debug_symbols": "
|
|
2147
|
+
"bytecode": "JwACBAEoAAABBIBJJwAABEklAAAARicCAwQBJwIEBAAfCgADAAQASBwASEgFLQhIAiUAAACCJwICBEknAgMEADsOAAMAAigAAEMFAlgsAABEADBkTnLhMaApuFBFtoGBWF0oM+hIeblwkUPh9ZPwAAAAJwBFAQEnAEYEAScARwABJh4CAAQBCiIERAUWCgUGHAoGBwAEKgcEBicCBAEACioFBAckAgAHAAAAtScCCAQAPAYIAR4CAAUAKQIABwADbVJ/KwIACAAAAAAAAAAAAwAAAAAAAAAALQgBCScCCgQFAAgBCgEnAwkEAQAiCQIKLQoKCy0OBwsAIgsCCy0OBQsAIgsCCy0OBgsAIgsCCy0OCAstCAEFJwIHBAUACAEHAScDBQQBACIJAgcAIgUCCj8PAAcACgAiBUYHLQsHBzMKAAcABSQCAAUAAAFSJQAABYAMIgJDBQoqBQQHJAIABwAAAWklAAAFkikCAAUA71JTTS0IAQcnAgkEBQAIAQkBJwMHBAEAIgcCCS0KCQotDgUKACIKAgotDEcKACIKAgotDgYKACIKAgotDggKLQgBBScCBgQFAAgBBgEnAwUEAQAiBwIGACIFAgk/DwAGAAkAIgVGBi0LBgYnAgUAAAoqBgUHCioHBAUkAgAFAAAB9SUAAAWkHgIABAAvKgAGAAQABRwKBQcEHAoHBAACKgUEBywCAAQALV4Ji4K6N7Q7maExYRj9INQvUWbJ6fE/teplqW0eCm0EKgcEBRwKBQkEHAoJBwACKgUHCQQqCQQFHAoFCgIcCgoJABwKCQoCHAoKCwEcCgsJAicCCgIACioJCgsWCgsJHAoJDAACKgUMDSwCAAUAMDPqJG5QbomOl/Vwyv/XBMsLtGAxP7cgsp4TnlwQAAEEKg0FDBwKDA4EHAoODQACKgwNDgQqDgQMHAoMDgIcCg4EABwKBA4CHAoODwEcCg8EAgoqBAoOFgoOBBwKBAoAAioMCg8EKg8FChwKCgwEHAoMBQAcCgUKBRwKDgUFHAoEDAUEKgwKBBwKDQoFHAoLDAUcCgkLBQQqCwoJHAoHCgUeAgAHBgwqBwoLKQIACgUAAVGAJAIACwAAA1UjAAADRgQqDAoEACoJBAMjAAADZAQqBQoJACoECQMjAAADZAwqAwIFJAIABQAAA5IjAAADdgIqAwIEDioCAwUkAgAFAAADjSUAAAW2IwAAA6AnAgUFAC0KBQQjAAADoAAqBwQFDioHBQkkAgAJAAADtyUAAAXIHgIABAAvKgAGAAQABwAiBkcEHgIACQAvKgAEAAkACicCCQACACoGCQseAgAMAC8qAAsADAANHAoHDgQcCg4MABwKBQcAJwIFACAnAg8EEC0IABAtCgkSLQoFEwAIAA8AJQAABdotAgAALQoSDgQqBw4FACoMBQcnAgUAQCcCDgQPLQgADy0KCREtCgUSAAgADgAlAAAF2i0CAAAtChEMACoHDAUcCgIHACcCAgBIJwIOBA8tCAAPLQoJES0KAhIACAAOACUAAAXaLQIAAC0KEQwEKgcMAgAqBQIHJwICAGgnAgwEDi0IAA4tCgkQLQoCEQAIAAwAJQAABdotAgAALQoQBQAqBwUCHAoDBQAnAgMAcCcCDAQOLQgADi0KCRAtCgMRAAgADAAlAAAF2i0CAAAtChAHBCoFBwMAKgIDBS0IAQInAgMEBQAIAQMBJwMCBAEAIgICAy0KAwctDgUHACIHAgctDgoHACIHAgctDg0HACIHAgctDggHLQgBAycCBwQFAAgBBwEnAwMEAQAiAgIHACIDAgg/DwAHAAgAIgNGAi0LAgIwCgAFAAYwCgAKAAQwCgANAAsnAgMAAwAqBgMEMAoAAgAEJioBAAEF1RJ9KcLS6O08BAIBJioBAAEFXm0/LtzNhwk8BAIBJioBAAEFursh14IzGGQ8BAIBJioBAAEFG7xl0D/c6tw8BAIBJioBAAEF0Afr9MvGZ5A8BAIBJicCBwQCJwIIAQEtCAEGJwIJBCEACAEJAScDBgQBACIGAgknAgoEIEMDqgADAAcACgAIAAktAgkDLQIKBCUAAAaxJwIDBCEnAgcEIC0IRgQtCEcFIwAABjIMKgQDCCQCAAgAAAZJIwAABkQtCgUCJgQqBQUIAioHBAkOKgQHCiQCAAoAAAZlJQAABbYMKgkHCiQCAAoAAAZ3JQAABuwAIgYCCwAqCwkKLQsKChwKCgkABCoIAgoEKgkKCwIoRwkKBCoKCAkAKgsJBQAiBEYILQoIBCMAAAYyLQADBwAAAwQIAgAIAggjAAAG3i0BBwUtAQgGLQQGBy0EBQgAAAcCBwIACAIIDAAHCAkkAAAJAAAGxCYqAQABBeQIUEUCtYwfPAQCASY=",
|
|
2148
|
+
"debug_symbols": "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"
|
|
2141
2149
|
},
|
|
2142
2150
|
{
|
|
2143
2151
|
"name": "update",
|
|
@@ -2166,10 +2174,6 @@
|
|
|
2166
2174
|
],
|
|
2167
2175
|
"return_type": null,
|
|
2168
2176
|
"error_types": {
|
|
2169
|
-
"361444214588792908": {
|
|
2170
|
-
"error_kind": "string",
|
|
2171
|
-
"string": "attempt to multiply with overflow"
|
|
2172
|
-
},
|
|
2173
2177
|
"1998584279744703196": {
|
|
2174
2178
|
"error_kind": "string",
|
|
2175
2179
|
"string": "attempt to subtract with overflow"
|
|
@@ -2196,8 +2200,8 @@
|
|
|
2196
2200
|
}
|
|
2197
2201
|
}
|
|
2198
2202
|
},
|
|
2199
|
-
"bytecode": "
|
|
2200
|
-
"debug_symbols": "
|
|
2203
|
+
"bytecode": "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",
|
|
2204
|
+
"debug_symbols": "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"
|
|
2201
2205
|
}
|
|
2202
2206
|
],
|
|
2203
2207
|
"outputs": {
|
|
@@ -2294,7 +2298,7 @@
|
|
|
2294
2298
|
}
|
|
2295
2299
|
],
|
|
2296
2300
|
"kind": "struct",
|
|
2297
|
-
"path": "
|
|
2301
|
+
"path": "aztec::protocol_types::point::Point"
|
|
2298
2302
|
}
|
|
2299
2303
|
}
|
|
2300
2304
|
],
|
|
@@ -2330,7 +2334,7 @@
|
|
|
2330
2334
|
}
|
|
2331
2335
|
],
|
|
2332
2336
|
"kind": "struct",
|
|
2333
|
-
"path": "
|
|
2337
|
+
"path": "aztec::protocol_types::point::Point"
|
|
2334
2338
|
}
|
|
2335
2339
|
}
|
|
2336
2340
|
],
|
|
@@ -2366,7 +2370,7 @@
|
|
|
2366
2370
|
}
|
|
2367
2371
|
],
|
|
2368
2372
|
"kind": "struct",
|
|
2369
|
-
"path": "
|
|
2373
|
+
"path": "aztec::protocol_types::point::Point"
|
|
2370
2374
|
}
|
|
2371
2375
|
}
|
|
2372
2376
|
],
|
|
@@ -2402,7 +2406,7 @@
|
|
|
2402
2406
|
}
|
|
2403
2407
|
],
|
|
2404
2408
|
"kind": "struct",
|
|
2405
|
-
"path": "
|
|
2409
|
+
"path": "aztec::protocol_types::point::Point"
|
|
2406
2410
|
}
|
|
2407
2411
|
}
|
|
2408
2412
|
],
|
|
@@ -2588,7 +2592,7 @@
|
|
|
2588
2592
|
}
|
|
2589
2593
|
],
|
|
2590
2594
|
"kind": "struct",
|
|
2591
|
-
"path": "
|
|
2595
|
+
"path": "aztec::protocol_types::point::Point"
|
|
2592
2596
|
}
|
|
2593
2597
|
}
|
|
2594
2598
|
],
|
|
@@ -2624,7 +2628,7 @@
|
|
|
2624
2628
|
}
|
|
2625
2629
|
],
|
|
2626
2630
|
"kind": "struct",
|
|
2627
|
-
"path": "
|
|
2631
|
+
"path": "aztec::protocol_types::point::Point"
|
|
2628
2632
|
}
|
|
2629
2633
|
}
|
|
2630
2634
|
],
|
|
@@ -2660,7 +2664,7 @@
|
|
|
2660
2664
|
}
|
|
2661
2665
|
],
|
|
2662
2666
|
"kind": "struct",
|
|
2663
|
-
"path": "
|
|
2667
|
+
"path": "aztec::protocol_types::point::Point"
|
|
2664
2668
|
}
|
|
2665
2669
|
}
|
|
2666
2670
|
],
|
|
@@ -2696,7 +2700,7 @@
|
|
|
2696
2700
|
}
|
|
2697
2701
|
],
|
|
2698
2702
|
"kind": "struct",
|
|
2699
|
-
"path": "
|
|
2703
|
+
"path": "aztec::protocol_types::point::Point"
|
|
2700
2704
|
}
|
|
2701
2705
|
}
|
|
2702
2706
|
],
|
|
@@ -2799,181 +2803,177 @@
|
|
|
2799
2803
|
"function_locations": [
|
|
2800
2804
|
{
|
|
2801
2805
|
"name": "<impl Empty for AztecAddress>::empty",
|
|
2802
|
-
"start":
|
|
2806
|
+
"start": 842
|
|
2803
2807
|
},
|
|
2804
2808
|
{
|
|
2805
2809
|
"name": "<impl ToField for AztecAddress>::to_field",
|
|
2806
|
-
"start":
|
|
2810
|
+
"start": 942
|
|
2807
2811
|
},
|
|
2808
2812
|
{
|
|
2809
2813
|
"name": "<impl FromField for AztecAddress>::from_field",
|
|
2810
|
-
"start":
|
|
2814
|
+
"start": 1054
|
|
2811
2815
|
},
|
|
2812
2816
|
{
|
|
2813
2817
|
"name": "AztecAddress::zero",
|
|
2814
|
-
"start":
|
|
2818
|
+
"start": 1149
|
|
2815
2819
|
},
|
|
2816
2820
|
{
|
|
2817
2821
|
"name": "AztecAddress::is_valid",
|
|
2818
|
-
"start":
|
|
2822
|
+
"start": 1479
|
|
2819
2823
|
},
|
|
2820
2824
|
{
|
|
2821
2825
|
"name": "AztecAddress::to_address_point",
|
|
2822
|
-
"start":
|
|
2826
|
+
"start": 1854
|
|
2823
2827
|
},
|
|
2824
2828
|
{
|
|
2825
2829
|
"name": "AztecAddress::is_positive",
|
|
2826
|
-
"start":
|
|
2830
|
+
"start": 2507
|
|
2827
2831
|
},
|
|
2828
2832
|
{
|
|
2829
2833
|
"name": "AztecAddress::get_y",
|
|
2830
|
-
"start":
|
|
2834
|
+
"start": 3363
|
|
2831
2835
|
},
|
|
2832
2836
|
{
|
|
2833
2837
|
"name": "AztecAddress::compute",
|
|
2834
|
-
"start":
|
|
2838
|
+
"start": 3749
|
|
2835
2839
|
},
|
|
2836
2840
|
{
|
|
2837
2841
|
"name": "AztecAddress::compute_from_class_id",
|
|
2838
|
-
"start":
|
|
2842
|
+
"start": 7971
|
|
2839
2843
|
},
|
|
2840
2844
|
{
|
|
2841
2845
|
"name": "AztecAddress::is_zero",
|
|
2842
|
-
"start":
|
|
2846
|
+
"start": 8243
|
|
2843
2847
|
},
|
|
2844
2848
|
{
|
|
2845
2849
|
"name": "AztecAddress::assert_is_zero",
|
|
2846
|
-
"start":
|
|
2850
|
+
"start": 8308
|
|
2847
2851
|
},
|
|
2848
2852
|
{
|
|
2849
2853
|
"name": "check_max_field_value",
|
|
2850
|
-
"start":
|
|
2854
|
+
"start": 8392
|
|
2851
2855
|
},
|
|
2852
2856
|
{
|
|
2853
2857
|
"name": "check_is_positive",
|
|
2854
|
-
"start":
|
|
2858
|
+
"start": 8503
|
|
2855
2859
|
},
|
|
2856
2860
|
{
|
|
2857
2861
|
"name": "check_embedded_curve_point_add",
|
|
2858
|
-
"start":
|
|
2862
|
+
"start": 9024
|
|
2859
2863
|
},
|
|
2860
2864
|
{
|
|
2861
2865
|
"name": "check_embedded_curve_point_add_2",
|
|
2862
|
-
"start":
|
|
2866
|
+
"start": 9441
|
|
2863
2867
|
},
|
|
2864
2868
|
{
|
|
2865
2869
|
"name": "compute_address_from_partial_and_pub_keys",
|
|
2866
|
-
"start":
|
|
2870
|
+
"start": 9670
|
|
2867
2871
|
},
|
|
2868
2872
|
{
|
|
2869
2873
|
"name": "compute_preaddress_from_partial_and_pub_keys",
|
|
2870
|
-
"start":
|
|
2874
|
+
"start": 11501
|
|
2871
2875
|
},
|
|
2872
2876
|
{
|
|
2873
2877
|
"name": "from_field_to_field",
|
|
2874
|
-
"start":
|
|
2878
|
+
"start": 11850
|
|
2875
2879
|
},
|
|
2876
2880
|
{
|
|
2877
2881
|
"name": "serde",
|
|
2878
|
-
"start":
|
|
2882
|
+
"start": 11987
|
|
2879
2883
|
},
|
|
2880
2884
|
{
|
|
2881
2885
|
"name": "to_address_point_valid",
|
|
2882
|
-
"start":
|
|
2886
|
+
"start": 12393
|
|
2883
2887
|
},
|
|
2884
2888
|
{
|
|
2885
2889
|
"name": "to_address_point_invalid",
|
|
2886
|
-
"start":
|
|
2890
|
+
"start": 13057
|
|
2887
2891
|
}
|
|
2888
2892
|
],
|
|
2889
2893
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/address/aztec_address.nr",
|
|
2890
|
-
"source": "use crate::{\n address::{\n partial_address::PartialAddress, salted_initialization_hash::SaltedInitializationHash,\n },\n constants::{AZTEC_ADDRESS_LENGTH, DOM_SEP__CONTRACT_ADDRESS_V1, MAX_FIELD_VALUE},\n contract_class_id::ContractClassId,\n hash::poseidon2_hash_with_separator,\n public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, ToPoint, TpkM},\n traits::{Deserialize, Empty, FromField, Packable, Serialize, ToField},\n utils::field::sqrt,\n};\n\n// We do below because `use crate::point::Point;` does not work\nuse std::embedded_curve_ops::EmbeddedCurvePoint as Point;\n\nuse crate::public_keys::AddressPoint;\nuse std::{\n embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key},\n ops::Add,\n};\nuse std::meta::derive;\n\n// Aztec address\n#[derive(Deserialize, Eq, Packable, Serialize)]\npub struct AztecAddress {\n pub inner: Field,\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self { inner: 0 }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl FromField for AztecAddress {\n fn from_field(value: Field) -> AztecAddress {\n AztecAddress { inner: value }\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n /// Returns `true` if the address is valid.\n ///\n /// An invalid address is one that can be proven to not be correctly derived, meaning it contains no contract code,\n /// public keys, etc., and can therefore not receive messages nor execute calls.\n pub fn is_valid(self) -> bool {\n self.get_y().is_some()\n }\n\n /// Returns an address's [`AddressPoint`].\n ///\n /// This can be used to create shared secrets with the owner of the address. If the address is invalid (see\n /// [`AztecAddress::is_valid`]) then this returns `Option::none()`, and no shared secrets can be created.\n pub fn to_address_point(self) -> Option<AddressPoint> {\n self.get_y().map(|y| {\n // If we get a negative y coordinate (y > (r - 1) / 2), we swap it to the\n // positive one (where y <= (r - 1) / 2) by negating it.\n let final_y = if Self::is_positive(y) { y } else { -y };\n\n AddressPoint { inner: Point { x: self.inner, y: final_y, is_infinite: false } }\n })\n }\n\n /// Determines whether a y-coordinate is in the lower (positive) or upper (negative) \"half\" of the field.\n /// I.e.\n /// y <= (r - 1)/2 => positive.\n /// y > (r - 1)/2 => negative.\n /// An AddressPoint always uses the \"positive\" y.\n fn is_positive(y: Field) -> bool {\n // Note: The field modulus r is MAX_FIELD_VALUE + 1.\n let MID = MAX_FIELD_VALUE / 2; // (r - 1) / 2\n let MID_PLUS_1 = MID + 1; // (r - 1)/2 + 1\n // Note: y <= m implies y < m + 1.\n y.lt(MID_PLUS_1)\n }\n\n /// Returns one of the two possible y-coordinates.\n ///\n /// Not all `AztecAddresses` are valid, in which case there is no corresponding y-coordinate. This returns\n /// `Option::none()` for invalid addresses.\n ///\n /// An `AztecAddress` is defined by an x-coordinate, for which two y-coordinates exist as solutions to the curve\n /// equation. This function returns either of them. Note that an [`AddressPoint`] must **always** have a positive\n /// y-coordinate - if trying to obtain the underlying point use [`AztecAddress::to_address_point`] instead.\n fn get_y(self) -> Option<Field> {\n // We compute the address point by taking our address as x, and then solving for y in the\n // equation which defines the grumpkin curve:\n // y^2 = x^3 - 17; x = address\n let x = self.inner;\n let y_squared = x * x * x - 17;\n\n sqrt(y_squared)\n }\n\n pub fn compute(public_keys: PublicKeys, partial_address: PartialAddress) -> AztecAddress {\n //\n // address = address_point.x\n // |\n // address_point = pre_address * G + Ivpk_m (always choose \"positive\" y-coord)\n // | ^\n // | |.....................\n // pre_address .\n // / \\ .\n // / \\ .\n // partial_address public_keys_hash .\n // / \\ / / \\ \\ .\n // / \\ Npk_m Ivpk_m Ovpk_m Tpk_m .\n // contract_class_id \\ |...................\n // / | \\ \\\n // artifact_hash | public_bytecode_commitment salted_initialization_hash\n // | / / \\\n // private_function_tree_root deployer_address salt initialization_hash\n // / \\ / \\\n // ... ... constructor_fn_selector constructor_args_hash\n // / \\\n // / \\ / \\\n // leaf leaf leaf leaf\n // ^\n // |\n // |---h(function_selector, vk_hash)\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // Each of these represents a private function of the contract.\n\n let public_keys_hash = public_keys.hash();\n\n let pre_address = poseidon2_hash_with_separator(\n [public_keys_hash.to_field(), partial_address.to_field()],\n DOM_SEP__CONTRACT_ADDRESS_V1,\n );\n\n // Note: `.add()` will fail within the blackbox fn if either of the points are not on the curve. (See tests below).\n let address_point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address)).add(\n public_keys.ivpk_m.to_point(),\n );\n\n // Note that our address is only the x-coordinate of the full address_point. This is okay because when people want to encrypt something and send it to us\n // they can recover our full point using the x-coordinate (our address itself). To do this, they recompute the y-coordinate according to the equation y^2 = x^3 - 17.\n // When they do this, they may get a positive y-coordinate (a value that is less than or equal to MAX_FIELD_VALUE / 2) or\n // a negative y-coordinate (a value that is more than MAX_FIELD_VALUE), and we cannot dictate which one they get and hence the recovered point may sometimes be different than the one\n // our secret can decrypt. Regardless though, they should and will always encrypt using point with the positive y-coordinate by convention.\n // This ensures that everyone encrypts to the same point given an arbitrary x-coordinate (address). This is allowed because even though our original point may not have a positive y-coordinate,\n // with our original secret, we will be able to derive the secret to the point with the flipped (and now positive) y-coordinate that everyone encrypts to.\n AztecAddress::from_field(address_point.x)\n }\n\n pub fn compute_from_class_id(\n contract_class_id: ContractClassId,\n salted_initialization_hash: SaltedInitializationHash,\n public_keys: PublicKeys,\n ) -> Self {\n let partial_address = PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n salted_initialization_hash,\n );\n\n AztecAddress::compute(public_keys, partial_address)\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n#[test]\nfn check_max_field_value() {\n // Check that it is indeed r-1.\n assert_eq(MAX_FIELD_VALUE + 1, 0);\n}\n\n#[test]\nfn check_is_positive() {\n assert(AztecAddress::is_positive(0));\n assert(AztecAddress::is_positive(1));\n assert(!AztecAddress::is_positive(-1));\n assert(AztecAddress::is_positive(MAX_FIELD_VALUE / 2));\n assert(!AztecAddress::is_positive((MAX_FIELD_VALUE / 2) + 1));\n}\n\n// Gives us confidence that we don't need to manually check that the input public keys need to be on the curve for `add`,\n// because the blackbox function does this check for us.\n#[test(should_fail_with = \"is not on curve\")]\nfn check_embedded_curve_point_add() {\n // Choose a point not on the curve:\n let p1 = Point { x: 1, y: 1, is_infinite: false };\n let p2 = Point::generator();\n let _ = p1 + p2;\n}\n\n// Gives us confidence that we don't need to manually check that the input public keys need to be on the curve for `add`,\n// because the blackbox function does this check for us.\n#[test(should_fail_with = \"is not on curve\")]\nfn check_embedded_curve_point_add_2() {\n // Choose a point not on the curve in the 2nd position.\n let p1 = Point::generator();\n let p2 = Point { x: 1, y: 1, is_infinite: false };\n let _ = p1 + p2;\n}\n\n#[test]\nfn compute_address_from_partial_and_pub_keys() {\n let public_keys = PublicKeys {\n npk_m: NpkM {\n inner: Point {\n x: 0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab,\n y: 0x0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7,\n is_infinite: false,\n },\n },\n ivpk_m: IvpkM {\n inner: Point {\n x: 0x111223493147f6785514b1c195bb37a2589f22a6596d30bb2bb145fdc9ca8f1e,\n y: 0x273bbffd678edce8fe30e0deafc4f66d58357c06fd4a820285294b9746c3be95,\n is_infinite: false,\n },\n },\n ovpk_m: OvpkM {\n inner: Point {\n x: 0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c484,\n y: 0x0c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b,\n is_infinite: false,\n },\n },\n tpk_m: TpkM {\n inner: Point {\n x: 0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a762,\n y: 0x2f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a,\n is_infinite: false,\n },\n },\n };\n\n let partial_address = PartialAddress::from_field(\n 0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de,\n );\n\n let address = AztecAddress::compute(public_keys, partial_address);\n\n // The following value was generated by `derivation.test.ts`.\n // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data.\n let expected_computed_address_from_partial_and_pubkeys =\n 0x2f66081d4bb077fbe8e8abe96a3516a713a3d7e34360b4e985da0da95092b37d;\n assert(address.to_field() == expected_computed_address_from_partial_and_pubkeys);\n}\n\n#[test]\nfn compute_preaddress_from_partial_and_pub_keys() {\n let pre_address = poseidon2_hash_with_separator([1, 2], DOM_SEP__CONTRACT_ADDRESS_V1);\n let expected_computed_preaddress_from_partial_and_pubkey =\n 0x286c7755f2924b1e53b00bcaf1adaffe7287bd74bba7a02f4ab867e3892d28da;\n assert(pre_address == expected_computed_preaddress_from_partial_and_pubkey);\n}\n\n#[test]\nfn from_field_to_field() {\n let address = AztecAddress { inner: 37 };\n assert_eq(FromField::from_field(address.to_field()), address);\n}\n\n#[test]\nfn serde() {\n let address = AztecAddress { inner: 37 };\n // We use the AZTEC_ADDRESS_LENGTH constant to ensure that there is a match between the derived trait\n // implementation and the constant.\n let serialized: [Field; AZTEC_ADDRESS_LENGTH] = address.serialize();\n let deserialized = AztecAddress::deserialize(serialized);\n assert_eq(address, deserialized);\n}\n\n#[test]\nfn to_address_point_valid() {\n // x = 8 where x^3 - 17 = 512 - 17 = 495, which is a residue in this field\n let address = AztecAddress { inner: 8 };\n\n assert(address.get_y().is_some()); // We don't bother checking the result of get_y as it is only used internally\n assert(address.is_valid());\n\n let maybe_point = address.to_address_point();\n assert(maybe_point.is_some());\n\n let point = maybe_point.unwrap().inner;\n // check that x is preserved\n assert_eq(point.x, Field::from(8));\n\n // check that the curve equation holds: y^2 == x^3 - 17\n assert_eq(point.y * point.y, point.x * point.x * point.x - 17);\n}\n\n#[test]\nunconstrained fn to_address_point_invalid() {\n // x = 3 where x^3 - 17 = 27 - 17 = 10, which is a non-residue in this field\n let address = AztecAddress { inner: 3 };\n\n assert(address.get_y().is_none());\n assert(!address.is_valid());\n\n assert(address.to_address_point().is_none());\n}\n"
|
|
2894
|
+
"source": "use crate::{\n address::{\n partial_address::PartialAddress, salted_initialization_hash::SaltedInitializationHash,\n },\n constants::{AZTEC_ADDRESS_LENGTH, DOM_SEP__CONTRACT_ADDRESS_V1, MAX_FIELD_VALUE},\n contract_class_id::ContractClassId,\n hash::poseidon2_hash_with_separator,\n public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, ToPoint, TpkM},\n traits::{Deserialize, Empty, FromField, Packable, Serialize, ToField},\n utils::field::sqrt,\n};\n\nuse crate::point::Point;\n\nuse crate::public_keys::AddressPoint;\nuse std::{\n embedded_curve_ops::{EmbeddedCurveScalar, fixed_base_scalar_mul as derive_public_key},\n ops::Add,\n};\nuse std::meta::derive;\n\n// Aztec address\n#[derive(Deserialize, Eq, Packable, Serialize)]\npub struct AztecAddress {\n pub inner: Field,\n}\n\nimpl Empty for AztecAddress {\n fn empty() -> Self {\n Self { inner: 0 }\n }\n}\n\nimpl ToField for AztecAddress {\n fn to_field(self) -> Field {\n self.inner\n }\n}\n\nimpl FromField for AztecAddress {\n fn from_field(value: Field) -> AztecAddress {\n AztecAddress { inner: value }\n }\n}\n\nimpl AztecAddress {\n pub fn zero() -> Self {\n Self { inner: 0 }\n }\n\n /// Returns `true` if the address is valid.\n ///\n /// An invalid address is one that can be proven to not be correctly derived, meaning it contains no contract code,\n /// public keys, etc., and can therefore not receive messages nor execute calls.\n pub fn is_valid(self) -> bool {\n self.get_y().is_some()\n }\n\n /// Returns an address's [`AddressPoint`].\n ///\n /// This can be used to create shared secrets with the owner of the address. If the address is invalid (see\n /// [`AztecAddress::is_valid`]) then this returns `Option::none()`, and no shared secrets can be created.\n pub fn to_address_point(self) -> Option<AddressPoint> {\n self.get_y().map(|y| {\n // If we get a negative y coordinate (y > (r - 1) / 2), we swap it to the\n // positive one (where y <= (r - 1) / 2) by negating it.\n let final_y = if Self::is_positive(y) { y } else { -y };\n\n AddressPoint { inner: Point { x: self.inner, y: final_y, is_infinite: false } }\n })\n }\n\n /// Determines whether a y-coordinate is in the lower (positive) or upper (negative) \"half\" of the field.\n /// I.e.\n /// y <= (r - 1)/2 => positive.\n /// y > (r - 1)/2 => negative.\n /// An AddressPoint always uses the \"positive\" y.\n fn is_positive(y: Field) -> bool {\n // Note: The field modulus r is MAX_FIELD_VALUE + 1.\n let MID = MAX_FIELD_VALUE / 2; // (r - 1) / 2\n let MID_PLUS_1 = MID + 1; // (r - 1)/2 + 1\n // Note: y <= m implies y < m + 1.\n y.lt(MID_PLUS_1)\n }\n\n /// Returns one of the two possible y-coordinates.\n ///\n /// Not all `AztecAddresses` are valid, in which case there is no corresponding y-coordinate. This returns\n /// `Option::none()` for invalid addresses.\n ///\n /// An `AztecAddress` is defined by an x-coordinate, for which two y-coordinates exist as solutions to the curve\n /// equation. This function returns either of them. Note that an [`AddressPoint`] must **always** have a positive\n /// y-coordinate - if trying to obtain the underlying point use [`AztecAddress::to_address_point`] instead.\n fn get_y(self) -> Option<Field> {\n // We compute the address point by taking our address as x, and then solving for y in the\n // equation which defines the grumpkin curve:\n // y^2 = x^3 - 17; x = address\n let x = self.inner;\n let y_squared = x * x * x - 17;\n\n sqrt(y_squared)\n }\n\n pub fn compute(public_keys: PublicKeys, partial_address: PartialAddress) -> AztecAddress {\n //\n // address = address_point.x\n // |\n // address_point = pre_address * G + Ivpk_m (always choose \"positive\" y-coord)\n // | ^\n // | |.....................\n // pre_address .\n // / \\ .\n // / \\ .\n // partial_address public_keys_hash .\n // / \\ / / \\ \\ .\n // / \\ Npk_m Ivpk_m Ovpk_m Tpk_m .\n // contract_class_id \\ |...................\n // / | \\ \\\n // artifact_hash | public_bytecode_commitment salted_initialization_hash\n // | / / \\\n // private_function_tree_root deployer_address salt initialization_hash\n // / \\ / \\\n // ... ... constructor_fn_selector constructor_args_hash\n // / \\\n // / \\ / \\\n // leaf leaf leaf leaf\n // ^\n // |\n // |---h(function_selector, vk_hash)\n // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n // Each of these represents a private function of the contract.\n\n let public_keys_hash = public_keys.hash();\n\n let pre_address = poseidon2_hash_with_separator(\n [public_keys_hash.to_field(), partial_address.to_field()],\n DOM_SEP__CONTRACT_ADDRESS_V1,\n );\n\n // Note: `.add()` will fail within the blackbox fn if either of the points are not on the curve. (See tests below).\n // TODO(F-553): Drop the `.to_embedded()` / `.into()` round-trip once the custom `Point` wrapper is removed and\n // we use `EmbeddedCurvePoint` directly.\n let address_point: Point = derive_public_key(EmbeddedCurveScalar::from_field(pre_address))\n .add(public_keys.ivpk_m.to_point().to_embedded())\n .into();\n\n // Note that our address is only the x-coordinate of the full address_point. This is okay because when people want to encrypt something and send it to us\n // they can recover our full point using the x-coordinate (our address itself). To do this, they recompute the y-coordinate according to the equation y^2 = x^3 - 17.\n // When they do this, they may get a positive y-coordinate (a value that is less than or equal to MAX_FIELD_VALUE / 2) or\n // a negative y-coordinate (a value that is more than MAX_FIELD_VALUE), and we cannot dictate which one they get and hence the recovered point may sometimes be different than the one\n // our secret can decrypt. Regardless though, they should and will always encrypt using point with the positive y-coordinate by convention.\n // This ensures that everyone encrypts to the same point given an arbitrary x-coordinate (address). This is allowed because even though our original point may not have a positive y-coordinate,\n // with our original secret, we will be able to derive the secret to the point with the flipped (and now positive) y-coordinate that everyone encrypts to.\n AztecAddress::from_field(address_point.x)\n }\n\n pub fn compute_from_class_id(\n contract_class_id: ContractClassId,\n salted_initialization_hash: SaltedInitializationHash,\n public_keys: PublicKeys,\n ) -> Self {\n let partial_address = PartialAddress::compute_from_salted_initialization_hash(\n contract_class_id,\n salted_initialization_hash,\n );\n\n AztecAddress::compute(public_keys, partial_address)\n }\n\n pub fn is_zero(self) -> bool {\n self.inner == 0\n }\n\n pub fn assert_is_zero(self) {\n assert(self.to_field() == 0);\n }\n}\n\n#[test]\nfn check_max_field_value() {\n // Check that it is indeed r-1.\n assert_eq(MAX_FIELD_VALUE + 1, 0);\n}\n\n#[test]\nfn check_is_positive() {\n assert(AztecAddress::is_positive(0));\n assert(AztecAddress::is_positive(1));\n assert(!AztecAddress::is_positive(-1));\n assert(AztecAddress::is_positive(MAX_FIELD_VALUE / 2));\n assert(!AztecAddress::is_positive((MAX_FIELD_VALUE / 2) + 1));\n}\n\n// Gives us confidence that we don't need to manually check that the input public keys need to be on the curve for `add`,\n// because the blackbox function does this check for us.\n#[test(should_fail_with = \"is not on curve\")]\nfn check_embedded_curve_point_add() {\n // Choose a point not on the curve:\n let p1 = Point { x: 1, y: 1, is_infinite: false };\n let p2 = Point::generator();\n let _ = p1 + p2;\n}\n\n// Gives us confidence that we don't need to manually check that the input public keys need to be on the curve for `add`,\n// because the blackbox function does this check for us.\n#[test(should_fail_with = \"is not on curve\")]\nfn check_embedded_curve_point_add_2() {\n // Choose a point not on the curve in the 2nd position.\n let p1 = Point::generator();\n let p2 = Point { x: 1, y: 1, is_infinite: false };\n let _ = p1 + p2;\n}\n\n#[test]\nfn compute_address_from_partial_and_pub_keys() {\n let public_keys = PublicKeys {\n npk_m: NpkM {\n inner: Point {\n x: 0x22f7fcddfa3ce3e8f0cc8e82d7b94cdd740afa3e77f8e4a63ea78a239432dcab,\n y: 0x0471657de2b6216ade6c506d28fbc22ba8b8ed95c871ad9f3e3984e90d9723a7,\n is_infinite: false,\n },\n },\n ivpk_m: IvpkM {\n inner: Point {\n x: 0x111223493147f6785514b1c195bb37a2589f22a6596d30bb2bb145fdc9ca8f1e,\n y: 0x273bbffd678edce8fe30e0deafc4f66d58357c06fd4a820285294b9746c3be95,\n is_infinite: false,\n },\n },\n ovpk_m: OvpkM {\n inner: Point {\n x: 0x09115c96e962322ffed6522f57194627136b8d03ac7469109707f5e44190c484,\n y: 0x0c49773308a13d740a7f0d4f0e6163b02c5a408b6f965856b6a491002d073d5b,\n is_infinite: false,\n },\n },\n tpk_m: TpkM {\n inner: Point {\n x: 0x00d3d81beb009873eb7116327cf47c612d5758ef083d4fda78e9b63980b2a762,\n y: 0x2f567d22d2b02fe1f4ad42db9d58a36afd1983e7e2909d1cab61cafedad6193a,\n is_infinite: false,\n },\n },\n };\n\n let partial_address = PartialAddress::from_field(\n 0x0a7c585381b10f4666044266a02405bf6e01fa564c8517d4ad5823493abd31de,\n );\n\n let address = AztecAddress::compute(public_keys, partial_address);\n\n // The following value was generated by `derivation.test.ts`.\n // --> Run the test with AZTEC_GENERATE_TEST_DATA=1 flag to update test data.\n let expected_computed_address_from_partial_and_pubkeys =\n 0x2f66081d4bb077fbe8e8abe96a3516a713a3d7e34360b4e985da0da95092b37d;\n assert(address.to_field() == expected_computed_address_from_partial_and_pubkeys);\n}\n\n#[test]\nfn compute_preaddress_from_partial_and_pub_keys() {\n let pre_address = poseidon2_hash_with_separator([1, 2], DOM_SEP__CONTRACT_ADDRESS_V1);\n let expected_computed_preaddress_from_partial_and_pubkey =\n 0x286c7755f2924b1e53b00bcaf1adaffe7287bd74bba7a02f4ab867e3892d28da;\n assert(pre_address == expected_computed_preaddress_from_partial_and_pubkey);\n}\n\n#[test]\nfn from_field_to_field() {\n let address = AztecAddress { inner: 37 };\n assert_eq(FromField::from_field(address.to_field()), address);\n}\n\n#[test]\nfn serde() {\n let address = AztecAddress { inner: 37 };\n // We use the AZTEC_ADDRESS_LENGTH constant to ensure that there is a match between the derived trait\n // implementation and the constant.\n let serialized: [Field; AZTEC_ADDRESS_LENGTH] = address.serialize();\n let deserialized = AztecAddress::deserialize(serialized);\n assert_eq(address, deserialized);\n}\n\n#[test]\nfn to_address_point_valid() {\n // x = 8 where x^3 - 17 = 512 - 17 = 495, which is a residue in this field\n let address = AztecAddress { inner: 8 };\n\n assert(address.get_y().is_some()); // We don't bother checking the result of get_y as it is only used internally\n assert(address.is_valid());\n\n let maybe_point = address.to_address_point();\n assert(maybe_point.is_some());\n\n let point = maybe_point.unwrap().inner;\n // check that x is preserved\n assert_eq(point.x, Field::from(8));\n\n // check that the curve equation holds: y^2 == x^3 - 17\n assert_eq(point.y * point.y, point.x * point.x * point.x - 17);\n}\n\n#[test]\nunconstrained fn to_address_point_invalid() {\n // x = 3 where x^3 - 17 = 27 - 17 = 10, which is a non-residue in this field\n let address = AztecAddress { inner: 3 };\n\n assert(address.get_y().is_none());\n assert(!address.is_valid());\n\n assert(address.to_address_point().is_none());\n}\n"
|
|
2891
2895
|
},
|
|
2892
2896
|
"15": {
|
|
2893
2897
|
"function_locations": [
|
|
2894
2898
|
{
|
|
2895
2899
|
"name": "EmbeddedCurvePoint::double",
|
|
2896
|
-
"start":
|
|
2900
|
+
"start": 559
|
|
2897
2901
|
},
|
|
2898
2902
|
{
|
|
2899
2903
|
"name": "EmbeddedCurvePoint::point_at_infinity",
|
|
2900
|
-
"start":
|
|
2904
|
+
"start": 731
|
|
2901
2905
|
},
|
|
2902
2906
|
{
|
|
2903
2907
|
"name": "EmbeddedCurvePoint::generator",
|
|
2904
|
-
"start":
|
|
2908
|
+
"start": 872
|
|
2909
|
+
},
|
|
2910
|
+
{
|
|
2911
|
+
"name": "EmbeddedCurvePoint::is_infinite",
|
|
2912
|
+
"start": 1183
|
|
2905
2913
|
},
|
|
2906
2914
|
{
|
|
2907
2915
|
"name": "<impl Add for EmbeddedCurvePoint>::add",
|
|
2908
|
-
"start":
|
|
2916
|
+
"start": 1430
|
|
2909
2917
|
},
|
|
2910
2918
|
{
|
|
2911
2919
|
"name": "<impl Sub for EmbeddedCurvePoint>::sub",
|
|
2912
|
-
"start":
|
|
2920
|
+
"start": 1647
|
|
2913
2921
|
},
|
|
2914
2922
|
{
|
|
2915
2923
|
"name": "<impl Neg for EmbeddedCurvePoint>::neg",
|
|
2916
|
-
"start":
|
|
2924
|
+
"start": 1905
|
|
2917
2925
|
},
|
|
2918
2926
|
{
|
|
2919
2927
|
"name": "<impl Eq for EmbeddedCurvePoint>::eq",
|
|
2920
|
-
"start":
|
|
2928
|
+
"start": 2099
|
|
2921
2929
|
},
|
|
2922
2930
|
{
|
|
2923
2931
|
"name": "<impl Hash for EmbeddedCurvePoint>::hash",
|
|
2924
|
-
"start":
|
|
2932
|
+
"start": 2269
|
|
2925
2933
|
},
|
|
2926
2934
|
{
|
|
2927
2935
|
"name": "EmbeddedCurveScalar::new",
|
|
2928
|
-
"start":
|
|
2936
|
+
"start": 2823
|
|
2929
2937
|
},
|
|
2930
2938
|
{
|
|
2931
2939
|
"name": "EmbeddedCurveScalar::from_field",
|
|
2932
|
-
"start":
|
|
2940
|
+
"start": 3008
|
|
2933
2941
|
},
|
|
2934
2942
|
{
|
|
2935
2943
|
"name": "EmbeddedCurveScalar::from_bytes",
|
|
2936
|
-
"start":
|
|
2944
|
+
"start": 3354
|
|
2937
2945
|
},
|
|
2938
2946
|
{
|
|
2939
2947
|
"name": "<impl Eq for EmbeddedCurveScalar>::eq",
|
|
2940
|
-
"start":
|
|
2948
|
+
"start": 3800
|
|
2941
2949
|
},
|
|
2942
2950
|
{
|
|
2943
2951
|
"name": "<impl Hash for EmbeddedCurveScalar>::hash",
|
|
2944
|
-
"start":
|
|
2952
|
+
"start": 3983
|
|
2945
2953
|
},
|
|
2946
2954
|
{
|
|
2947
2955
|
"name": "multi_scalar_mul",
|
|
2948
|
-
"start":
|
|
2956
|
+
"start": 4659
|
|
2949
2957
|
},
|
|
2950
2958
|
{
|
|
2951
|
-
"name": "
|
|
2952
|
-
"start":
|
|
2959
|
+
"name": "fixed_base_scalar_mul",
|
|
2960
|
+
"start": 4874
|
|
2953
2961
|
},
|
|
2954
2962
|
{
|
|
2955
2963
|
"name": "multi_scalar_mul_array_return",
|
|
2956
|
-
"start":
|
|
2957
|
-
},
|
|
2958
|
-
{
|
|
2959
|
-
"name": "fixed_base_scalar_mul",
|
|
2960
|
-
"start": 5675
|
|
2964
|
+
"start": 5157
|
|
2961
2965
|
},
|
|
2962
2966
|
{
|
|
2963
2967
|
"name": "embedded_curve_add",
|
|
2964
|
-
"start":
|
|
2968
|
+
"start": 5612
|
|
2965
2969
|
},
|
|
2966
2970
|
{
|
|
2967
2971
|
"name": "embedded_curve_add_array_return",
|
|
2968
|
-
"start":
|
|
2969
|
-
},
|
|
2970
|
-
{
|
|
2971
|
-
"name": "embedded_curve_add_inner",
|
|
2972
|
-
"start": 6958
|
|
2972
|
+
"start": 5897
|
|
2973
2973
|
}
|
|
2974
2974
|
],
|
|
2975
2975
|
"path": "std/embedded_curve_ops.nr",
|
|
2976
|
-
"source": "use crate::cmp::Eq;\nuse crate::hash::Hash;\nuse crate::ops::arith::{Add, Neg, Sub};\n\n/// A point on the embedded elliptic curve\n/// By definition, the base field of the embedded curve is the scalar field of the proof system curve, i.e the Noir Field.\n/// x and y denotes the Weierstrass coordinates of the point
|
|
2976
|
+
"source": "use crate::cmp::Eq;\nuse crate::hash::Hash;\nuse crate::ops::arith::{Add, Neg, Sub};\n\n/// A point on the embedded elliptic curve\n/// By definition, the base field of the embedded curve is the scalar field of the proof system curve, i.e the Noir Field.\n/// x and y denotes the Weierstrass coordinates of the point.\npub struct EmbeddedCurvePoint {\n pub x: Field,\n pub y: Field,\n}\n\nimpl EmbeddedCurvePoint {\n /// Elliptic curve point doubling operation\n /// returns the doubled point of a point P, i.e P+P\n pub fn double(self) -> EmbeddedCurvePoint {\n embedded_curve_add(self, self)\n }\n\n /// Returns the null element of the curve; 'the point at infinity'\n pub fn point_at_infinity() -> EmbeddedCurvePoint {\n EmbeddedCurvePoint { x: 0, y: 0 }\n }\n\n /// Returns the curve's generator point.\n pub fn generator() -> EmbeddedCurvePoint {\n // Generator point for the grumpkin curve (y^2 = x^3 - 17)\n EmbeddedCurvePoint {\n x: 1,\n y: 17631683881184975370165255887551781615748388533673675138860, // sqrt(-16)\n }\n }\n\n /// True if this point is the point at infinity\n pub fn is_infinite(self) -> bool {\n (self.x == 0) & (self.y == 0)\n }\n}\n\nimpl Add for EmbeddedCurvePoint {\n /// Adds two points P+Q, using the curve addition formula, and also handles point at infinity\n fn add(self, other: EmbeddedCurvePoint) -> EmbeddedCurvePoint {\n embedded_curve_add(self, other)\n }\n}\n\nimpl Sub for EmbeddedCurvePoint {\n /// Points subtraction operation, using addition and negation\n fn sub(self, other: EmbeddedCurvePoint) -> EmbeddedCurvePoint {\n self + other.neg()\n }\n}\n\nimpl Neg for EmbeddedCurvePoint {\n /// Negates a point P, i.e returns -P, by negating the y coordinate.\n /// If the point is at infinity, then the result is also at infinity.\n fn neg(self) -> EmbeddedCurvePoint {\n EmbeddedCurvePoint { x: self.x, y: -self.y }\n }\n}\n\nimpl Eq for EmbeddedCurvePoint {\n /// Checks whether two points are equal\n fn eq(self: Self, b: EmbeddedCurvePoint) -> bool {\n (self.x == b.x) & (self.y == b.y)\n }\n}\n\nimpl Hash for EmbeddedCurvePoint {\n fn hash<H>(self, state: &mut H)\n where\n H: crate::hash::Hasher,\n {\n self.x.hash(state);\n self.y.hash(state);\n }\n}\n\n/// Scalar for the embedded curve represented as low and high limbs\n/// By definition, the scalar field of the embedded curve is base field of the proving system curve.\n/// It may not fit into a Field element, so it is represented with two Field elements; its low and high limbs.\npub struct EmbeddedCurveScalar {\n pub lo: Field,\n pub hi: Field,\n}\n\nimpl EmbeddedCurveScalar {\n /// Create a new scalar using the provided (lo, hi) pair\n pub fn new(lo: Field, hi: Field) -> Self {\n EmbeddedCurveScalar { lo, hi }\n }\n\n /// Create a scalar from the given bn254 field value\n #[field(bn254)]\n pub fn from_field(scalar: Field) -> EmbeddedCurveScalar {\n let (a, b) = crate::field::bn254::decompose(scalar);\n EmbeddedCurveScalar { lo: a, hi: b }\n }\n\n /// Take the first (after the specified offset) 16 bytes of the input as the lo value, and the next 16 bytes as the hi value\n #[field(bn254)]\n pub(crate) fn from_bytes(bytes: [u8; 64], offset: u32) -> EmbeddedCurveScalar {\n let mut v = 1;\n let mut lo = 0 as Field;\n let mut hi = 0 as Field;\n for i in 0..16 {\n lo = lo + (bytes[offset + 31 - i] as Field) * v;\n hi = hi + (bytes[offset + 15 - i] as Field) * v;\n v = v * 256;\n }\n let sig_s = crate::embedded_curve_ops::EmbeddedCurveScalar { lo, hi };\n sig_s\n }\n}\n\nimpl Eq for EmbeddedCurveScalar {\n fn eq(self, other: Self) -> bool {\n (other.hi == self.hi) & (other.lo == self.lo)\n }\n}\n\nimpl Hash for EmbeddedCurveScalar {\n fn hash<H>(self, state: &mut H)\n where\n H: crate::hash::Hasher,\n {\n self.hi.hash(state);\n self.lo.hash(state);\n }\n}\n\n/// Computes a multi scalar multiplication over the embedded curve.\n/// For bn254, We have Grumpkin.\n///\n/// The embedded curve being used is decided by the\n/// underlying proof system.\n///\n/// IMPORTANT: Prefer `multi_scalar_mul()` over repeated `embedded_curve_add()`\n/// for adding multiple points. This is significantly more efficient.\n/// For adding exactly 2 points, use `embedded_curve_add()` directly.\n// docs:start:multi_scalar_mul\npub fn multi_scalar_mul<let N: u32>(\n points: [EmbeddedCurvePoint; N],\n scalars: [EmbeddedCurveScalar; N],\n) -> EmbeddedCurvePoint\n// docs:end:multi_scalar_mul\n{\n multi_scalar_mul_array_return(points, scalars, true)[0]\n}\n\n// docs:start:fixed_base_scalar_mul\npub fn fixed_base_scalar_mul(scalar: EmbeddedCurveScalar) -> EmbeddedCurvePoint\n// docs:end:fixed_base_scalar_mul\n{\n multi_scalar_mul([EmbeddedCurvePoint::generator()], [scalar])\n}\n\n#[foreign(multi_scalar_mul)]\npub(crate) fn multi_scalar_mul_array_return<let N: u32>(\n points: [EmbeddedCurvePoint; N],\n scalars: [EmbeddedCurveScalar; N],\n predicate: bool,\n) -> [EmbeddedCurvePoint; 1] {}\n\n/// Elliptic curve addition\n/// IMPORTANT: this function is expected to perform a full addition in order to handle all corner cases:\n/// - points on the curve\n/// - point doubling\n/// - point at infinity\n/// As a result, you may not get optimal performance, depending on the assumptions of your inputs.\n// docs:start:embedded_curve_add\npub fn embedded_curve_add(\n point1: EmbeddedCurvePoint,\n point2: EmbeddedCurvePoint,\n) -> EmbeddedCurvePoint {\n // docs:end:embedded_curve_add\n embedded_curve_add_array_return(point1, point2, true)[0]\n}\n\n#[foreign(embedded_curve_add)]\nfn embedded_curve_add_array_return(\n _point1: EmbeddedCurvePoint,\n _point2: EmbeddedCurvePoint,\n _predicate: bool,\n) -> [EmbeddedCurvePoint; 1] {}\n"
|
|
2977
2977
|
},
|
|
2978
2978
|
"151": {
|
|
2979
2979
|
"function_locations": [
|
|
@@ -3117,215 +3117,215 @@
|
|
|
3117
3117
|
},
|
|
3118
3118
|
{
|
|
3119
3119
|
"name": "Field::to_le_bits",
|
|
3120
|
-
"start":
|
|
3120
|
+
"start": 1196
|
|
3121
3121
|
},
|
|
3122
3122
|
{
|
|
3123
3123
|
"name": "Field::to_be_bits",
|
|
3124
|
-
"start":
|
|
3124
|
+
"start": 2387
|
|
3125
3125
|
},
|
|
3126
3126
|
{
|
|
3127
3127
|
"name": "Field::to_le_bytes",
|
|
3128
|
-
"start":
|
|
3128
|
+
"start": 3562
|
|
3129
3129
|
},
|
|
3130
3130
|
{
|
|
3131
3131
|
"name": "Field::to_be_bytes",
|
|
3132
|
-
"start":
|
|
3132
|
+
"start": 5033
|
|
3133
3133
|
},
|
|
3134
3134
|
{
|
|
3135
3135
|
"name": "Field::to_le_radix",
|
|
3136
|
-
"start":
|
|
3136
|
+
"start": 5904
|
|
3137
3137
|
},
|
|
3138
3138
|
{
|
|
3139
3139
|
"name": "Field::to_be_radix",
|
|
3140
|
-
"start":
|
|
3140
|
+
"start": 6362
|
|
3141
3141
|
},
|
|
3142
3142
|
{
|
|
3143
3143
|
"name": "Field::pow_32",
|
|
3144
|
-
"start":
|
|
3144
|
+
"start": 7053
|
|
3145
3145
|
},
|
|
3146
3146
|
{
|
|
3147
3147
|
"name": "Field::sgn0",
|
|
3148
|
-
"start":
|
|
3148
|
+
"start": 7455
|
|
3149
3149
|
},
|
|
3150
3150
|
{
|
|
3151
3151
|
"name": "Field::lt",
|
|
3152
|
-
"start":
|
|
3152
|
+
"start": 7538
|
|
3153
3153
|
},
|
|
3154
3154
|
{
|
|
3155
3155
|
"name": "Field::from_le_bytes",
|
|
3156
|
-
"start":
|
|
3156
|
+
"start": 7918
|
|
3157
3157
|
},
|
|
3158
3158
|
{
|
|
3159
3159
|
"name": "Field::from_be_bytes",
|
|
3160
|
-
"start":
|
|
3160
|
+
"start": 8476
|
|
3161
3161
|
},
|
|
3162
3162
|
{
|
|
3163
3163
|
"name": "__assert_max_bit_size",
|
|
3164
|
-
"start":
|
|
3164
|
+
"start": 8757
|
|
3165
3165
|
},
|
|
3166
3166
|
{
|
|
3167
3167
|
"name": "__to_le_radix",
|
|
3168
|
-
"start":
|
|
3168
|
+
"start": 8885
|
|
3169
3169
|
},
|
|
3170
3170
|
{
|
|
3171
3171
|
"name": "__to_be_radix",
|
|
3172
|
-
"start":
|
|
3172
|
+
"start": 9013
|
|
3173
3173
|
},
|
|
3174
3174
|
{
|
|
3175
3175
|
"name": "__to_le_bits",
|
|
3176
|
-
"start":
|
|
3176
|
+
"start": 9734
|
|
3177
3177
|
},
|
|
3178
3178
|
{
|
|
3179
3179
|
"name": "__to_be_bits",
|
|
3180
|
-
"start":
|
|
3180
|
+
"start": 10452
|
|
3181
3181
|
},
|
|
3182
3182
|
{
|
|
3183
3183
|
"name": "modulus_num_bits",
|
|
3184
|
-
"start":
|
|
3184
|
+
"start": 10527
|
|
3185
3185
|
},
|
|
3186
3186
|
{
|
|
3187
3187
|
"name": "modulus_be_bits",
|
|
3188
|
-
"start":
|
|
3188
|
+
"start": 10603
|
|
3189
3189
|
},
|
|
3190
3190
|
{
|
|
3191
3191
|
"name": "modulus_le_bits",
|
|
3192
|
-
"start":
|
|
3192
|
+
"start": 10679
|
|
3193
3193
|
},
|
|
3194
3194
|
{
|
|
3195
3195
|
"name": "modulus_be_bytes",
|
|
3196
|
-
"start":
|
|
3196
|
+
"start": 10755
|
|
3197
3197
|
},
|
|
3198
3198
|
{
|
|
3199
3199
|
"name": "modulus_le_bytes",
|
|
3200
|
-
"start":
|
|
3200
|
+
"start": 10831
|
|
3201
3201
|
},
|
|
3202
3202
|
{
|
|
3203
3203
|
"name": "__field_less_than",
|
|
3204
|
-
"start":
|
|
3204
|
+
"start": 10992
|
|
3205
3205
|
},
|
|
3206
3206
|
{
|
|
3207
3207
|
"name": "field_less_than",
|
|
3208
|
-
"start":
|
|
3208
|
+
"start": 11068
|
|
3209
3209
|
},
|
|
3210
3210
|
{
|
|
3211
3211
|
"name": "bytes32_to_field",
|
|
3212
|
-
"start":
|
|
3212
|
+
"start": 11210
|
|
3213
3213
|
},
|
|
3214
3214
|
{
|
|
3215
3215
|
"name": "lt_fallback",
|
|
3216
|
-
"start":
|
|
3216
|
+
"start": 11617
|
|
3217
3217
|
},
|
|
3218
3218
|
{
|
|
3219
3219
|
"name": "tests::test_to_be_bits",
|
|
3220
|
-
"start":
|
|
3220
|
+
"start": 12579
|
|
3221
3221
|
},
|
|
3222
3222
|
{
|
|
3223
3223
|
"name": "tests::test_to_le_bits",
|
|
3224
|
-
"start":
|
|
3224
|
+
"start": 12852
|
|
3225
3225
|
},
|
|
3226
3226
|
{
|
|
3227
3227
|
"name": "tests::test_to_be_bytes",
|
|
3228
|
-
"start":
|
|
3228
|
+
"start": 13127
|
|
3229
3229
|
},
|
|
3230
3230
|
{
|
|
3231
3231
|
"name": "tests::test_to_le_bytes",
|
|
3232
|
-
"start":
|
|
3232
|
+
"start": 13433
|
|
3233
3233
|
},
|
|
3234
3234
|
{
|
|
3235
3235
|
"name": "tests::test_to_be_radix",
|
|
3236
|
-
"start":
|
|
3236
|
+
"start": 13739
|
|
3237
3237
|
},
|
|
3238
3238
|
{
|
|
3239
3239
|
"name": "tests::test_to_le_radix",
|
|
3240
|
-
"start":
|
|
3240
|
+
"start": 14321
|
|
3241
3241
|
},
|
|
3242
3242
|
{
|
|
3243
3243
|
"name": "tests::test_to_le_radix_1",
|
|
3244
|
-
"start":
|
|
3244
|
+
"start": 14921
|
|
3245
3245
|
},
|
|
3246
3246
|
{
|
|
3247
3247
|
"name": "tests::test_to_le_radix_brillig_1",
|
|
3248
|
-
"start":
|
|
3248
|
+
"start": 15374
|
|
3249
3249
|
},
|
|
3250
3250
|
{
|
|
3251
3251
|
"name": "tests::test_to_le_radix_3",
|
|
3252
|
-
"start":
|
|
3252
|
+
"start": 15728
|
|
3253
3253
|
},
|
|
3254
3254
|
{
|
|
3255
3255
|
"name": "tests::test_to_le_radix_brillig_3",
|
|
3256
|
-
"start":
|
|
3256
|
+
"start": 16039
|
|
3257
3257
|
},
|
|
3258
3258
|
{
|
|
3259
3259
|
"name": "tests::test_to_le_radix_512",
|
|
3260
|
-
"start":
|
|
3260
|
+
"start": 16467
|
|
3261
3261
|
},
|
|
3262
3262
|
{
|
|
3263
3263
|
"name": "tests::not_enough_limbs_brillig",
|
|
3264
|
-
"start":
|
|
3264
|
+
"start": 16876
|
|
3265
3265
|
},
|
|
3266
3266
|
{
|
|
3267
3267
|
"name": "tests::not_enough_limbs",
|
|
3268
|
-
"start":
|
|
3268
|
+
"start": 17072
|
|
3269
3269
|
},
|
|
3270
3270
|
{
|
|
3271
3271
|
"name": "tests::test_field_less_than",
|
|
3272
|
-
"start":
|
|
3272
|
+
"start": 17214
|
|
3273
3273
|
},
|
|
3274
3274
|
{
|
|
3275
3275
|
"name": "tests::test_large_field_values_unconstrained",
|
|
3276
|
-
"start":
|
|
3276
|
+
"start": 17469
|
|
3277
3277
|
},
|
|
3278
3278
|
{
|
|
3279
3279
|
"name": "tests::test_large_field_values",
|
|
3280
|
-
"start":
|
|
3280
|
+
"start": 17922
|
|
3281
3281
|
},
|
|
3282
3282
|
{
|
|
3283
3283
|
"name": "tests::test_decomposition_edge_cases",
|
|
3284
|
-
"start":
|
|
3284
|
+
"start": 18369
|
|
3285
3285
|
},
|
|
3286
3286
|
{
|
|
3287
3287
|
"name": "tests::test_pow_32",
|
|
3288
|
-
"start":
|
|
3288
|
+
"start": 18959
|
|
3289
3289
|
},
|
|
3290
3290
|
{
|
|
3291
3291
|
"name": "tests::test_sgn0",
|
|
3292
|
-
"start":
|
|
3292
|
+
"start": 19288
|
|
3293
3293
|
},
|
|
3294
3294
|
{
|
|
3295
3295
|
"name": "tests::test_bit_decomposition_overflow",
|
|
3296
|
-
"start":
|
|
3296
|
+
"start": 19710
|
|
3297
3297
|
},
|
|
3298
3298
|
{
|
|
3299
3299
|
"name": "tests::test_byte_decomposition_overflow",
|
|
3300
|
-
"start":
|
|
3300
|
+
"start": 19992
|
|
3301
3301
|
},
|
|
3302
3302
|
{
|
|
3303
3303
|
"name": "tests::test_to_from_be_bytes_bn254_edge_cases",
|
|
3304
|
-
"start":
|
|
3304
|
+
"start": 20209
|
|
3305
3305
|
},
|
|
3306
3306
|
{
|
|
3307
3307
|
"name": "tests::test_to_from_le_bytes_bn254_edge_cases",
|
|
3308
|
-
"start":
|
|
3308
|
+
"start": 22160
|
|
3309
3309
|
},
|
|
3310
3310
|
{
|
|
3311
3311
|
"name": "tests::from_le_bits",
|
|
3312
|
-
"start":
|
|
3312
|
+
"start": 24245
|
|
3313
3313
|
},
|
|
3314
3314
|
{
|
|
3315
3315
|
"name": "tests::from_be_bits",
|
|
3316
|
-
"start":
|
|
3316
|
+
"start": 24792
|
|
3317
3317
|
},
|
|
3318
3318
|
{
|
|
3319
3319
|
"name": "tests::test_to_from_be_bits_bn254_edge_cases",
|
|
3320
|
-
"start":
|
|
3320
|
+
"start": 25038
|
|
3321
3321
|
},
|
|
3322
3322
|
{
|
|
3323
3323
|
"name": "tests::test_to_from_le_bits_bn254_edge_cases",
|
|
3324
|
-
"start":
|
|
3324
|
+
"start": 26971
|
|
3325
3325
|
}
|
|
3326
3326
|
],
|
|
3327
3327
|
"path": "std/field/mod.nr",
|
|
3328
|
-
"source": "pub mod bn254;\nuse crate::{runtime::is_unconstrained, static_assert};\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n /// Asserts that `self` can be represented in `bit_size` bits.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^{bit_size}`.\n // docs:start:assert_max_bit_size\n pub fn assert_max_bit_size<let BIT_SIZE: u32>(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits<let N: u32>(self: Self) -> [u1; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits<let N: u32>(self: Self) -> [u1; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i] == 1);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes<let N: u32>(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes<let N: u32>(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix<let N: u32>(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix<let N: u32>(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\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: [u1; 32] = exponent.to_le_bits();\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 `elem` {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 /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes<let N: u32>(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes<let N: u32>(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix<let N: u32>(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix<let N: u32>(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits<let N: u32>(value: Field) -> [u1; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[u1; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits<let N: u32>(value: Field) -> [u1; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [u1] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [u1] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\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 if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 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\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_be_bits();\n assert_eq(bits, [0, 0, 0, 0, 0, 0, 1, 0]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [u1; 8] = field.to_le_bits();\n assert_eq(bits, [0, 1, 0, 0, 0, 0, 0, 0]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_field.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [u1; 64] = large_val.to_le_bits();\n assert_eq(bits[0], 1);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [u1; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [0; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [u1; 8] = 1.to_le_bits();\n let expected: [u1; 8] = [1, 0, 0, 0, 0, 0, 0, 0];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [u1; 8] = 4.to_le_bits();\n let expected: [u1; 8] = [0, 0, 1, 0, 0, 0, 0, 0];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), 0);\n assert_eq(2.sgn0(), 0);\n assert_eq(4.sgn0(), 0);\n assert_eq(100.sgn0(), 0);\n\n assert_eq(1.sgn0(), 1);\n assert_eq(3.sgn0(), 1);\n assert_eq(5.sgn0(), 1);\n assert_eq(101.sgn0(), 1);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u1; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits<let N: u32>(bits: [u1; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits<let N: u32>(bits: [u1; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1] > 0);\n p_minus_1_bits[254 - 1] -= 1;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_be_bits().as_array();\n assert(p_plus_4_bits[254 - 3] < 1);\n p_plus_4_bits[254 - 3] += 1;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_be_bits();\n assert_eq(p_plus_4_converted_bits[254 - 3], 1);\n p_plus_4_converted_bits[254 - 3] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_be_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0] > 0);\n p_minus_1_bits[0] -= 1;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [u1; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [u1; 254] = modulus_le_bits().as_array();\n assert(p_plus_4_bits[2] < 1);\n p_plus_4_bits[2] += 1;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [u1; 254] = p_plus_4.to_le_bits();\n assert_eq(p_plus_4_converted_bits[2], 1);\n p_plus_4_converted_bits[2] = 0;\n assert_eq(p_plus_4_converted_bits, [0; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bytes produces 254 zeroes\n let p_bits: [u1; 254] = 0.to_le_bits();\n assert_eq(p_bits, [0; 254]);\n }\n }\n}\n"
|
|
3328
|
+
"source": "pub mod bn254;\nuse crate::{runtime::is_unconstrained, static_assert};\nuse bn254::lt as bn254_lt;\n\nimpl Field {\n /// Asserts that `self` can be represented in `bit_size` bits.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^{bit_size}`.\n // docs:start:assert_max_bit_size\n pub fn assert_max_bit_size<let BIT_SIZE: u32>(self) {\n // docs:end:assert_max_bit_size\n static_assert(\n BIT_SIZE < modulus_num_bits() as u32,\n \"BIT_SIZE must be less than modulus_num_bits\",\n );\n __assert_max_bit_size(self, BIT_SIZE);\n }\n\n /// Decomposes `self` into its little endian bit decomposition as a `[bool; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_le_bits\n pub fn to_le_bits<let N: u32>(self: Self) -> [bool; N] {\n // docs:end:to_le_bits\n let bits = __to_le_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[N - 1 - i] != p[N - 1 - i]) {\n assert(p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its big endian bit decomposition as a `[bool; N]` array.\n /// This array will be zero padded should not all bits be necessary to represent `self`.\n ///\n /// # Failures\n /// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n /// be able to represent the original `Field`.\n ///\n /// # Safety\n /// The bit decomposition returned is canonical and is guaranteed to not overflow the modulus.\n // docs:start:to_be_bits\n pub fn to_be_bits<let N: u32>(self: Self) -> [bool; N] {\n // docs:end:to_be_bits\n let bits = __to_be_bits(self);\n\n if !is_unconstrained() {\n // Ensure that the decomposition does not overflow the modulus\n let p = modulus_be_bits();\n assert(bits.len() <= p.len());\n let mut ok = bits.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bits[i] != p[i]) {\n assert(p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bits\n }\n\n /// Decomposes `self` into its little endian byte decomposition as a `[u8;N]` array\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_le_bytes\n pub fn to_le_bytes<let N: u32>(self: Self) -> [u8; N] {\n // docs:end:to_le_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_le_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_le_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[N - 1 - i] != p[N - 1 - i]) {\n assert(bytes[N - 1 - i] < p[N - 1 - i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n /// Decomposes `self` into its big endian byte decomposition as a `[u8;N]` array of length required to represent the field modulus\n /// This array will be zero padded should not all bytes be necessary to represent `self`.\n ///\n /// # Failures\n /// The length N of the array must be big enough to contain all the bytes of the 'self',\n /// and no more than the number of bytes required to represent the field modulus\n ///\n /// # Safety\n /// The result is ensured to be the canonical decomposition of the field element\n // docs:start:to_be_bytes\n pub fn to_be_bytes<let N: u32>(self: Self) -> [u8; N] {\n // docs:end:to_be_bytes\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n // Compute the byte decomposition\n let bytes = self.to_be_radix(256);\n\n if !is_unconstrained() {\n // Ensure that the byte decomposition does not overflow the modulus\n let p = modulus_be_bytes();\n assert(bytes.len() <= p.len());\n let mut ok = bytes.len() != p.len();\n for i in 0..N {\n if !ok {\n if (bytes[i] != p[i]) {\n assert(bytes[i] < p[i]);\n ok = true;\n }\n }\n }\n assert(ok);\n }\n bytes\n }\n\n fn to_le_radix<let N: u32>(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_le_radix(self, radix)\n }\n\n fn to_be_radix<let N: u32>(self: Self, radix: u32) -> [u8; N] {\n // Brillig does not need an immediate radix\n if !crate::runtime::is_unconstrained() {\n static_assert(1 < radix, \"radix must be greater than 1\");\n static_assert(radix <= 256, \"radix must be less than or equal to 256\");\n static_assert(radix & (radix - 1) == 0, \"radix must be a power of 2\");\n }\n __to_be_radix(self, radix)\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: [bool; 32] = exponent.to_le_bits();\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) = false if x `elem` {0, ..., p-1} is even, otherwise sgn0(x mod p) = true.\n pub fn sgn0(self) -> bool {\n (self as u8) % 2 == 1\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 /// Convert a little endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_le_bytes<let N: u32>(bytes: [u8; N]) -> Field {\n static_assert(\n N <= modulus_le_bytes().len(),\n \"N must be less than or equal to modulus_le_bytes().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[i] as Field) * v;\n v = v * 256;\n }\n result\n }\n\n /// Convert a big endian byte array to a field element.\n /// If the provided byte array overflows the field modulus then the Field will silently wrap around.\n pub fn from_be_bytes<let N: u32>(bytes: [u8; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bytes[N - 1 - i] as Field) * v;\n v = v * 256;\n }\n result\n }\n}\n\n#[builtin(apply_range_constraint)]\nfn __assert_max_bit_size(value: Field, bit_size: u32) {}\n\n// `_radix` must be less than 256\n#[builtin(to_le_radix)]\nfn __to_le_radix<let N: u32>(value: Field, radix: u32) -> [u8; N] {}\n\n// `_radix` must be less than 256\n#[builtin(to_be_radix)]\nfn __to_be_radix<let N: u32>(value: Field, radix: u32) -> [u8; N] {}\n\n/// Decomposes `self` into its little endian bit decomposition as a `[bool; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_le_bits)]\nfn __to_le_bits<let N: u32>(value: Field) -> [bool; N] {}\n\n/// Decomposes `self` into its big endian bit decomposition as a `[bool; N]` array.\n/// This array will be zero padded should not all bits be necessary to represent `self`.\n///\n/// # Failures\n/// Causes a constraint failure for `Field` values exceeding `2^N` as the resulting array will not\n/// be able to represent the original `Field`.\n///\n/// # Safety\n/// Values of `N` equal to or greater than the number of bits necessary to represent the `Field` modulus\n/// (e.g. 254 for the BN254 field) allow for multiple bit decompositions. This is due to how the `Field` will\n/// wrap around due to overflow when verifying the decomposition.\n#[builtin(to_be_bits)]\nfn __to_be_bits<let N: u32>(value: Field) -> [bool; N] {}\n\n#[builtin(modulus_num_bits)]\npub comptime fn modulus_num_bits() -> u64 {}\n\n#[builtin(modulus_be_bits)]\npub comptime fn modulus_be_bits() -> [bool] {}\n\n#[builtin(modulus_le_bits)]\npub comptime fn modulus_le_bits() -> [bool] {}\n\n#[builtin(modulus_be_bytes)]\npub comptime fn modulus_be_bytes() -> [u8] {}\n\n#[builtin(modulus_le_bytes)]\npub comptime fn modulus_le_bytes() -> [u8] {}\n\n/// An unconstrained only built in to efficiently compare fields.\n#[builtin(field_less_than)]\nunconstrained fn __field_less_than(x: Field, y: Field) -> bool {}\n\npub(crate) unconstrained fn field_less_than(x: Field, y: Field) -> bool {\n __field_less_than(x, y)\n}\n\n// Convert a 32 byte array to a field element by modding\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 if is_unconstrained() {\n // Safety: unconstrained context\n unsafe {\n field_less_than(x, y)\n }\n } else {\n let x_bytes: [u8; 32] = x.to_le_bytes();\n let y_bytes: [u8; 32] = y.to_le_bytes();\n let mut x_is_lt = false;\n let mut done = false;\n for i in 0..32 {\n if (!done) {\n let x_byte = x_bytes[32 - 1 - i] as u8;\n let y_byte = y_bytes[32 - 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\nmod tests {\n use crate::{panic::panic, runtime, static_assert};\n use super::{\n field_less_than, modulus_be_bits, modulus_be_bytes, modulus_le_bits, modulus_le_bytes,\n };\n\n #[test]\n // docs:start:to_be_bits_example\n fn test_to_be_bits() {\n let field = 2;\n let bits: [bool; 8] = field.to_be_bits();\n assert_eq(bits, [false, false, false, false, false, false, true, false]);\n }\n // docs:end:to_be_bits_example\n\n #[test]\n // docs:start:to_le_bits_example\n fn test_to_le_bits() {\n let field = 2;\n let bits: [bool; 8] = field.to_le_bits();\n assert_eq(bits, [false, true, false, false, false, false, false, false]);\n }\n // docs:end:to_le_bits_example\n\n #[test]\n // docs:start:to_be_bytes_example\n fn test_to_be_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_be_bytes();\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 0, 2]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_bytes_example\n\n #[test]\n // docs:start:to_le_bytes_example\n fn test_to_le_bytes() {\n let field = 2;\n let bytes: [u8; 8] = field.to_le_bytes();\n assert_eq(bytes, [2, 0, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_bytes_example\n\n #[test]\n // docs:start:to_be_radix_example\n fn test_to_be_radix() {\n // 259, in base 256, big endian, is [1, 3].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_be_radix(256);\n assert_eq(bytes, [0, 0, 0, 0, 0, 0, 1, 3]);\n assert_eq(Field::from_be_bytes::<8>(bytes), field);\n }\n // docs:end:to_be_radix_example\n\n #[test]\n // docs:start:to_le_radix_example\n fn test_to_le_radix() {\n // 259, in base 256, little endian, is [3, 1].\n // i.e. 3 * 256^0 + 1 * 256^1\n let field = 259;\n\n // The radix (in this example, 256) must be a power of 2.\n // The length of the returned byte array can be specified to be\n // >= the amount of space needed.\n let bytes: [u8; 8] = field.to_le_radix(256);\n assert_eq(bytes, [3, 1, 0, 0, 0, 0, 0, 0]);\n assert_eq(Field::from_le_bytes::<8>(bytes), field);\n }\n // docs:end:to_le_radix_example\n\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(\"radix must be greater than 1\");\n }\n }\n\n // Updated test to account for Brillig restriction that radix must be greater than 2\n #[test(should_fail_with = \"radix must be greater than 1\")]\n fn test_to_le_radix_brillig_1() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 1;\n let _: [u8; 8] = field.to_le_radix(1);\n } else {\n panic(\"radix must be greater than 1\");\n }\n }\n\n #[test(should_fail_with = \"radix must be a power of 2\")]\n fn test_to_le_radix_3() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(3);\n } else {\n panic(\"radix must be a power of 2\");\n }\n }\n\n #[test]\n fn test_to_le_radix_brillig_3() {\n // this test should only fail in constrained mode\n if runtime::is_unconstrained() {\n let field = 1;\n let out: [u8; 8] = field.to_le_radix(3);\n let mut expected = [0; 8];\n expected[0] = 1;\n assert(out == expected, \"unexpected result\");\n }\n }\n\n #[test(should_fail_with = \"radix must be less than or equal to 256\")]\n fn test_to_le_radix_512() {\n // this test should only fail in constrained mode\n if !runtime::is_unconstrained() {\n let field = 2;\n let _: [u8; 8] = field.to_le_radix(512);\n } else {\n panic(\"radix must be less than or equal to 256\")\n }\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n unconstrained fn not_enough_limbs_brillig() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 16 limbs\")]\n fn not_enough_limbs() {\n let _: [u8; 16] = 0x100000000000000000000000000000000.to_le_bytes();\n }\n\n #[test]\n unconstrained fn test_field_less_than() {\n assert(field_less_than(0, 1));\n assert(field_less_than(0, 0x100));\n assert(field_less_than(0x100, 0 - 1));\n assert(!field_less_than(0 - 1, 0));\n }\n\n #[test]\n unconstrained fn test_large_field_values_unconstrained() {\n let large_field = 0xffffffffffffffff;\n\n let bits: [bool; 64] = large_field.to_le_bits();\n assert_eq(bits[0], true);\n\n let bytes: [u8; 8] = large_field.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_field);\n\n let radix_bytes: [u8; 8] = large_field.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_field);\n }\n\n #[test]\n fn test_large_field_values() {\n let large_val = 0xffffffffffffffff;\n\n let bits: [bool; 64] = large_val.to_le_bits();\n assert_eq(bits[0], true);\n\n let bytes: [u8; 8] = large_val.to_le_bytes();\n assert_eq(Field::from_le_bytes::<8>(bytes), large_val);\n\n let radix_bytes: [u8; 8] = large_val.to_le_radix(256);\n assert_eq(Field::from_le_bytes::<8>(radix_bytes), large_val);\n }\n\n #[test]\n fn test_decomposition_edge_cases() {\n let zero_bits: [bool; 8] = 0.to_le_bits();\n assert_eq(zero_bits, [false; 8]);\n\n let zero_bytes: [u8; 8] = 0.to_le_bytes();\n assert_eq(zero_bytes, [0; 8]);\n\n let one_bits: [bool; 8] = 1.to_le_bits();\n let expected: [bool; 8] = [true, false, false, false, false, false, false, false];\n assert_eq(one_bits, expected);\n\n let pow2_bits: [bool; 8] = 4.to_le_bits();\n let expected: [bool; 8] = [false, false, true, false, false, false, false, false];\n assert_eq(pow2_bits, expected);\n }\n\n #[test]\n fn test_pow_32() {\n assert_eq(2.pow_32(3), 8);\n assert_eq(3.pow_32(2), 9);\n assert_eq(5.pow_32(0), 1);\n assert_eq(7.pow_32(1), 7);\n\n assert_eq(2.pow_32(10), 1024);\n\n assert_eq(0.pow_32(5), 0);\n assert_eq(0.pow_32(0), 1);\n\n assert_eq(1.pow_32(100), 1);\n }\n\n #[test]\n fn test_sgn0() {\n assert_eq(0.sgn0(), false);\n assert_eq(2.sgn0(), false);\n assert_eq(4.sgn0(), false);\n assert_eq(100.sgn0(), false);\n\n assert_eq(1.sgn0(), true);\n assert_eq(3.sgn0(), true);\n assert_eq(5.sgn0(), true);\n assert_eq(101.sgn0(), true);\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 8 limbs\")]\n fn test_bit_decomposition_overflow() {\n // 8 bits can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [bool; 8] = large_val.to_le_bits();\n }\n\n #[test(should_fail_with = \"Field failed to decompose into specified 4 limbs\")]\n fn test_byte_decomposition_overflow() {\n // 4 bytes can't represent large field values\n let large_val = 0x1000000000000000;\n let _: [u8; 4] = large_val.to_le_bytes();\n }\n\n #[test]\n fn test_to_from_be_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 BE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_minus_1_bytes[32 - 1] > 0);\n p_minus_1_bytes[32 - 1] -= 1;\n\n let p_minus_1 = Field::from_be_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_be_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 BE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_be_bytes().as_array();\n assert(p_plus_1_bytes[32 - 1] < 255);\n p_plus_1_bytes[32 - 1] += 1;\n\n let p_plus_1 = Field::from_be_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 BE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_be_bytes();\n assert_eq(p_plus_1_converted_bytes[32 - 1], 1);\n p_plus_1_converted_bytes[32 - 1] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_be_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_be_bytes().len(), 32);\n let p = Field::from_be_bytes::<32>(modulus_be_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 BE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_be_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n #[test]\n fn test_to_from_le_bytes_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this byte produces the expected 32 LE bytes for (modulus - 1)\n let mut p_minus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_minus_1_bytes[0] > 0);\n p_minus_1_bytes[0] -= 1;\n\n let p_minus_1 = Field::from_le_bytes::<32>(p_minus_1_bytes);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 32 BE bytes produces the same bytes\n let p_minus_1_converted_bytes: [u8; 32] = p_minus_1.to_le_bytes();\n assert_eq(p_minus_1_converted_bytes, p_minus_1_bytes);\n\n // checking that incrementing this byte produces 32 LE bytes for (modulus + 1)\n let mut p_plus_1_bytes: [u8; 32] = modulus_le_bytes().as_array();\n assert(p_plus_1_bytes[0] < 255);\n p_plus_1_bytes[0] += 1;\n\n let p_plus_1 = Field::from_le_bytes::<32>(p_plus_1_bytes);\n assert_eq(p_plus_1, 1);\n\n // checking that converting p_plus_1 to 32 LE bytes produces the same\n // byte set to 1 as p_plus_1_bytes and otherwise zeroes\n let mut p_plus_1_converted_bytes: [u8; 32] = p_plus_1.to_le_bytes();\n assert_eq(p_plus_1_converted_bytes[0], 1);\n p_plus_1_converted_bytes[0] = 0;\n assert_eq(p_plus_1_converted_bytes, [0; 32]);\n\n // checking that Field::from_le_bytes::<32> on the Field modulus produces 0\n assert_eq(modulus_le_bytes().len(), 32);\n let p = Field::from_le_bytes::<32>(modulus_le_bytes().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 32 LE bytes produces 32 zeroes\n let p_bytes: [u8; 32] = 0.to_le_bytes();\n assert_eq(p_bytes, [0; 32]);\n }\n }\n\n /// Convert a little endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_le_bits<let N: u32>(bits: [bool; N]) -> Field {\n static_assert(\n N <= modulus_le_bits().len(),\n \"N must be less than or equal to modulus_le_bits().len()\",\n );\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n /// Convert a big endian bit array to a field element.\n /// If the provided bit array overflows the field modulus then the Field will silently wrap around.\n fn from_be_bits<let N: u32>(bits: [bool; N]) -> Field {\n let mut v = 1;\n let mut result = 0;\n\n for i in 0..N {\n result += (bits[N - 1 - i] as Field) * v;\n v = v * 2;\n }\n result\n }\n\n #[test]\n fn test_to_from_be_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 BE bits for (modulus - 1)\n let mut p_minus_1_bits: [bool; 254] = modulus_be_bits().as_array();\n assert(p_minus_1_bits[254 - 1]);\n p_minus_1_bits[254 - 1] = false;\n\n let p_minus_1 = from_be_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [bool; 254] = p_minus_1.to_be_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 BE bits for (modulus + 4)\n let mut p_plus_4_bits: [bool; 254] = modulus_be_bits().as_array();\n assert(!p_plus_4_bits[254 - 3]);\n p_plus_4_bits[254 - 3] = true;\n\n let p_plus_4 = from_be_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 BE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [bool; 254] = p_plus_4.to_be_bits();\n assert(p_plus_4_converted_bits[254 - 3]);\n p_plus_4_converted_bits[254 - 3] = false;\n assert_eq(p_plus_4_converted_bits, [false; 254]);\n\n // checking that Field::from_be_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_be_bits().len(), 254);\n let p = from_be_bits::<254>(modulus_be_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 BE bits produces 254 false values\n let p_bits: [bool; 254] = 0.to_be_bits();\n assert_eq(p_bits, [false; 254]);\n }\n }\n\n #[test]\n fn test_to_from_le_bits_bn254_edge_cases() {\n if crate::compat::is_bn254() {\n // checking that decrementing this bit produces the expected 254 LE bits for (modulus - 1)\n let mut p_minus_1_bits: [bool; 254] = modulus_le_bits().as_array();\n assert(p_minus_1_bits[0]);\n p_minus_1_bits[0] = false;\n\n let p_minus_1 = from_le_bits::<254>(p_minus_1_bits);\n assert_eq(p_minus_1 + 1, 0);\n\n // checking that converting (modulus - 1) from and then to 254 BE bits produces the same bits\n let p_minus_1_converted_bits: [bool; 254] = p_minus_1.to_le_bits();\n assert_eq(p_minus_1_converted_bits, p_minus_1_bits);\n\n // checking that incrementing this bit produces 254 LE bits for (modulus + 4)\n let mut p_plus_4_bits: [bool; 254] = modulus_le_bits().as_array();\n assert(!p_plus_4_bits[2]);\n p_plus_4_bits[2] = true;\n\n let p_plus_4 = from_le_bits::<254>(p_plus_4_bits);\n assert_eq(p_plus_4, 4);\n\n // checking that converting p_plus_4 to 254 LE bits produces the same\n // bit set to 1 as p_plus_4_bits and otherwise zeroes\n let mut p_plus_4_converted_bits: [bool; 254] = p_plus_4.to_le_bits();\n assert(p_plus_4_converted_bits[2]);\n p_plus_4_converted_bits[2] = false;\n assert_eq(p_plus_4_converted_bits, [false; 254]);\n\n // checking that Field::from_le_bits::<254> on the Field modulus produces 0\n assert_eq(modulus_le_bits().len(), 254);\n let p = from_le_bits::<254>(modulus_le_bits().as_array());\n assert_eq(p, 0);\n\n // checking that converting 0 to 254 LE bits produces 254 false values\n let p_bits: [bool; 254] = 0.to_le_bits();\n assert_eq(p_bits, [false; 254]);\n }\n }\n}\n"
|
|
3329
3329
|
},
|
|
3330
3330
|
"171": {
|
|
3331
3331
|
"function_locations": [
|
|
@@ -3343,19 +3343,19 @@
|
|
|
3343
3343
|
},
|
|
3344
3344
|
{
|
|
3345
3345
|
"name": "<impl Packable for DelayedPublicMutableValues<T, INITIAL_DELAY>>::pack",
|
|
3346
|
-
"start":
|
|
3346
|
+
"start": 4565
|
|
3347
3347
|
},
|
|
3348
3348
|
{
|
|
3349
3349
|
"name": "<impl Packable for DelayedPublicMutableValues<T, INITIAL_DELAY>>::unpack",
|
|
3350
|
-
"start":
|
|
3350
|
+
"start": 5966
|
|
3351
3351
|
},
|
|
3352
3352
|
{
|
|
3353
3353
|
"name": "<impl Hash for DelayedPublicMutableValues<T, INITIAL_DELAY>>::hash",
|
|
3354
|
-
"start":
|
|
3354
|
+
"start": 6265
|
|
3355
3355
|
}
|
|
3356
3356
|
],
|
|
3357
3357
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/delayed_public_mutable/delayed_public_mutable_values.nr",
|
|
3358
|
-
"source": "use crate::{\n delayed_public_mutable::{\n scheduled_delay_change::ScheduledDelayChange, scheduled_value_change::ScheduledValueChange,\n },\n hash::poseidon2_hash,\n traits::{Hash, Packable},\n utils::arrays,\n};\nuse std::meta::derive;\n\nmod test;\n\n/// DelayedPublicMutableValues is just a wrapper around ScheduledValueChange and ScheduledDelayChange that then allows us\n/// to wrap both of these values in WithHash. WithHash allows for efficient read of values in private.\n///\n/// Note that the WithHash optimization does not work in public (due to there being no unconstrained). But we also want\n/// to be able to read the values efficiently in public and we want to be able to read each value separately. Reading\n/// the values separately is tricky because ScheduledValueChange and ScheduledDelayChange are packed together (sdc and\n/// svc.timestamp_of_change are stored in the same slot). For that reason we expose `unpack_value_change` and\n/// `unpack_delay_change` functions that can be used to extract the values from the packed representation. This\n/// is \"hacky\" but there is no way around it.\n#[derive(Eq)]\npub struct DelayedPublicMutableValues<T, let INITIAL_DELAY: u64> {\n pub svc: ScheduledValueChange<T>,\n pub sdc: ScheduledDelayChange<INITIAL_DELAY>,\n}\n\nimpl<T, let INITIAL_DELAY: u64> DelayedPublicMutableValues<T, INITIAL_DELAY> {\n pub fn new(svc: ScheduledValueChange<T>, sdc: ScheduledDelayChange<INITIAL_DELAY>) -> Self {\n DelayedPublicMutableValues { svc, sdc }\n }\n}\n\n/// Extracts a ScheduledValueChange struct from the packed representation of the full DelayedPublicMutable.\n/// TODO: impl the packable trait for ScheduledValueChange.\npub fn unpack_value_change<T, let M: u32>(packed: [Field; 2 * M + 1]) -> ScheduledValueChange<T>\nwhere\n T: Packable<N = M>,\n{\n let svc_pre_packed = arrays::subarray(packed, 1);\n let svc_post_packed = arrays::subarray(packed, M + 1);\n\n // We first cast to u32 as the timestamp_of_change is packed into the same field as the delay change and it\n // occupies the first 32 bits of the field.\n let timestamp_of_change = (packed[0] as u32) as u64;\n ScheduledValueChange::new(\n T::unpack(svc_pre_packed),\n T::unpack(svc_post_packed),\n timestamp_of_change,\n )\n}\n\n/// Extracts a ScheduledDelayChange struct from 0th field of the packed representation of the full DelayedPublicMutable.\n/// This function expects to be called with just the first field of the packed representation, which contains sdc\n/// and svc timestamp_of_change. We'll discard the svc component.\npub fn unpack_delay_change<let INITIAL_DELAY: u64>(\n packed: Field,\n) -> ScheduledDelayChange<INITIAL_DELAY> {\n // This function expects to be called with just the first field of the packed representation, which contains sdc\n // and svc timestamp_of_change. We'll discard the svc component.\n let svc_timestamp_of_change = packed as u32;\n\n let mut tmp = (packed - svc_timestamp_of_change as Field) / TWO_POW_32;\n let sdc_timestamp_of_change = tmp as u32;\n\n tmp = (tmp - sdc_timestamp_of_change as Field) / TWO_POW_32;\n let sdc_post_is_some = (tmp as
|
|
3358
|
+
"source": "use crate::{\n delayed_public_mutable::{\n scheduled_delay_change::ScheduledDelayChange, scheduled_value_change::ScheduledValueChange,\n },\n hash::poseidon2_hash,\n traits::{Hash, Packable},\n utils::arrays,\n};\nuse std::meta::derive;\n\nmod test;\n\n/// DelayedPublicMutableValues is just a wrapper around ScheduledValueChange and ScheduledDelayChange that then allows us\n/// to wrap both of these values in WithHash. WithHash allows for efficient read of values in private.\n///\n/// Note that the WithHash optimization does not work in public (due to there being no unconstrained). But we also want\n/// to be able to read the values efficiently in public and we want to be able to read each value separately. Reading\n/// the values separately is tricky because ScheduledValueChange and ScheduledDelayChange are packed together (sdc and\n/// svc.timestamp_of_change are stored in the same slot). For that reason we expose `unpack_value_change` and\n/// `unpack_delay_change` functions that can be used to extract the values from the packed representation. This\n/// is \"hacky\" but there is no way around it.\n#[derive(Eq)]\npub struct DelayedPublicMutableValues<T, let INITIAL_DELAY: u64> {\n pub svc: ScheduledValueChange<T>,\n pub sdc: ScheduledDelayChange<INITIAL_DELAY>,\n}\n\nimpl<T, let INITIAL_DELAY: u64> DelayedPublicMutableValues<T, INITIAL_DELAY> {\n pub fn new(svc: ScheduledValueChange<T>, sdc: ScheduledDelayChange<INITIAL_DELAY>) -> Self {\n DelayedPublicMutableValues { svc, sdc }\n }\n}\n\n/// Extracts a ScheduledValueChange struct from the packed representation of the full DelayedPublicMutable.\n/// TODO: impl the packable trait for ScheduledValueChange.\npub fn unpack_value_change<T, let M: u32>(packed: [Field; 2 * M + 1]) -> ScheduledValueChange<T>\nwhere\n T: Packable<N = M>,\n{\n let svc_pre_packed = arrays::subarray(packed, 1);\n let svc_post_packed = arrays::subarray(packed, M + 1);\n\n // We first cast to u32 as the timestamp_of_change is packed into the same field as the delay change and it\n // occupies the first 32 bits of the field.\n let timestamp_of_change = (packed[0] as u32) as u64;\n ScheduledValueChange::new(\n T::unpack(svc_pre_packed),\n T::unpack(svc_post_packed),\n timestamp_of_change,\n )\n}\n\n/// Extracts a ScheduledDelayChange struct from 0th field of the packed representation of the full DelayedPublicMutable.\n/// This function expects to be called with just the first field of the packed representation, which contains sdc\n/// and svc timestamp_of_change. We'll discard the svc component.\npub fn unpack_delay_change<let INITIAL_DELAY: u64>(\n packed: Field,\n) -> ScheduledDelayChange<INITIAL_DELAY> {\n // This function expects to be called with just the first field of the packed representation, which contains sdc\n // and svc timestamp_of_change. We'll discard the svc component.\n let svc_timestamp_of_change = packed as u32;\n\n let mut tmp = (packed - svc_timestamp_of_change as Field) / TWO_POW_32;\n let sdc_timestamp_of_change = tmp as u32;\n\n tmp = (tmp - sdc_timestamp_of_change as Field) / TWO_POW_32;\n let sdc_post_is_some = (tmp as u8) % 2 != 0;\n\n tmp = (tmp - sdc_post_is_some as Field) / TWO_POW_8;\n let sdc_post_inner = tmp as u32;\n\n tmp = (tmp - sdc_post_inner as Field) / TWO_POW_32;\n let sdc_pre_is_some = (tmp as u8) % 2 != 0;\n\n tmp = (tmp - sdc_pre_is_some as Field) / TWO_POW_8;\n let sdc_pre_inner = tmp as u32;\n\n // Note that below we cast the values to u64 as that is the default type of timestamp in the system. Us packing\n // the values as u32 is a tech debt that is not worth tackling.\n ScheduledDelayChange {\n pre: if sdc_pre_is_some {\n Option::some(sdc_pre_inner as u64)\n } else {\n Option::none()\n },\n post: if sdc_post_is_some {\n Option::some(sdc_post_inner as u64)\n } else {\n Option::none()\n },\n timestamp_of_change: sdc_timestamp_of_change as u64,\n }\n}\n\n// Q: do these evaluate at comptime or runtime?\nglobal TWO_POW_32: Field = 2.pow_32(32);\nglobal TWO_POW_8: Field = 2.pow_32(8);\n\n// We pack to `2 * N + 1` fields because ScheduledValueChange contains T twice (hence `2 * N`) and we need one extra\n// field to store ScheduledDelayChange and the timestamp_of_change of ScheduledValueChange.\nimpl<T, let INITIAL_DELAY: u64> Packable for DelayedPublicMutableValues<T, INITIAL_DELAY>\nwhere\n T: Packable,\n{\n let N: u32 = 2 * <T as Packable>::N + 1;\n\n fn pack(self) -> [Field; Self::N] {\n let mut result = [0; Self::N];\n\n // We pack sdc.pre, sdc.post, sdc.timestamp_of_change and svc.timestamp_of_change into a single field as follows:\n // [ sdc.pre_inner: u32 | sdc.pre_is_some: u8 | sdc.post_inner: u32 | sdc.post_is_some: u8 | sdc.timestamp_of_change: u32 | svc.timestamp_of_change: u32 ]\n // Note that the code below no longer works after 2106 as by that time the timestamp will overflow u32. This is a tech debt that is not worth tackling.\n result[0] = self.svc.timestamp_of_change as Field\n + ((self.sdc.timestamp_of_change as Field) * 2.pow_32(32))\n + ((self.sdc.post.is_some() as Field) * 2.pow_32(64))\n + ((self.sdc.post.unwrap_unchecked() as Field) * 2.pow_32(72))\n + ((self.sdc.pre.is_some() as Field) * 2.pow_32(104))\n + ((self.sdc.pre.unwrap_unchecked() as Field) * 2.pow_32(112));\n\n // Pack the pre and post values from ScheduledValueChange\n let svc_pre_packed = self.svc.pre.pack();\n let svc_post_packed = self.svc.post.pack();\n for i in 0..<T as Packable>::N {\n result[i + 1] = svc_pre_packed[i];\n result[i + 1 + <T as Packable>::N] = svc_post_packed[i];\n }\n result\n }\n\n // Note: inefficient if all you want to unpack is the svc; use unpack_value_change instead.\n fn unpack(fields: [Field; Self::N]) -> Self {\n let svc = unpack_value_change::<T, _>(fields);\n let sdc = unpack_delay_change::<INITIAL_DELAY>(fields[0]);\n Self::new(svc, sdc)\n }\n}\n\nimpl<T, let INITIAL_DELAY: u64> Hash for DelayedPublicMutableValues<T, INITIAL_DELAY>\nwhere\n T: Packable,\n{\n fn hash(self) -> Field {\n poseidon2_hash(self.pack())\n }\n}\n"
|
|
3359
3359
|
},
|
|
3360
3360
|
"174": {
|
|
3361
3361
|
"function_locations": [
|
|
@@ -3587,131 +3587,123 @@
|
|
|
3587
3587
|
},
|
|
3588
3588
|
{
|
|
3589
3589
|
"name": "pedersen_hash",
|
|
3590
|
-
"start":
|
|
3590
|
+
"start": 2380
|
|
3591
3591
|
},
|
|
3592
3592
|
{
|
|
3593
3593
|
"name": "pedersen_hash_with_separator",
|
|
3594
|
-
"start":
|
|
3594
|
+
"start": 2537
|
|
3595
3595
|
},
|
|
3596
3596
|
{
|
|
3597
3597
|
"name": "derive_generators",
|
|
3598
|
-
"start":
|
|
3598
|
+
"start": 3531
|
|
3599
3599
|
},
|
|
3600
3600
|
{
|
|
3601
3601
|
"name": "__derive_generators",
|
|
3602
|
-
"start":
|
|
3603
|
-
},
|
|
3604
|
-
{
|
|
3605
|
-
"name": "from_field_unsafe",
|
|
3606
|
-
"start": 4265
|
|
3602
|
+
"start": 3890
|
|
3607
3603
|
},
|
|
3608
3604
|
{
|
|
3609
3605
|
"name": "poseidon2_permutation",
|
|
3610
|
-
"start":
|
|
3606
|
+
"start": 3968
|
|
3611
3607
|
},
|
|
3612
3608
|
{
|
|
3613
3609
|
"name": "poseidon2_permutation_internal",
|
|
3614
|
-
"start":
|
|
3610
|
+
"start": 4324
|
|
3615
3611
|
},
|
|
3616
3612
|
{
|
|
3617
3613
|
"name": "poseidon2_config_state_size",
|
|
3618
|
-
"start":
|
|
3614
|
+
"start": 4417
|
|
3619
3615
|
},
|
|
3620
3616
|
{
|
|
3621
3617
|
"name": "derive_hash",
|
|
3622
|
-
"start":
|
|
3618
|
+
"start": 4728
|
|
3623
3619
|
},
|
|
3624
3620
|
{
|
|
3625
3621
|
"name": "<impl BuildHasher for BuildHasherDefault<H>>::build_hasher",
|
|
3626
|
-
"start":
|
|
3622
|
+
"start": 5953
|
|
3627
3623
|
},
|
|
3628
3624
|
{
|
|
3629
3625
|
"name": "<impl Default for BuildHasherDefault<H>>::default",
|
|
3630
|
-
"start":
|
|
3626
|
+
"start": 6085
|
|
3631
3627
|
},
|
|
3632
3628
|
{
|
|
3633
3629
|
"name": "<impl Hash for Field>::hash",
|
|
3634
|
-
"start":
|
|
3635
|
-
},
|
|
3636
|
-
{
|
|
3637
|
-
"name": "<impl Hash for u1>::hash",
|
|
3638
|
-
"start": 7087
|
|
3630
|
+
"start": 6217
|
|
3639
3631
|
},
|
|
3640
3632
|
{
|
|
3641
3633
|
"name": "<impl Hash for u8>::hash",
|
|
3642
|
-
"start":
|
|
3634
|
+
"start": 6347
|
|
3643
3635
|
},
|
|
3644
3636
|
{
|
|
3645
3637
|
"name": "<impl Hash for u16>::hash",
|
|
3646
|
-
"start":
|
|
3638
|
+
"start": 6487
|
|
3647
3639
|
},
|
|
3648
3640
|
{
|
|
3649
3641
|
"name": "<impl Hash for u32>::hash",
|
|
3650
|
-
"start":
|
|
3642
|
+
"start": 6627
|
|
3651
3643
|
},
|
|
3652
3644
|
{
|
|
3653
3645
|
"name": "<impl Hash for u64>::hash",
|
|
3654
|
-
"start":
|
|
3646
|
+
"start": 6767
|
|
3655
3647
|
},
|
|
3656
3648
|
{
|
|
3657
3649
|
"name": "<impl Hash for u128>::hash",
|
|
3658
|
-
"start":
|
|
3650
|
+
"start": 6908
|
|
3659
3651
|
},
|
|
3660
3652
|
{
|
|
3661
3653
|
"name": "<impl Hash for i8>::hash",
|
|
3662
|
-
"start":
|
|
3654
|
+
"start": 7047
|
|
3663
3655
|
},
|
|
3664
3656
|
{
|
|
3665
3657
|
"name": "<impl Hash for i16>::hash",
|
|
3666
|
-
"start":
|
|
3658
|
+
"start": 7193
|
|
3667
3659
|
},
|
|
3668
3660
|
{
|
|
3669
3661
|
"name": "<impl Hash for i32>::hash",
|
|
3670
|
-
"start":
|
|
3662
|
+
"start": 7340
|
|
3671
3663
|
},
|
|
3672
3664
|
{
|
|
3673
3665
|
"name": "<impl Hash for i64>::hash",
|
|
3674
|
-
"start":
|
|
3666
|
+
"start": 7487
|
|
3675
3667
|
},
|
|
3676
3668
|
{
|
|
3677
3669
|
"name": "<impl Hash for bool>::hash",
|
|
3678
|
-
"start":
|
|
3670
|
+
"start": 7635
|
|
3679
3671
|
},
|
|
3680
3672
|
{
|
|
3681
3673
|
"name": "<impl Hash for ()>::hash",
|
|
3682
|
-
"start":
|
|
3674
|
+
"start": 7782
|
|
3683
3675
|
},
|
|
3684
3676
|
{
|
|
3685
3677
|
"name": "<impl Hash for [T; N]>::hash",
|
|
3686
|
-
"start":
|
|
3678
|
+
"start": 7914
|
|
3687
3679
|
},
|
|
3688
3680
|
{
|
|
3689
3681
|
"name": "<impl Hash for [T]>::hash",
|
|
3690
|
-
"start":
|
|
3682
|
+
"start": 8103
|
|
3691
3683
|
},
|
|
3692
3684
|
{
|
|
3693
3685
|
"name": "<impl Hash for (A, B)>::hash",
|
|
3694
|
-
"start":
|
|
3686
|
+
"start": 8343
|
|
3695
3687
|
},
|
|
3696
3688
|
{
|
|
3697
3689
|
"name": "<impl Hash for (A, B, C)>::hash",
|
|
3698
|
-
"start":
|
|
3690
|
+
"start": 8559
|
|
3699
3691
|
},
|
|
3700
3692
|
{
|
|
3701
3693
|
"name": "<impl Hash for (A, B, C, D)>::hash",
|
|
3702
|
-
"start":
|
|
3694
|
+
"start": 8822
|
|
3703
3695
|
},
|
|
3704
3696
|
{
|
|
3705
3697
|
"name": "<impl Hash for (A, B, C, D, E)>::hash",
|
|
3706
|
-
"start":
|
|
3698
|
+
"start": 9132
|
|
3707
3699
|
},
|
|
3708
3700
|
{
|
|
3709
3701
|
"name": "assert_pedersen",
|
|
3710
|
-
"start":
|
|
3702
|
+
"start": 9528
|
|
3711
3703
|
}
|
|
3712
3704
|
],
|
|
3713
3705
|
"path": "std/hash/mod.nr",
|
|
3714
|
-
"source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\nuse crate::static_assert;\n\n/// The size of the state accepted by the backend in `poseidon2_permutation`.\nglobal POSEIDON2_CONFIG_STATE_SIZE: u32 = poseidon2_config_state_size();\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s<let N: u32>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3<let N: u32>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3<let N: u32>(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment<let N: u32>(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator<let N: u32>(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n // we use the unsafe version because the multi_scalar_mul will constrain the scalars.\n points[i] = from_field_unsafe(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash<let N: u32>(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator<let N: u32>(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n crate::assert_constant(separator);\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = from_field_unsafe(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators<let N: u32, let M: u32>(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n crate::assert_constant(starting_index);\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators<let N: u32, let M: u32>(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\n#[field(bn254)]\n// Decompose the input 'bn254 scalar' into two 128 bits limbs.\n// It is called 'unsafe' because it does not assert the limbs are 128 bits\n// Assuming the limbs are 128 bits:\n// Assert the decomposition does not overflow the field size.\nfn from_field_unsafe(scalar: Field) -> EmbeddedCurveScalar {\n // Safety: xlo and xhi decomposition is checked below\n let (xlo, xhi) = unsafe { crate::field::bn254::decompose_hint(scalar) };\n // Check that the decomposition is correct\n assert_eq(scalar, xlo + crate::field::bn254::TWO_POW_128 * xhi);\n // Check that the decomposition does not overflow the field size\n let (a, b) = if xhi == crate::field::bn254::PHI {\n (xlo, crate::field::bn254::PLO)\n } else {\n (xhi, crate::field::bn254::PHI)\n };\n crate::field::bn254::assert_lt(a, b);\n\n EmbeddedCurveScalar { lo: xlo, hi: xhi }\n}\n\npub fn poseidon2_permutation<let N: u32>(input: [Field; N], state_len: u32) -> [Field; N] {\n assert_eq(input.len(), state_len);\n\n static_assert(\n N == POSEIDON2_CONFIG_STATE_SIZE,\n f\"the input length must equal the state size in the Poseidon2 config; expected {POSEIDON2_CONFIG_STATE_SIZE}, got {N}\",\n );\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal<let N: u32>(input: [Field; N]) -> [Field; N] {}\n\n#[foreign(poseidon2_config_state_size)]\ncomptime fn poseidon2_config_state_size() -> u32 {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash<H>(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault<H>;\n\nimpl<H> BuildHasher for BuildHasherDefault<H>\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl<H> Default for BuildHasherDefault<H>\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u1 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u8 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash<H>(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl<T, let N: u32> Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl<T> Hash for [T]\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl<A, B> Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl<A, B, C> Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl<A, B, C, D> Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl<A, B, C, D, E> Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n is_infinite: false,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n is_infinite: false,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n is_infinite: false,\n },\n );\n}\n"
|
|
3706
|
+
"source": "// Exposed only for usage in `std::meta`\npub(crate) mod poseidon2;\n\nuse crate::default::Default;\nuse crate::embedded_curve_ops::{\n EmbeddedCurvePoint, EmbeddedCurveScalar, multi_scalar_mul, multi_scalar_mul_array_return,\n};\nuse crate::meta::derive_via;\nuse crate::static_assert;\n\n/// The size of the state accepted by the backend in `poseidon2_permutation`.\nglobal POSEIDON2_CONFIG_STATE_SIZE: u32 = poseidon2_config_state_size();\n\n#[foreign(sha256_compression)]\n// docs:start:sha256_compression\npub fn sha256_compression(input: [u32; 16], state: [u32; 8]) -> [u32; 8] {}\n// docs:end:sha256_compression\n\n#[foreign(keccakf1600)]\n// docs:start:keccakf1600\npub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {}\n// docs:end:keccakf1600\n\npub mod keccak {\n #[deprecated(\"This function has been moved to std::hash::keccakf1600\")]\n pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] {\n super::keccakf1600(input)\n }\n}\n\n#[foreign(blake2s)]\n// docs:start:blake2s\npub fn blake2s<let N: u32>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake2s\n{}\n\n// docs:start:blake3\npub fn blake3<let N: u32>(input: [u8; N]) -> [u8; 32]\n// docs:end:blake3\n{\n if crate::runtime::is_unconstrained() {\n // Temporary measure while Barretenberg is main proving system.\n // Please open an issue if you're working on another proving system and running into problems due to this.\n crate::static_assert(\n N <= 1024,\n \"Barretenberg cannot prove blake3 hashes with inputs larger than 1024 bytes\",\n );\n }\n __blake3(input)\n}\n\n#[foreign(blake3)]\nfn __blake3<let N: u32>(input: [u8; N]) -> [u8; 32] {}\n\n// docs:start:pedersen_commitment\npub fn pedersen_commitment<let N: u32>(input: [Field; N]) -> EmbeddedCurvePoint {\n // docs:end:pedersen_commitment\n pedersen_commitment_with_separator(input, 0)\n}\n\n#[inline_always]\npub fn pedersen_commitment_with_separator<let N: u32>(\n input: [Field; N],\n separator: u32,\n) -> EmbeddedCurvePoint {\n let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N];\n for i in 0..N {\n points[i] = EmbeddedCurveScalar::from_field(input[i]);\n }\n let generators = derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n multi_scalar_mul(generators, points)\n}\n\n// docs:start:pedersen_hash\npub fn pedersen_hash<let N: u32>(input: [Field; N]) -> Field\n// docs:end:pedersen_hash\n{\n pedersen_hash_with_separator(input, 0)\n}\n\n#[no_predicates]\npub fn pedersen_hash_with_separator<let N: u32>(input: [Field; N], separator: u32) -> Field {\n let mut scalars: [EmbeddedCurveScalar; N + 1] = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N + 1];\n let mut generators: [EmbeddedCurvePoint; N + 1] =\n [EmbeddedCurvePoint::point_at_infinity(); N + 1];\n crate::assert_constant(separator);\n let domain_generators: [EmbeddedCurvePoint; N] =\n derive_generators(\"DEFAULT_DOMAIN_SEPARATOR\".as_bytes(), separator);\n\n for i in 0..N {\n scalars[i] = EmbeddedCurveScalar::from_field(input[i]);\n generators[i] = domain_generators[i];\n }\n scalars[N] = EmbeddedCurveScalar { lo: N as Field, hi: 0 as Field };\n\n let length_generator: [EmbeddedCurvePoint; 1] =\n derive_generators(\"pedersen_hash_length\".as_bytes(), 0);\n generators[N] = length_generator[0];\n multi_scalar_mul_array_return(generators, scalars, true)[0].x\n}\n\n#[field(bn254)]\n#[inline_always]\npub fn derive_generators<let N: u32, let M: u32>(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {\n crate::assert_constant(domain_separator_bytes);\n crate::assert_constant(starting_index);\n __derive_generators(domain_separator_bytes, starting_index)\n}\n\n#[builtin(derive_pedersen_generators)]\n#[field(bn254)]\nfn __derive_generators<let N: u32, let M: u32>(\n domain_separator_bytes: [u8; M],\n starting_index: u32,\n) -> [EmbeddedCurvePoint; N] {}\n\npub fn poseidon2_permutation<let N: u32>(input: [Field; N]) -> [Field; N] {\n static_assert(\n N == POSEIDON2_CONFIG_STATE_SIZE,\n f\"the input length must equal the state size in the Poseidon2 config; expected {POSEIDON2_CONFIG_STATE_SIZE}, got {N}\",\n );\n poseidon2_permutation_internal(input)\n}\n\n#[foreign(poseidon2_permutation)]\nfn poseidon2_permutation_internal<let N: u32>(input: [Field; N]) -> [Field; N] {}\n\n#[foreign(poseidon2_config_state_size)]\ncomptime fn poseidon2_config_state_size() -> u32 {}\n\n// Generic hashing support.\n// Partially ported and impacted by rust.\n\n// Hash trait shall be implemented per type.\n#[derive_via(derive_hash)]\npub trait Hash {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher;\n}\n\n// docs:start:derive_hash\ncomptime fn derive_hash(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::hash::Hash };\n let signature = quote { fn hash<H>(_self: Self, _state: &mut H) where H: $crate::hash::Hasher };\n let for_each_field = |name| quote { _self.$name.hash(_state); };\n crate::meta::make_trait_impl(\n s,\n name,\n signature,\n for_each_field,\n quote {},\n |fields| fields,\n )\n}\n// docs:end:derive_hash\n\n// Hasher trait shall be implemented by algorithms to provide hash-agnostic means.\n// TODO: consider making the types generic here ([u8], [Field], etc.)\npub trait Hasher {\n fn finish(self) -> Field;\n\n /// Returns the hash value without consuming the hasher.\n /// Override this for more efficient implementations that avoid copying.\n /// TODO: deprecate finish() and replace it\n fn finish_ref(&self) -> Field {\n (*self).finish()\n }\n\n fn write(&mut self, input: Field);\n}\n\n// BuildHasher is a factory trait, responsible for production of specific Hasher.\npub trait BuildHasher {\n type H: Hasher;\n\n fn build_hasher(self) -> H;\n}\n\npub struct BuildHasherDefault<H>;\n\nimpl<H> BuildHasher for BuildHasherDefault<H>\nwhere\n H: Hasher + Default,\n{\n type H = H;\n\n fn build_hasher(_self: Self) -> H {\n H::default()\n }\n}\n\nimpl<H> Default for BuildHasherDefault<H>\nwhere\n H: Hasher + Default,\n{\n fn default() -> Self {\n BuildHasherDefault {}\n }\n}\n\nimpl Hash for Field {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self);\n }\n}\n\nimpl Hash for u8 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u16 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u32 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u64 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for u128 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for i8 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u8 as Field);\n }\n}\n\nimpl Hash for i16 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u16 as Field);\n }\n}\n\nimpl Hash for i32 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u32 as Field);\n }\n}\n\nimpl Hash for i64 {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as u64 as Field);\n }\n}\n\nimpl Hash for bool {\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n H::write(state, self as Field);\n }\n}\n\nimpl Hash for () {\n fn hash<H>(_self: Self, _state: &mut H)\n where\n H: Hasher,\n {}\n}\n\nimpl<T, let N: u32> Hash for [T; N]\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl<T> Hash for [T]\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.len().hash(state);\n for elem in self {\n elem.hash(state);\n }\n }\n}\n\nimpl<A, B> Hash for (A, B)\nwhere\n A: Hash,\n B: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n }\n}\n\nimpl<A, B, C> Hash for (A, B, C)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n }\n}\n\nimpl<A, B, C, D> Hash for (A, B, C, D)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n }\n}\n\nimpl<A, B, C, D, E> Hash for (A, B, C, D, E)\nwhere\n A: Hash,\n B: Hash,\n C: Hash,\n D: Hash,\n E: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self.0.hash(state);\n self.1.hash(state);\n self.2.hash(state);\n self.3.hash(state);\n self.4.hash(state);\n }\n}\n\n// Some test vectors for Pedersen hash and Pedersen Commitment.\n// They have been generated using the same functions so the tests are for now useless\n// but they will be useful when we switch to Noir implementation.\n#[test]\nfn assert_pedersen() {\n assert_eq(\n pedersen_hash_with_separator([1], 1),\n 0x1b3f4b1a83092a13d8d1a59f7acb62aba15e7002f4440f2275edb99ebbc2305f,\n );\n assert_eq(\n pedersen_commitment_with_separator([1], 1),\n EmbeddedCurvePoint {\n x: 0x054aa86a73cb8a34525e5bbed6e43ba1198e860f5f3950268f71df4591bde402,\n y: 0x209dcfbf2cfb57f9f6046f44d71ac6faf87254afc7407c04eb621a6287cac126,\n },\n );\n\n assert_eq(\n pedersen_hash_with_separator([1, 2], 2),\n 0x26691c129448e9ace0c66d11f0a16d9014a9e8498ee78f4d69f0083168188255,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2], 2),\n EmbeddedCurvePoint {\n x: 0x2e2b3b191e49541fe468ec6877721d445dcaffe41728df0a0eafeb15e87b0753,\n y: 0x2ff4482400ad3a6228be17a2af33e2bcdf41be04795f9782bd96efe7e24f8778,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3], 3),\n 0x0bc694b7a1f8d10d2d8987d07433f26bd616a2d351bc79a3c540d85b6206dbe4,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3], 3),\n EmbeddedCurvePoint {\n x: 0x1fee4e8cf8d2f527caa2684236b07c4b1bad7342c01b0f75e9a877a71827dc85,\n y: 0x2f9fedb9a090697ab69bf04c8bc15f7385b3e4b68c849c1536e5ae15ff138fd1,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4], 4),\n 0xdae10fb32a8408521803905981a2b300d6a35e40e798743e9322b223a5eddc,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4], 4),\n EmbeddedCurvePoint {\n x: 0x07ae3e202811e1fca39c2d81eabe6f79183978e6f12be0d3b8eda095b79bdbc9,\n y: 0x0afc6f892593db6fbba60f2da558517e279e0ae04f95758587760ba193145014,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5], 5),\n 0xfc375b062c4f4f0150f7100dfb8d9b72a6d28582dd9512390b0497cdad9c22,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5], 5),\n EmbeddedCurvePoint {\n x: 0x1754b12bd475a6984a1094b5109eeca9838f4f81ac89c5f0a41dbce53189bb29,\n y: 0x2da030e3cfcdc7ddad80eaf2599df6692cae0717d4e9f7bfbee8d073d5d278f7,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6], 6),\n 0x1696ed13dc2730062a98ac9d8f9de0661bb98829c7582f699d0273b18c86a572,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6], 6),\n EmbeddedCurvePoint {\n x: 0x190f6c0e97ad83e1e28da22a98aae156da083c5a4100e929b77e750d3106a697,\n y: 0x1f4b60f34ef91221a0b49756fa0705da93311a61af73d37a0c458877706616fb,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n 0x128c0ff144fc66b6cb60eeac8a38e23da52992fc427b92397a7dffd71c45ede3,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7], 7),\n EmbeddedCurvePoint {\n x: 0x015441e9d29491b06563fac16fc76abf7a9534c715421d0de85d20dbe2965939,\n y: 0x1d2575b0276f4e9087e6e07c2cb75aa1baafad127af4be5918ef8a2ef2fea8fc,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n 0x2f960e117482044dfc99d12fece2ef6862fba9242be4846c7c9a3e854325a55c,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8], 8),\n EmbeddedCurvePoint {\n x: 0x1657737676968887fceb6dd516382ea13b3a2c557f509811cd86d5d1199bc443,\n y: 0x1f39f0cb569040105fa1e2f156521e8b8e08261e635a2b210bdc94e8d6d65f77,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n 0x0c96db0790602dcb166cc4699e2d306c479a76926b81c2cb2aaa92d249ec7be7,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9], 9),\n EmbeddedCurvePoint {\n x: 0x0a3ceae42d14914a432aa60ec7fded4af7dad7dd4acdbf2908452675ec67e06d,\n y: 0xfc19761eaaf621ad4aec9a8b2e84a4eceffdba78f60f8b9391b0bd9345a2f2,\n },\n );\n assert_eq(\n pedersen_hash_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n 0x2cd37505871bc460a62ea1e63c7fe51149df5d0801302cf1cbc48beb8dff7e94,\n );\n assert_eq(\n pedersen_commitment_with_separator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 10),\n EmbeddedCurvePoint {\n x: 0x2fb3f8b3d41ddde007c8c3c62550f9a9380ee546fcc639ffbb3fd30c8d8de30c,\n y: 0x300783be23c446b11a4c0fabf6c91af148937cea15fcf5fb054abf7f752ee245,\n },\n );\n}\n"
|
|
3715
3707
|
},
|
|
3716
3708
|
"181": {
|
|
3717
3709
|
"function_locations": [
|
|
@@ -3789,107 +3781,179 @@
|
|
|
3789
3781
|
},
|
|
3790
3782
|
"199": {
|
|
3791
3783
|
"function_locations": [
|
|
3784
|
+
{
|
|
3785
|
+
"name": "Point::generator",
|
|
3786
|
+
"start": 918
|
|
3787
|
+
},
|
|
3788
|
+
{
|
|
3789
|
+
"name": "Point::point_at_infinity",
|
|
3790
|
+
"start": 1068
|
|
3791
|
+
},
|
|
3792
|
+
{
|
|
3793
|
+
"name": "Point::double",
|
|
3794
|
+
"start": 1157
|
|
3795
|
+
},
|
|
3796
|
+
{
|
|
3797
|
+
"name": "Point::to_embedded",
|
|
3798
|
+
"start": 1260
|
|
3799
|
+
},
|
|
3800
|
+
{
|
|
3801
|
+
"name": "<impl From<EmbeddedCurvePoint> for Point>::from",
|
|
3802
|
+
"start": 1408
|
|
3803
|
+
},
|
|
3804
|
+
{
|
|
3805
|
+
"name": "<impl std::ops::Add for Point>::add",
|
|
3806
|
+
"start": 1553
|
|
3807
|
+
},
|
|
3808
|
+
{
|
|
3809
|
+
"name": "<impl std::ops::Sub for Point>::sub",
|
|
3810
|
+
"start": 1693
|
|
3811
|
+
},
|
|
3812
|
+
{
|
|
3813
|
+
"name": "<impl std::ops::Neg for Point>::neg",
|
|
3814
|
+
"start": 1819
|
|
3815
|
+
},
|
|
3816
|
+
{
|
|
3817
|
+
"name": "<impl Eq for Point>::eq",
|
|
3818
|
+
"start": 1959
|
|
3819
|
+
},
|
|
3792
3820
|
{
|
|
3793
3821
|
"name": "<impl Hash for Point>::hash",
|
|
3794
|
-
"start":
|
|
3822
|
+
"start": 2111
|
|
3795
3823
|
},
|
|
3796
3824
|
{
|
|
3797
3825
|
"name": "<impl Empty for Point>::empty",
|
|
3798
|
-
"start":
|
|
3826
|
+
"start": 2381
|
|
3827
|
+
},
|
|
3828
|
+
{
|
|
3829
|
+
"name": "<impl Serialize for Point>::serialize",
|
|
3830
|
+
"start": 2543
|
|
3831
|
+
},
|
|
3832
|
+
{
|
|
3833
|
+
"name": "<impl Serialize for Point>::stream_serialize",
|
|
3834
|
+
"start": 2670
|
|
3835
|
+
},
|
|
3836
|
+
{
|
|
3837
|
+
"name": "<impl Deserialize for Point>::deserialize",
|
|
3838
|
+
"start": 2904
|
|
3839
|
+
},
|
|
3840
|
+
{
|
|
3841
|
+
"name": "<impl Deserialize for Point>::stream_deserialize",
|
|
3842
|
+
"start": 3078
|
|
3799
3843
|
},
|
|
3800
3844
|
{
|
|
3801
3845
|
"name": "validate_on_curve",
|
|
3802
|
-
"start":
|
|
3846
|
+
"start": 3210
|
|
3803
3847
|
},
|
|
3804
3848
|
{
|
|
3805
3849
|
"name": "<impl Packable for Point>::pack",
|
|
3806
|
-
"start":
|
|
3850
|
+
"start": 3761
|
|
3807
3851
|
},
|
|
3808
3852
|
{
|
|
3809
3853
|
"name": "<impl Packable for Point>::unpack",
|
|
3810
|
-
"start":
|
|
3854
|
+
"start": 3843
|
|
3811
3855
|
},
|
|
3812
3856
|
{
|
|
3813
3857
|
"name": "tests::test_validate_on_curve_generator",
|
|
3814
|
-
"start":
|
|
3858
|
+
"start": 4012
|
|
3815
3859
|
},
|
|
3816
3860
|
{
|
|
3817
3861
|
"name": "tests::test_validate_on_curve_infinity",
|
|
3818
|
-
"start":
|
|
3862
|
+
"start": 4224
|
|
3819
3863
|
},
|
|
3820
3864
|
{
|
|
3821
3865
|
"name": "tests::test_validate_on_curve_invalid_point",
|
|
3822
|
-
"start":
|
|
3866
|
+
"start": 4506
|
|
3823
3867
|
},
|
|
3824
3868
|
{
|
|
3825
3869
|
"name": "tests::test_validate_on_curve_infinity_non_canonical_x",
|
|
3826
|
-
"start":
|
|
3870
|
+
"start": 4829
|
|
3827
3871
|
},
|
|
3828
3872
|
{
|
|
3829
3873
|
"name": "tests::test_validate_on_curve_infinity_non_canonical_y",
|
|
3830
|
-
"start":
|
|
3874
|
+
"start": 5175
|
|
3831
3875
|
}
|
|
3832
3876
|
],
|
|
3833
3877
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/point.nr",
|
|
3834
|
-
"source": "
|
|
3878
|
+
"source": "use crate::{\n hash::poseidon2_hash,\n traits::{Deserialize, Empty, Hash, Packable, Serialize},\n utils::{reader::Reader, writer::Writer},\n};\nuse std::embedded_curve_ops::EmbeddedCurvePoint;\n\npub global POINT_LENGTH: u32 = 3;\n\n// TODO(F-553): This custom `Point` struct is a temporary workaround. A newer version of Noir dropped the `is_infinite`\n// field from `EmbeddedCurvePoint` and changed its serialization from 3 fields to 2. To preserve backwards compatibility\n// of our onchain serialization format we re-introduced our own `Point` that wraps `EmbeddedCurvePoint` and keeps the\n// old 3-field layout. Once we're ready to take the breaking change (e.g. alongside the v5 oracle changes), delete this\n// struct, use `EmbeddedCurvePoint` directly and reduce `POINT_LENGTH` to 2.\npub struct Point {\n pub x: Field,\n pub y: Field,\n pub is_infinite: bool,\n}\n\nimpl Point {\n pub fn generator() -> Self {\n let g = EmbeddedCurvePoint::generator();\n Point { x: g.x, y: g.y, is_infinite: false }\n }\n\n pub fn point_at_infinity() -> Self {\n Point { x: 0, y: 0, is_infinite: true }\n }\n\n pub fn double(self) -> Self {\n self.to_embedded().double().into()\n }\n\n pub fn to_embedded(self) -> EmbeddedCurvePoint {\n EmbeddedCurvePoint { x: self.x, y: self.y }\n }\n}\n\nimpl From<EmbeddedCurvePoint> for Point {\n fn from(p: EmbeddedCurvePoint) -> Self {\n Point { x: p.x, y: p.y, is_infinite: p.is_infinite() }\n }\n}\n\nimpl std::ops::Add for Point {\n fn add(self, other: Point) -> Point {\n (self.to_embedded() + other.to_embedded()).into()\n }\n}\n\nimpl std::ops::Sub for Point {\n fn sub(self, other: Point) -> Point {\n (self.to_embedded() - other.to_embedded()).into()\n }\n}\n\nimpl std::ops::Neg for Point {\n fn neg(self) -> Point {\n Point { x: self.x, y: -self.y, is_infinite: self.is_infinite }\n }\n}\n\nimpl Eq for Point {\n fn eq(self, other: Point) -> bool {\n (self.x == other.x) & (self.y == other.y) & (self.is_infinite == other.is_infinite)\n }\n}\n\nimpl Hash for Point {\n fn hash(self) -> Field {\n poseidon2_hash(self.serialize())\n }\n}\n\nimpl Empty for Point {\n /// Note: Does not return a valid point on curve - instead represents an empty/\"unpopulated\" point struct (e.g.\n /// empty/unpopulated value in an array of points).\n fn empty() -> Self {\n Point { x: 0, y: 0, is_infinite: false }\n }\n}\n\nimpl Serialize for Point {\n let N: u32 = POINT_LENGTH;\n\n fn serialize(self) -> [Field; Self::N] {\n [self.x, self.y, self.is_infinite as Field]\n }\n\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self.x);\n writer.write(self.y);\n writer.write(self.is_infinite as Field);\n }\n}\n\nimpl Deserialize for Point {\n let N: u32 = POINT_LENGTH;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n Point { x: fields[0], y: fields[1], is_infinite: fields[2] != 0 }\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n Point { x: reader.read(), y: reader.read(), is_infinite: reader.read_bool() }\n }\n}\n\npub fn validate_on_curve(p: Point) {\n // y^2 == x^3 - 17\n let x = p.x;\n let y = p.y;\n if p.is_infinite {\n // Assert the canonical representation of infinity\n assert_eq(x, 0, \"Point at infinity should have canonical representation (0 0)\");\n assert_eq(y, 0, \"Point at infinity should have canonical representation (0 0)\");\n } else {\n assert_eq(y * y, x * x * x - 17, \"Point not on curve\");\n }\n}\n\n// TODO(#11356): use compact representation here.\nimpl Packable for Point {\n let N: u32 = POINT_LENGTH;\n\n fn pack(self) -> [Field; Self::N] {\n self.serialize()\n }\n\n fn unpack(packed: [Field; Self::N]) -> Self {\n Self::deserialize(packed)\n }\n}\n\nmod tests {\n use super::{Point, validate_on_curve};\n\n #[test]\n unconstrained fn test_validate_on_curve_generator() {\n // The generator point should be on the curve\n let generator = Point::generator();\n validate_on_curve(generator);\n }\n\n #[test]\n unconstrained fn test_validate_on_curve_infinity() {\n // Canonical infinite point (x=0, y=0) should pass\n let infinity = Point { x: 0, y: 0, is_infinite: true };\n validate_on_curve(infinity);\n }\n\n #[test(should_fail_with = \"Point not on curve\")]\n unconstrained fn test_validate_on_curve_invalid_point() {\n // A point not on the curve should fail\n let invalid = Point { x: 1, y: 1, is_infinite: false };\n validate_on_curve(invalid);\n }\n\n #[test(should_fail_with = \"Point at infinity should have canonical representation (0 0)\")]\n unconstrained fn test_validate_on_curve_infinity_non_canonical_x() {\n // Infinite point with non-zero x should fail\n let invalid_infinity = Point { x: 1, y: 0, is_infinite: true };\n validate_on_curve(invalid_infinity);\n }\n\n #[test(should_fail_with = \"Point at infinity should have canonical representation (0 0)\")]\n unconstrained fn test_validate_on_curve_infinity_non_canonical_y() {\n // Infinite point with non-zero y should fail\n let invalid_infinity = Point { x: 0, y: 1, is_infinite: true };\n validate_on_curve(invalid_infinity);\n }\n}\n"
|
|
3835
3879
|
},
|
|
3836
3880
|
"207": {
|
|
3837
3881
|
"function_locations": [
|
|
3838
3882
|
{
|
|
3839
3883
|
"name": "<impl ToPoint for NpkM>::to_point",
|
|
3840
|
-
"start":
|
|
3884
|
+
"start": 646
|
|
3841
3885
|
},
|
|
3842
3886
|
{
|
|
3843
3887
|
"name": "<impl Hash for NpkM>::hash",
|
|
3844
|
-
"start":
|
|
3888
|
+
"start": 816
|
|
3845
3889
|
},
|
|
3846
3890
|
{
|
|
3847
3891
|
"name": "<impl ToPoint for IvpkM>::to_point",
|
|
3848
|
-
"start":
|
|
3892
|
+
"start": 991
|
|
3849
3893
|
},
|
|
3850
3894
|
{
|
|
3851
3895
|
"name": "<impl Hash for OvpkM>::hash",
|
|
3852
|
-
"start":
|
|
3896
|
+
"start": 1152
|
|
3853
3897
|
},
|
|
3854
3898
|
{
|
|
3855
3899
|
"name": "<impl ToPoint for OvpkM>::to_point",
|
|
3856
|
-
"start":
|
|
3900
|
+
"start": 1245
|
|
3857
3901
|
},
|
|
3858
3902
|
{
|
|
3859
3903
|
"name": "<impl ToPoint for TpkM>::to_point",
|
|
3860
|
-
"start":
|
|
3904
|
+
"start": 1411
|
|
3861
3905
|
},
|
|
3862
3906
|
{
|
|
3863
3907
|
"name": "<impl Default for PublicKeys>::default",
|
|
3864
|
-
"start":
|
|
3908
|
+
"start": 1649
|
|
3865
3909
|
},
|
|
3866
3910
|
{
|
|
3867
3911
|
"name": "PublicKeys::hash",
|
|
3868
|
-
"start":
|
|
3912
|
+
"start": 2293
|
|
3869
3913
|
},
|
|
3870
3914
|
{
|
|
3871
3915
|
"name": "PublicKeys::validate_on_curve",
|
|
3872
|
-
"start":
|
|
3916
|
+
"start": 2492
|
|
3917
|
+
},
|
|
3918
|
+
{
|
|
3919
|
+
"name": "PublicKeys::validate_non_infinity",
|
|
3920
|
+
"start": 2722
|
|
3873
3921
|
},
|
|
3874
3922
|
{
|
|
3875
3923
|
"name": "<impl ToPoint for AddressPoint>::to_point",
|
|
3876
|
-
"start":
|
|
3924
|
+
"start": 3207
|
|
3877
3925
|
},
|
|
3878
3926
|
{
|
|
3879
3927
|
"name": "test::compute_public_keys_hash",
|
|
3880
|
-
"start":
|
|
3928
|
+
"start": 3517
|
|
3929
|
+
},
|
|
3930
|
+
{
|
|
3931
|
+
"name": "test::test_validate_on_curve",
|
|
3932
|
+
"start": 4231
|
|
3933
|
+
},
|
|
3934
|
+
{
|
|
3935
|
+
"name": "test::test_validate_not_on_curve",
|
|
3936
|
+
"start": 4690
|
|
3937
|
+
},
|
|
3938
|
+
{
|
|
3939
|
+
"name": "test::test_validate_non_infinity",
|
|
3940
|
+
"start": 5151
|
|
3941
|
+
},
|
|
3942
|
+
{
|
|
3943
|
+
"name": "test::test_validate_infinity",
|
|
3944
|
+
"start": 5621
|
|
3881
3945
|
},
|
|
3882
3946
|
{
|
|
3883
3947
|
"name": "test::compute_default_hash",
|
|
3884
|
-
"start":
|
|
3948
|
+
"start": 6015
|
|
3885
3949
|
},
|
|
3886
3950
|
{
|
|
3887
3951
|
"name": "test::serde",
|
|
3888
|
-
"start":
|
|
3952
|
+
"start": 6393
|
|
3889
3953
|
}
|
|
3890
3954
|
],
|
|
3891
3955
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/public_keys.nr",
|
|
3892
|
-
"source": "use crate::{\n address::public_keys_hash::PublicKeysHash,\n constants::{\n DEFAULT_IVPK_M_X, DEFAULT_IVPK_M_Y, DEFAULT_NPK_M_X, DEFAULT_NPK_M_Y, DEFAULT_OVPK_M_X,\n DEFAULT_OVPK_M_Y, DEFAULT_TPK_M_X, DEFAULT_TPK_M_Y, DOM_SEP__PUBLIC_KEYS_HASH,\n },\n hash::poseidon2_hash_with_separator,\n point::validate_on_curve,\n traits::{Deserialize, Hash, Serialize},\n};\n\nuse std::{default::Default, meta::derive};\
|
|
3956
|
+
"source": "use crate::{\n address::public_keys_hash::PublicKeysHash,\n constants::{\n DEFAULT_IVPK_M_X, DEFAULT_IVPK_M_Y, DEFAULT_NPK_M_X, DEFAULT_NPK_M_Y, DEFAULT_OVPK_M_X,\n DEFAULT_OVPK_M_Y, DEFAULT_TPK_M_X, DEFAULT_TPK_M_Y, DOM_SEP__PUBLIC_KEYS_HASH,\n },\n hash::poseidon2_hash_with_separator,\n point::validate_on_curve,\n traits::{Deserialize, Hash, Serialize},\n};\n\nuse crate::point::Point;\nuse std::{default::Default, meta::derive};\n\npub trait ToPoint {\n fn to_point(self) -> Point;\n}\n\n#[derive(Deserialize, Eq, Serialize)]\npub struct NpkM {\n pub inner: Point,\n}\n\nimpl ToPoint for NpkM {\n fn to_point(self) -> Point {\n self.inner\n }\n}\n\n// Note: If we store npk_m_hash directly we can remove this trait implementation. See #8091\nimpl Hash for NpkM {\n fn hash(self) -> Field {\n self.inner.hash()\n }\n}\n\n#[derive(Deserialize, Eq, Serialize)]\npub struct IvpkM {\n pub inner: Point,\n}\n\nimpl ToPoint for IvpkM {\n fn to_point(self) -> Point {\n self.inner\n }\n}\n\n#[derive(Deserialize, Eq, Serialize)]\npub struct OvpkM {\n pub inner: Point,\n}\n\nimpl Hash for OvpkM {\n fn hash(self) -> Field {\n self.inner.hash()\n }\n}\n\nimpl ToPoint for OvpkM {\n fn to_point(self) -> Point {\n self.inner\n }\n}\n\n#[derive(Deserialize, Eq, Serialize)]\npub struct TpkM {\n pub inner: Point,\n}\n\nimpl ToPoint for TpkM {\n fn to_point(self) -> Point {\n self.inner\n }\n}\n\n#[derive(Deserialize, Eq, Serialize)]\npub struct PublicKeys {\n pub npk_m: NpkM,\n pub ivpk_m: IvpkM,\n pub ovpk_m: OvpkM,\n pub tpk_m: TpkM,\n}\n\nimpl Default for PublicKeys {\n fn default() -> Self {\n PublicKeys {\n npk_m: NpkM {\n inner: Point { x: DEFAULT_NPK_M_X, y: DEFAULT_NPK_M_Y, is_infinite: false },\n },\n ivpk_m: IvpkM {\n inner: Point { x: DEFAULT_IVPK_M_X, y: DEFAULT_IVPK_M_Y, is_infinite: false },\n },\n ovpk_m: OvpkM {\n inner: Point { x: DEFAULT_OVPK_M_X, y: DEFAULT_OVPK_M_Y, is_infinite: false },\n },\n tpk_m: TpkM {\n inner: Point { x: DEFAULT_TPK_M_X, y: DEFAULT_TPK_M_Y, is_infinite: false },\n },\n }\n }\n}\n\nimpl PublicKeys {\n pub fn hash(self) -> PublicKeysHash {\n PublicKeysHash::from_field(poseidon2_hash_with_separator(\n self.serialize(),\n DOM_SEP__PUBLIC_KEYS_HASH as Field,\n ))\n }\n\n pub fn validate_on_curve(self) {\n validate_on_curve(self.npk_m.inner);\n validate_on_curve(self.ivpk_m.inner);\n validate_on_curve(self.ovpk_m.inner);\n validate_on_curve(self.tpk_m.inner);\n }\n\n pub fn validate_non_infinity(self) {\n assert_eq(self.npk_m.inner.is_infinite, false, \"NpkM is the point at infinity\");\n assert_eq(self.ivpk_m.inner.is_infinite, false, \"IvpkM is the point at infinity\");\n assert_eq(self.ovpk_m.inner.is_infinite, false, \"OvpkM is the point at infinity\");\n assert_eq(self.tpk_m.inner.is_infinite, false, \"TpkM is the point at infinity\");\n }\n}\n\npub struct AddressPoint {\n pub inner: Point,\n}\n\nimpl ToPoint for AddressPoint {\n fn to_point(self) -> Point {\n self.inner\n }\n}\n\nmod test {\n use crate::point::Point;\n use crate::{\n point::POINT_LENGTH,\n public_keys::{IvpkM, NpkM, OvpkM, PublicKeys, TpkM},\n traits::{Deserialize, Serialize},\n };\n use std::ops::Neg;\n\n #[test]\n unconstrained fn compute_public_keys_hash() {\n let keys = PublicKeys {\n npk_m: NpkM { inner: Point { x: 1, y: 2, is_infinite: false } },\n ivpk_m: IvpkM { inner: Point { x: 3, y: 4, is_infinite: false } },\n ovpk_m: OvpkM { inner: Point { x: 5, y: 6, is_infinite: false } },\n tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } },\n };\n\n let actual = keys.hash();\n\n // The following value was generated by `public_keys.test.ts`.\n let expected_public_keys_hash =\n 0x056998309f6c119e4d753e404f94fef859dddfa530a9379634ceb0854b29bf7a;\n\n assert(actual.to_field() == expected_public_keys_hash);\n }\n\n #[test]\n unconstrained fn test_validate_on_curve() {\n let keys = PublicKeys {\n npk_m: NpkM { inner: Point::generator() },\n ivpk_m: IvpkM { inner: Point::generator().double() },\n ovpk_m: OvpkM { inner: Point::generator().neg() },\n tpk_m: TpkM { inner: Point::generator() + Point::generator().double() },\n };\n\n keys.validate_on_curve();\n }\n\n #[test(should_fail_with = \"Point not on curve\")]\n unconstrained fn test_validate_not_on_curve() {\n let keys = PublicKeys {\n npk_m: NpkM { inner: Point { x: 1, y: 2, is_infinite: false } },\n ivpk_m: IvpkM { inner: Point { x: 3, y: 4, is_infinite: false } },\n ovpk_m: OvpkM { inner: Point { x: 5, y: 6, is_infinite: false } },\n tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } },\n };\n\n keys.validate_on_curve();\n }\n\n #[test]\n unconstrained fn test_validate_non_infinity() {\n let keys = PublicKeys {\n npk_m: NpkM { inner: Point::generator() },\n ivpk_m: IvpkM { inner: Point::generator().double() },\n ovpk_m: OvpkM { inner: Point::generator().neg() },\n tpk_m: TpkM { inner: Point::generator() + Point::generator().double() },\n };\n\n keys.validate_non_infinity();\n }\n\n #[test(should_fail_with = \"TpkM is the point at infinity\")]\n unconstrained fn test_validate_infinity() {\n let keys = PublicKeys {\n npk_m: NpkM { inner: Point::generator() },\n ivpk_m: IvpkM { inner: Point::generator().double() },\n ovpk_m: OvpkM { inner: Point::generator().neg() },\n tpk_m: TpkM { inner: Point::point_at_infinity() },\n };\n\n keys.validate_non_infinity();\n }\n\n #[test]\n unconstrained fn compute_default_hash() {\n let keys = PublicKeys::default();\n\n let actual = keys.hash();\n\n // The following value was generated by `public_keys.test.ts`.\n let test_data_default_hash =\n 0x023547e676dba19784188825b901a0e70d8ad978300d21d6185a54281b734da0;\n\n assert(actual.to_field() == test_data_default_hash);\n }\n\n #[test]\n unconstrained fn serde() {\n let keys = PublicKeys {\n npk_m: NpkM { inner: Point { x: 1, y: 2, is_infinite: false } },\n ivpk_m: IvpkM { inner: Point { x: 3, y: 4, is_infinite: false } },\n ovpk_m: OvpkM { inner: Point { x: 5, y: 6, is_infinite: false } },\n tpk_m: TpkM { inner: Point { x: 7, y: 8, is_infinite: false } },\n };\n\n // We use the PUBLIC_KEYS_LENGTH constant to ensure that there is a match between the derived trait\n let serialized: [Field; POINT_LENGTH * 4] = keys.serialize();\n let deserialized = PublicKeys::deserialize(serialized);\n\n assert_eq(keys, deserialized);\n }\n}\n"
|
|
3893
3957
|
},
|
|
3894
3958
|
"212": {
|
|
3895
3959
|
"function_locations": [
|
|
@@ -3917,115 +3981,115 @@
|
|
|
3917
3981
|
},
|
|
3918
3982
|
{
|
|
3919
3983
|
"name": "<impl Packable for u8>::pack",
|
|
3920
|
-
"start":
|
|
3984
|
+
"start": 767
|
|
3921
3985
|
},
|
|
3922
3986
|
{
|
|
3923
3987
|
"name": "<impl Packable for u8>::unpack",
|
|
3924
|
-
"start":
|
|
3988
|
+
"start": 869
|
|
3925
3989
|
},
|
|
3926
3990
|
{
|
|
3927
3991
|
"name": "<impl Packable for u16>::pack",
|
|
3928
|
-
"start":
|
|
3992
|
+
"start": 1021
|
|
3929
3993
|
},
|
|
3930
3994
|
{
|
|
3931
3995
|
"name": "<impl Packable for u16>::unpack",
|
|
3932
|
-
"start":
|
|
3996
|
+
"start": 1123
|
|
3933
3997
|
},
|
|
3934
3998
|
{
|
|
3935
3999
|
"name": "<impl Packable for u32>::pack",
|
|
3936
|
-
"start":
|
|
4000
|
+
"start": 1276
|
|
3937
4001
|
},
|
|
3938
4002
|
{
|
|
3939
4003
|
"name": "<impl Packable for u32>::unpack",
|
|
3940
|
-
"start":
|
|
4004
|
+
"start": 1378
|
|
3941
4005
|
},
|
|
3942
4006
|
{
|
|
3943
4007
|
"name": "<impl Packable for u64>::pack",
|
|
3944
|
-
"start":
|
|
4008
|
+
"start": 1531
|
|
3945
4009
|
},
|
|
3946
4010
|
{
|
|
3947
4011
|
"name": "<impl Packable for u64>::unpack",
|
|
3948
|
-
"start":
|
|
4012
|
+
"start": 1633
|
|
3949
4013
|
},
|
|
3950
4014
|
{
|
|
3951
4015
|
"name": "<impl Packable for u128>::pack",
|
|
3952
|
-
"start":
|
|
4016
|
+
"start": 1788
|
|
3953
4017
|
},
|
|
3954
4018
|
{
|
|
3955
4019
|
"name": "<impl Packable for u128>::unpack",
|
|
3956
|
-
"start":
|
|
4020
|
+
"start": 1890
|
|
3957
4021
|
},
|
|
3958
4022
|
{
|
|
3959
4023
|
"name": "<impl Packable for Field>::pack",
|
|
3960
|
-
"start":
|
|
4024
|
+
"start": 2048
|
|
3961
4025
|
},
|
|
3962
4026
|
{
|
|
3963
4027
|
"name": "<impl Packable for Field>::unpack",
|
|
3964
|
-
"start":
|
|
4028
|
+
"start": 2141
|
|
3965
4029
|
},
|
|
3966
4030
|
{
|
|
3967
4031
|
"name": "<impl Packable for i8>::pack",
|
|
3968
|
-
"start":
|
|
4032
|
+
"start": 2285
|
|
3969
4033
|
},
|
|
3970
4034
|
{
|
|
3971
4035
|
"name": "<impl Packable for i8>::unpack",
|
|
3972
|
-
"start":
|
|
4036
|
+
"start": 2393
|
|
3973
4037
|
},
|
|
3974
4038
|
{
|
|
3975
4039
|
"name": "<impl Packable for i16>::pack",
|
|
3976
|
-
"start":
|
|
4040
|
+
"start": 2551
|
|
3977
4041
|
},
|
|
3978
4042
|
{
|
|
3979
4043
|
"name": "<impl Packable for i16>::unpack",
|
|
3980
|
-
"start":
|
|
4044
|
+
"start": 2660
|
|
3981
4045
|
},
|
|
3982
4046
|
{
|
|
3983
4047
|
"name": "<impl Packable for i32>::pack",
|
|
3984
|
-
"start":
|
|
4048
|
+
"start": 2820
|
|
3985
4049
|
},
|
|
3986
4050
|
{
|
|
3987
4051
|
"name": "<impl Packable for i32>::unpack",
|
|
3988
|
-
"start":
|
|
4052
|
+
"start": 2929
|
|
3989
4053
|
},
|
|
3990
4054
|
{
|
|
3991
4055
|
"name": "<impl Packable for i64>::pack",
|
|
3992
|
-
"start":
|
|
4056
|
+
"start": 3089
|
|
3993
4057
|
},
|
|
3994
4058
|
{
|
|
3995
4059
|
"name": "<impl Packable for i64>::unpack",
|
|
3996
|
-
"start":
|
|
4060
|
+
"start": 3198
|
|
3997
4061
|
},
|
|
3998
4062
|
{
|
|
3999
4063
|
"name": "<impl Packable for [T; M]>::pack",
|
|
4000
|
-
"start":
|
|
4064
|
+
"start": 3407
|
|
4001
4065
|
},
|
|
4002
4066
|
{
|
|
4003
4067
|
"name": "<impl Packable for [T; M]>::unpack",
|
|
4004
|
-
"start":
|
|
4068
|
+
"start": 3769
|
|
4005
4069
|
},
|
|
4006
4070
|
{
|
|
4007
4071
|
"name": "test_u16_packing",
|
|
4008
|
-
"start":
|
|
4072
|
+
"start": 4014
|
|
4009
4073
|
},
|
|
4010
4074
|
{
|
|
4011
4075
|
"name": "test_i8_packing",
|
|
4012
|
-
"start":
|
|
4076
|
+
"start": 4110
|
|
4013
4077
|
},
|
|
4014
4078
|
{
|
|
4015
4079
|
"name": "test_i16_packing",
|
|
4016
|
-
"start":
|
|
4080
|
+
"start": 4206
|
|
4017
4081
|
},
|
|
4018
4082
|
{
|
|
4019
4083
|
"name": "test_i32_packing",
|
|
4020
|
-
"start":
|
|
4084
|
+
"start": 4304
|
|
4021
4085
|
},
|
|
4022
4086
|
{
|
|
4023
4087
|
"name": "test_i64_packing",
|
|
4024
|
-
"start":
|
|
4088
|
+
"start": 4402
|
|
4025
4089
|
}
|
|
4026
4090
|
],
|
|
4027
4091
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr",
|
|
4028
|
-
"source": "use crate::traits::Packable;\n\nglobal BOOL_PACKED_LEN: u32 = 1;\nglobal U8_PACKED_LEN: u32 = 1;\nglobal U16_PACKED_LEN: u32 = 1;\nglobal U32_PACKED_LEN: u32 = 1;\nglobal U64_PACKED_LEN: u32 = 1;\nglobal U128_PACKED_LEN: u32 = 1;\nglobal FIELD_PACKED_LEN: u32 = 1;\nglobal I8_PACKED_LEN: u32 = 1;\nglobal I16_PACKED_LEN: u32 = 1;\nglobal I32_PACKED_LEN: u32 = 1;\nglobal I64_PACKED_LEN: u32 = 1;\n\nimpl Packable for bool {\n let N: u32 = BOOL_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> bool {\n (fields[0] as
|
|
4092
|
+
"source": "use crate::traits::Packable;\n\nglobal BOOL_PACKED_LEN: u32 = 1;\nglobal U8_PACKED_LEN: u32 = 1;\nglobal U16_PACKED_LEN: u32 = 1;\nglobal U32_PACKED_LEN: u32 = 1;\nglobal U64_PACKED_LEN: u32 = 1;\nglobal U128_PACKED_LEN: u32 = 1;\nglobal FIELD_PACKED_LEN: u32 = 1;\nglobal I8_PACKED_LEN: u32 = 1;\nglobal I16_PACKED_LEN: u32 = 1;\nglobal I32_PACKED_LEN: u32 = 1;\nglobal I64_PACKED_LEN: u32 = 1;\n\nimpl Packable for bool {\n let N: u32 = BOOL_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> bool {\n (fields[0] as u8) % 2 != 0\n }\n}\n\nimpl Packable for u8 {\n let N: u32 = U8_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u8\n }\n}\n\nimpl Packable for u16 {\n let N: u32 = U16_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u16\n }\n}\n\nimpl Packable for u32 {\n let N: u32 = U32_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u32\n }\n}\n\nimpl Packable for u64 {\n let N: u32 = U64_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u64\n }\n}\n\nimpl Packable for u128 {\n let N: u32 = U128_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u128\n }\n}\n\nimpl Packable for Field {\n let N: u32 = FIELD_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0]\n }\n}\n\nimpl Packable for i8 {\n let N: u32 = I8_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as u8 as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u8 as i8\n }\n}\n\nimpl Packable for i16 {\n let N: u32 = I16_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as u16 as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u16 as i16\n }\n}\n\nimpl Packable for i32 {\n let N: u32 = I32_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as u32 as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u32 as i32\n }\n}\n\nimpl Packable for i64 {\n let N: u32 = I64_PACKED_LEN;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n [self as u64 as Field]\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n fields[0] as u64 as i64\n }\n}\n\nimpl<T, let M: u32> Packable for [T; M]\nwhere\n T: Packable,\n{\n let N: u32 = M * <T as Packable>::N;\n\n #[inline_always]\n fn pack(self) -> [Field; Self::N] {\n let mut result: [Field; Self::N] = std::mem::zeroed();\n for i in 0..M {\n let serialized = self[i].pack();\n for j in 0..<T as Packable>::N {\n result[i * <T as Packable>::N + j] = serialized[j];\n }\n }\n result\n }\n\n #[inline_always]\n fn unpack(fields: [Field; Self::N]) -> Self {\n let mut reader = crate::utils::reader::Reader::new(fields);\n let result: [T; M] = std::mem::zeroed();\n reader.read_struct_array::<T, <T as Packable>::N, M>(Packable::unpack, result)\n }\n}\n\n#[test]\nfn test_u16_packing() {\n let a: u16 = 10;\n assert_eq(a, u16::unpack(a.pack()));\n}\n\n#[test]\nfn test_i8_packing() {\n let a: i8 = -10;\n assert_eq(a, i8::unpack(a.pack()));\n}\n\n#[test]\nfn test_i16_packing() {\n let a: i16 = -10;\n assert_eq(a, i16::unpack(a.pack()));\n}\n\n#[test]\nfn test_i32_packing() {\n let a: i32 = -10;\n assert_eq(a, i32::unpack(a.pack()));\n}\n\n#[test]\nfn test_i64_packing() {\n let a: i64 = -10;\n assert_eq(a, i64::unpack(a.pack()));\n}\n"
|
|
4029
4093
|
},
|
|
4030
4094
|
"239": {
|
|
4031
4095
|
"function_locations": [
|
|
@@ -4043,31 +4107,31 @@
|
|
|
4043
4107
|
},
|
|
4044
4108
|
{
|
|
4045
4109
|
"name": "Poseidon2::absorb",
|
|
4046
|
-
"start":
|
|
4110
|
+
"start": 923
|
|
4047
4111
|
},
|
|
4048
4112
|
{
|
|
4049
4113
|
"name": "Poseidon2::squeeze",
|
|
4050
|
-
"start":
|
|
4114
|
+
"start": 1453
|
|
4051
4115
|
},
|
|
4052
4116
|
{
|
|
4053
4117
|
"name": "Poseidon2::hash_internal",
|
|
4054
|
-
"start":
|
|
4118
|
+
"start": 1814
|
|
4055
4119
|
},
|
|
4056
4120
|
{
|
|
4057
4121
|
"name": "<impl Hasher for Poseidon2Hasher>::finish",
|
|
4058
|
-
"start":
|
|
4122
|
+
"start": 4105
|
|
4059
4123
|
},
|
|
4060
4124
|
{
|
|
4061
4125
|
"name": "<impl Hasher for Poseidon2Hasher>::write",
|
|
4062
|
-
"start":
|
|
4126
|
+
"start": 4426
|
|
4063
4127
|
},
|
|
4064
4128
|
{
|
|
4065
4129
|
"name": "<impl Default for Poseidon2Hasher>::default",
|
|
4066
|
-
"start":
|
|
4130
|
+
"start": 4549
|
|
4067
4131
|
}
|
|
4068
4132
|
],
|
|
4069
|
-
"path": "/home/aztec-dev/nargo/github.com/noir-lang/poseidon/v0.
|
|
4070
|
-
"source": "use std::default::Default;\nuse std::hash::Hasher;\n\nglobal RATE: u32 = 3;\n\npub struct Poseidon2 {\n cache: [Field; 3],\n state: [Field; 4],\n cache_size: u32,\n squeeze_mode: bool, // 0 => absorb, 1 => squeeze\n}\n\nimpl Poseidon2 {\n #[no_predicates]\n pub fn hash<let N: u32>(input: [Field; N], message_size: u32) -> Field {\n Poseidon2::hash_internal(input, message_size)\n }\n\n pub(crate) fn new(iv: Field) -> Poseidon2 {\n let mut result =\n Poseidon2 { cache: [0; 3], state: [0; 4], cache_size: 0, squeeze_mode: false };\n result.state[RATE] = iv;\n result\n }\n\n fn perform_duplex(&mut self) {\n // add the cache into sponge state\n self.state[0] += self.cache[0];\n self.state[1] += self.cache[1];\n self.state[2] += self.cache[2];\n self.state = crate::poseidon2_permutation(self.state
|
|
4133
|
+
"path": "/home/aztec-dev/nargo/github.com/noir-lang/poseidon/v0.3.0/src/poseidon2.nr",
|
|
4134
|
+
"source": "use std::default::Default;\nuse std::hash::Hasher;\n\nglobal RATE: u32 = 3;\n\npub struct Poseidon2 {\n cache: [Field; 3],\n state: [Field; 4],\n cache_size: u32,\n squeeze_mode: bool, // 0 => absorb, 1 => squeeze\n}\n\nimpl Poseidon2 {\n #[no_predicates]\n pub fn hash<let N: u32>(input: [Field; N], message_size: u32) -> Field {\n Poseidon2::hash_internal(input, message_size)\n }\n\n pub(crate) fn new(iv: Field) -> Poseidon2 {\n let mut result =\n Poseidon2 { cache: [0; 3], state: [0; 4], cache_size: 0, squeeze_mode: false };\n result.state[RATE] = iv;\n result\n }\n\n fn perform_duplex(&mut self) {\n // add the cache into sponge state\n self.state[0] += self.cache[0];\n self.state[1] += self.cache[1];\n self.state[2] += self.cache[2];\n self.state = crate::poseidon2_permutation(self.state);\n }\n\n fn absorb(&mut self, input: Field) {\n assert(!self.squeeze_mode);\n if self.cache_size == RATE {\n // If we're absorbing, and the cache is full, apply the sponge permutation to compress the cache\n self.perform_duplex();\n self.cache[0] = input;\n self.cache_size = 1;\n } else {\n // If we're absorbing, and the cache is not full, add the input into the cache\n self.cache[self.cache_size] = input;\n self.cache_size += 1;\n }\n }\n\n fn squeeze(&mut self) -> Field {\n assert(!self.squeeze_mode);\n // If we're in absorb mode, apply sponge permutation to compress the cache.\n self.perform_duplex();\n self.squeeze_mode = true;\n\n // Pop one item off the top of the permutation and return it.\n self.state[0]\n }\n\n fn hash_internal<let N: u32>(input: [Field; N], in_len: u32) -> Field {\n let two_pow_64 = 18446744073709551616;\n let iv: Field = (in_len as Field) * two_pow_64;\n let mut state = [0; 4];\n state[RATE] = iv;\n\n if std::runtime::is_unconstrained() {\n for i in 0..(in_len / RATE) {\n state[0] += input[i * RATE];\n state[1] += input[i * RATE + 1];\n state[2] += input[i * RATE + 2];\n state = crate::poseidon2_permutation(state);\n }\n\n // handle remaining elements after last full RATE-sized chunk\n let num_extra_fields = in_len % RATE;\n if num_extra_fields != 0 {\n let remainder_start = in_len - num_extra_fields;\n state[0] += input[remainder_start];\n if num_extra_fields > 1 {\n state[1] += input[remainder_start + 1];\n }\n }\n } else {\n let mut states: [[Field; 4]; N / RATE + 1] = [[0; 4]; N / RATE + 1];\n states[0] = state;\n\n // process all full RATE-sized chunks, storing state after each permutation\n for chunk_idx in 0..(N / RATE) {\n for i in 0..RATE {\n state[i] += input[chunk_idx * RATE + i];\n }\n state = crate::poseidon2_permutation(state);\n states[chunk_idx + 1] = state;\n }\n\n // get state at the last full block before in_len\n let first_partially_filled_chunk = in_len / RATE;\n state = states[first_partially_filled_chunk];\n\n // handle remaining elements after last full RATE-sized chunk\n let remainder_start = (in_len / RATE) * RATE;\n for j in 0..RATE {\n let idx = remainder_start + j;\n if idx < in_len {\n state[j] += input[idx];\n }\n }\n }\n\n // always run final permutation unless we just completed a full chunk\n // still need to permute once if in_len is 0\n if (in_len == 0) | (in_len % RATE != 0) {\n state = crate::poseidon2_permutation(state);\n };\n\n state[0]\n }\n}\n\npub struct Poseidon2Hasher {\n _state: [Field],\n}\n\nimpl Hasher for Poseidon2Hasher {\n fn finish(self) -> Field {\n let iv: Field = (self._state.len() as Field) * 18446744073709551616; // iv = (self._state.len() << 64)\n let mut sponge = Poseidon2::new(iv);\n for i in 0..self._state.len() {\n sponge.absorb(self._state[i]);\n }\n sponge.squeeze()\n }\n\n fn write(&mut self, input: Field) {\n self._state = self._state.push_back(input);\n }\n}\n\nimpl Default for Poseidon2Hasher {\n fn default() -> Self {\n Poseidon2Hasher { _state: @[] }\n }\n}\n"
|
|
4071
4135
|
},
|
|
4072
4136
|
"242": {
|
|
4073
4137
|
"function_locations": [
|
|
@@ -4149,473 +4213,315 @@
|
|
|
4149
4213
|
"function_locations": [
|
|
4150
4214
|
{
|
|
4151
4215
|
"name": "<impl Serialize for bool>::serialize",
|
|
4152
|
-
"start":
|
|
4216
|
+
"start": 693
|
|
4153
4217
|
},
|
|
4154
4218
|
{
|
|
4155
4219
|
"name": "<impl Serialize for bool>::stream_serialize",
|
|
4156
|
-
"start":
|
|
4220
|
+
"start": 914
|
|
4157
4221
|
},
|
|
4158
4222
|
{
|
|
4159
4223
|
"name": "<impl Deserialize for bool>::deserialize",
|
|
4160
|
-
"start":
|
|
4224
|
+
"start": 1082
|
|
4161
4225
|
},
|
|
4162
4226
|
{
|
|
4163
4227
|
"name": "<impl Deserialize for bool>::stream_deserialize",
|
|
4164
|
-
"start":
|
|
4165
|
-
},
|
|
4166
|
-
{
|
|
4167
|
-
"name": "<impl Serialize for u1>::serialize",
|
|
4168
|
-
"start": 1505
|
|
4169
|
-
},
|
|
4170
|
-
{
|
|
4171
|
-
"name": "<impl Serialize for u1>::stream_serialize",
|
|
4172
|
-
"start": 1726
|
|
4173
|
-
},
|
|
4174
|
-
{
|
|
4175
|
-
"name": "<impl Deserialize for u1>::deserialize",
|
|
4176
|
-
"start": 1890
|
|
4177
|
-
},
|
|
4178
|
-
{
|
|
4179
|
-
"name": "<impl Deserialize for u1>::stream_deserialize",
|
|
4180
|
-
"start": 2136
|
|
4228
|
+
"start": 1328
|
|
4181
4229
|
},
|
|
4182
4230
|
{
|
|
4183
4231
|
"name": "<impl Serialize for u8>::serialize",
|
|
4184
|
-
"start":
|
|
4232
|
+
"start": 1470
|
|
4185
4233
|
},
|
|
4186
4234
|
{
|
|
4187
4235
|
"name": "<impl Serialize for u8>::stream_serialize",
|
|
4188
|
-
"start":
|
|
4236
|
+
"start": 1691
|
|
4189
4237
|
},
|
|
4190
4238
|
{
|
|
4191
4239
|
"name": "<impl Deserialize for u8>::deserialize",
|
|
4192
|
-
"start":
|
|
4240
|
+
"start": 1855
|
|
4193
4241
|
},
|
|
4194
4242
|
{
|
|
4195
4243
|
"name": "<impl Deserialize for u8>::stream_deserialize",
|
|
4196
|
-
"start":
|
|
4244
|
+
"start": 2101
|
|
4197
4245
|
},
|
|
4198
4246
|
{
|
|
4199
4247
|
"name": "<impl Serialize for u16>::serialize",
|
|
4200
|
-
"start":
|
|
4248
|
+
"start": 2246
|
|
4201
4249
|
},
|
|
4202
4250
|
{
|
|
4203
4251
|
"name": "<impl Serialize for u16>::stream_serialize",
|
|
4204
|
-
"start":
|
|
4252
|
+
"start": 2467
|
|
4205
4253
|
},
|
|
4206
4254
|
{
|
|
4207
4255
|
"name": "<impl Deserialize for u16>::deserialize",
|
|
4208
|
-
"start":
|
|
4256
|
+
"start": 2633
|
|
4209
4257
|
},
|
|
4210
4258
|
{
|
|
4211
4259
|
"name": "<impl Deserialize for u16>::stream_deserialize",
|
|
4212
|
-
"start":
|
|
4260
|
+
"start": 2879
|
|
4213
4261
|
},
|
|
4214
4262
|
{
|
|
4215
4263
|
"name": "<impl Serialize for u32>::serialize",
|
|
4216
|
-
"start":
|
|
4264
|
+
"start": 3025
|
|
4217
4265
|
},
|
|
4218
4266
|
{
|
|
4219
4267
|
"name": "<impl Serialize for u32>::stream_serialize",
|
|
4220
|
-
"start":
|
|
4268
|
+
"start": 3246
|
|
4221
4269
|
},
|
|
4222
4270
|
{
|
|
4223
4271
|
"name": "<impl Deserialize for u32>::deserialize",
|
|
4224
|
-
"start":
|
|
4272
|
+
"start": 3412
|
|
4225
4273
|
},
|
|
4226
4274
|
{
|
|
4227
4275
|
"name": "<impl Deserialize for u32>::stream_deserialize",
|
|
4228
|
-
"start":
|
|
4276
|
+
"start": 3658
|
|
4229
4277
|
},
|
|
4230
4278
|
{
|
|
4231
4279
|
"name": "<impl Serialize for u64>::serialize",
|
|
4232
|
-
"start":
|
|
4280
|
+
"start": 3804
|
|
4233
4281
|
},
|
|
4234
4282
|
{
|
|
4235
4283
|
"name": "<impl Serialize for u64>::stream_serialize",
|
|
4236
|
-
"start":
|
|
4284
|
+
"start": 4025
|
|
4237
4285
|
},
|
|
4238
4286
|
{
|
|
4239
4287
|
"name": "<impl Deserialize for u64>::deserialize",
|
|
4240
|
-
"start":
|
|
4288
|
+
"start": 4191
|
|
4241
4289
|
},
|
|
4242
4290
|
{
|
|
4243
4291
|
"name": "<impl Deserialize for u64>::stream_deserialize",
|
|
4244
|
-
"start":
|
|
4292
|
+
"start": 4437
|
|
4245
4293
|
},
|
|
4246
4294
|
{
|
|
4247
4295
|
"name": "<impl Serialize for u128>::serialize",
|
|
4248
|
-
"start":
|
|
4296
|
+
"start": 4585
|
|
4249
4297
|
},
|
|
4250
4298
|
{
|
|
4251
4299
|
"name": "<impl Serialize for u128>::stream_serialize",
|
|
4252
|
-
"start":
|
|
4300
|
+
"start": 4806
|
|
4253
4301
|
},
|
|
4254
4302
|
{
|
|
4255
4303
|
"name": "<impl Deserialize for u128>::deserialize",
|
|
4256
|
-
"start":
|
|
4304
|
+
"start": 4974
|
|
4257
4305
|
},
|
|
4258
4306
|
{
|
|
4259
4307
|
"name": "<impl Deserialize for u128>::stream_deserialize",
|
|
4260
|
-
"start":
|
|
4308
|
+
"start": 5220
|
|
4261
4309
|
},
|
|
4262
4310
|
{
|
|
4263
4311
|
"name": "<impl Serialize for Field>::serialize",
|
|
4264
|
-
"start":
|
|
4312
|
+
"start": 5371
|
|
4265
4313
|
},
|
|
4266
4314
|
{
|
|
4267
4315
|
"name": "<impl Serialize for Field>::stream_serialize",
|
|
4268
|
-
"start":
|
|
4316
|
+
"start": 5592
|
|
4269
4317
|
},
|
|
4270
4318
|
{
|
|
4271
4319
|
"name": "<impl Deserialize for Field>::deserialize",
|
|
4272
|
-
"start":
|
|
4320
|
+
"start": 5753
|
|
4273
4321
|
},
|
|
4274
4322
|
{
|
|
4275
4323
|
"name": "<impl Deserialize for Field>::stream_deserialize",
|
|
4276
|
-
"start":
|
|
4324
|
+
"start": 5999
|
|
4277
4325
|
},
|
|
4278
4326
|
{
|
|
4279
4327
|
"name": "<impl Serialize for i8>::serialize",
|
|
4280
|
-
"start":
|
|
4328
|
+
"start": 6136
|
|
4281
4329
|
},
|
|
4282
4330
|
{
|
|
4283
4331
|
"name": "<impl Serialize for i8>::stream_serialize",
|
|
4284
|
-
"start":
|
|
4332
|
+
"start": 6357
|
|
4285
4333
|
},
|
|
4286
4334
|
{
|
|
4287
4335
|
"name": "<impl Deserialize for i8>::deserialize",
|
|
4288
|
-
"start":
|
|
4336
|
+
"start": 6527
|
|
4289
4337
|
},
|
|
4290
4338
|
{
|
|
4291
4339
|
"name": "<impl Deserialize for i8>::stream_deserialize",
|
|
4292
|
-
"start":
|
|
4340
|
+
"start": 6773
|
|
4293
4341
|
},
|
|
4294
4342
|
{
|
|
4295
4343
|
"name": "<impl Serialize for i16>::serialize",
|
|
4296
|
-
"start":
|
|
4344
|
+
"start": 6924
|
|
4297
4345
|
},
|
|
4298
4346
|
{
|
|
4299
4347
|
"name": "<impl Serialize for i16>::stream_serialize",
|
|
4300
|
-
"start":
|
|
4348
|
+
"start": 7145
|
|
4301
4349
|
},
|
|
4302
4350
|
{
|
|
4303
4351
|
"name": "<impl Deserialize for i16>::deserialize",
|
|
4304
|
-
"start":
|
|
4352
|
+
"start": 7318
|
|
4305
4353
|
},
|
|
4306
4354
|
{
|
|
4307
4355
|
"name": "<impl Deserialize for i16>::stream_deserialize",
|
|
4308
|
-
"start":
|
|
4356
|
+
"start": 7564
|
|
4309
4357
|
},
|
|
4310
4358
|
{
|
|
4311
4359
|
"name": "<impl Serialize for i32>::serialize",
|
|
4312
|
-
"start":
|
|
4360
|
+
"start": 7717
|
|
4313
4361
|
},
|
|
4314
4362
|
{
|
|
4315
4363
|
"name": "<impl Serialize for i32>::stream_serialize",
|
|
4316
|
-
"start":
|
|
4364
|
+
"start": 7938
|
|
4317
4365
|
},
|
|
4318
4366
|
{
|
|
4319
4367
|
"name": "<impl Deserialize for i32>::deserialize",
|
|
4320
|
-
"start":
|
|
4368
|
+
"start": 8111
|
|
4321
4369
|
},
|
|
4322
4370
|
{
|
|
4323
4371
|
"name": "<impl Deserialize for i32>::stream_deserialize",
|
|
4324
|
-
"start":
|
|
4372
|
+
"start": 8357
|
|
4325
4373
|
},
|
|
4326
4374
|
{
|
|
4327
4375
|
"name": "<impl Serialize for i64>::serialize",
|
|
4328
|
-
"start":
|
|
4376
|
+
"start": 8510
|
|
4329
4377
|
},
|
|
4330
4378
|
{
|
|
4331
4379
|
"name": "<impl Serialize for i64>::stream_serialize",
|
|
4332
|
-
"start":
|
|
4380
|
+
"start": 8731
|
|
4333
4381
|
},
|
|
4334
4382
|
{
|
|
4335
4383
|
"name": "<impl Deserialize for i64>::deserialize",
|
|
4336
|
-
"start":
|
|
4384
|
+
"start": 8904
|
|
4337
4385
|
},
|
|
4338
4386
|
{
|
|
4339
4387
|
"name": "<impl Deserialize for i64>::stream_deserialize",
|
|
4340
|
-
"start":
|
|
4388
|
+
"start": 9150
|
|
4341
4389
|
},
|
|
4342
4390
|
{
|
|
4343
4391
|
"name": "<impl Serialize for [T; M]>::serialize",
|
|
4344
|
-
"start":
|
|
4392
|
+
"start": 9350
|
|
4345
4393
|
},
|
|
4346
4394
|
{
|
|
4347
4395
|
"name": "<impl Serialize for [T; M]>::stream_serialize",
|
|
4348
|
-
"start":
|
|
4396
|
+
"start": 9571
|
|
4349
4397
|
},
|
|
4350
4398
|
{
|
|
4351
4399
|
"name": "<impl Deserialize for [T; M]>::deserialize",
|
|
4352
|
-
"start":
|
|
4400
|
+
"start": 9831
|
|
4353
4401
|
},
|
|
4354
4402
|
{
|
|
4355
4403
|
"name": "<impl Deserialize for [T; M]>::stream_deserialize",
|
|
4356
|
-
"start":
|
|
4404
|
+
"start": 10077
|
|
4357
4405
|
},
|
|
4358
4406
|
{
|
|
4359
4407
|
"name": "<impl Serialize for Option<T>>::serialize",
|
|
4360
|
-
"start":
|
|
4408
|
+
"start": 10389
|
|
4361
4409
|
},
|
|
4362
4410
|
{
|
|
4363
4411
|
"name": "<impl Serialize for Option<T>>::stream_serialize",
|
|
4364
|
-
"start":
|
|
4412
|
+
"start": 10610
|
|
4365
4413
|
},
|
|
4366
4414
|
{
|
|
4367
4415
|
"name": "<impl Deserialize for Option<T>>::deserialize",
|
|
4368
|
-
"start":
|
|
4416
|
+
"start": 10997
|
|
4369
4417
|
},
|
|
4370
4418
|
{
|
|
4371
4419
|
"name": "<impl Deserialize for Option<T>>::stream_deserialize",
|
|
4372
|
-
"start":
|
|
4420
|
+
"start": 11243
|
|
4373
4421
|
},
|
|
4374
4422
|
{
|
|
4375
4423
|
"name": "<impl Serialize for EmbeddedCurveScalar>::serialize",
|
|
4376
|
-
"start":
|
|
4424
|
+
"start": 11621
|
|
4377
4425
|
},
|
|
4378
4426
|
{
|
|
4379
4427
|
"name": "<impl Serialize for EmbeddedCurveScalar>::stream_serialize",
|
|
4380
|
-
"start":
|
|
4428
|
+
"start": 11744
|
|
4381
4429
|
},
|
|
4382
4430
|
{
|
|
4383
4431
|
"name": "<impl Deserialize for EmbeddedCurveScalar>::deserialize",
|
|
4384
|
-
"start":
|
|
4432
|
+
"start": 11944
|
|
4385
4433
|
},
|
|
4386
4434
|
{
|
|
4387
4435
|
"name": "<impl Deserialize for EmbeddedCurveScalar>::stream_deserialize",
|
|
4388
|
-
"start":
|
|
4436
|
+
"start": 12090
|
|
4389
4437
|
},
|
|
4390
4438
|
{
|
|
4391
4439
|
"name": "<impl Serialize for EmbeddedCurvePoint>::serialize",
|
|
4392
|
-
"start":
|
|
4440
|
+
"start": 12297
|
|
4393
4441
|
},
|
|
4394
4442
|
{
|
|
4395
4443
|
"name": "<impl Serialize for EmbeddedCurvePoint>::stream_serialize",
|
|
4396
|
-
"start":
|
|
4444
|
+
"start": 12397
|
|
4397
4445
|
},
|
|
4398
4446
|
{
|
|
4399
4447
|
"name": "<impl Deserialize for EmbeddedCurvePoint>::deserialize",
|
|
4400
|
-
"start":
|
|
4448
|
+
"start": 12593
|
|
4401
4449
|
},
|
|
4402
4450
|
{
|
|
4403
4451
|
"name": "<impl Deserialize for EmbeddedCurvePoint>::stream_deserialize",
|
|
4404
|
-
"start":
|
|
4452
|
+
"start": 12737
|
|
4405
4453
|
},
|
|
4406
4454
|
{
|
|
4407
4455
|
"name": "<impl Deserialize for str<M>>::deserialize",
|
|
4408
|
-
"start":
|
|
4456
|
+
"start": 12916
|
|
4409
4457
|
},
|
|
4410
4458
|
{
|
|
4411
4459
|
"name": "<impl Deserialize for str<M>>::stream_deserialize",
|
|
4412
|
-
"start":
|
|
4460
|
+
"start": 13162
|
|
4413
4461
|
},
|
|
4414
4462
|
{
|
|
4415
4463
|
"name": "<impl Serialize for str<M>>::serialize",
|
|
4416
|
-
"start":
|
|
4464
|
+
"start": 13395
|
|
4417
4465
|
},
|
|
4418
4466
|
{
|
|
4419
4467
|
"name": "<impl Serialize for str<M>>::stream_serialize",
|
|
4420
|
-
"start":
|
|
4468
|
+
"start": 13616
|
|
4421
4469
|
},
|
|
4422
4470
|
{
|
|
4423
4471
|
"name": "<impl Deserialize for BoundedVec<T, M>>::deserialize",
|
|
4424
|
-
"start":
|
|
4472
|
+
"start": 13997
|
|
4425
4473
|
},
|
|
4426
4474
|
{
|
|
4427
4475
|
"name": "<impl Deserialize for BoundedVec<T, M>>::stream_deserialize",
|
|
4428
|
-
"start":
|
|
4476
|
+
"start": 14243
|
|
4429
4477
|
},
|
|
4430
4478
|
{
|
|
4431
4479
|
"name": "<impl Deserialize for ()>::deserialize",
|
|
4432
|
-
"start":
|
|
4480
|
+
"start": 15299
|
|
4433
4481
|
},
|
|
4434
4482
|
{
|
|
4435
4483
|
"name": "<impl Deserialize for ()>::stream_deserialize",
|
|
4436
|
-
"start":
|
|
4484
|
+
"start": 15546
|
|
4437
4485
|
},
|
|
4438
4486
|
{
|
|
4439
4487
|
"name": "<impl Serialize for BoundedVec<T, M>>::serialize",
|
|
4440
|
-
"start":
|
|
4488
|
+
"start": 15911
|
|
4441
4489
|
},
|
|
4442
4490
|
{
|
|
4443
4491
|
"name": "<impl Serialize for BoundedVec<T, M>>::stream_serialize",
|
|
4444
|
-
"start":
|
|
4492
|
+
"start": 16132
|
|
4445
4493
|
},
|
|
4446
4494
|
{
|
|
4447
4495
|
"name": "make_slice",
|
|
4448
|
-
"start":
|
|
4496
|
+
"start": 16617
|
|
4449
4497
|
},
|
|
4450
4498
|
{
|
|
4451
4499
|
"name": "impl_serialize_for_tuple",
|
|
4452
|
-
"start":
|
|
4500
|
+
"start": 16867
|
|
4453
4501
|
},
|
|
4454
4502
|
{
|
|
4455
4503
|
"name": "<impl Serialize for (T1,)>::serialize",
|
|
4456
|
-
"start":
|
|
4504
|
+
"start": 20158
|
|
4457
4505
|
},
|
|
4458
4506
|
{
|
|
4459
4507
|
"name": "<impl Serialize for (T1,)>::stream_serialize",
|
|
4460
|
-
"start":
|
|
4508
|
+
"start": 20409
|
|
4461
4509
|
},
|
|
4462
4510
|
{
|
|
4463
4511
|
"name": "<impl Deserialize for (T1,)>::deserialize",
|
|
4464
|
-
"start":
|
|
4512
|
+
"start": 20616
|
|
4465
4513
|
},
|
|
4466
4514
|
{
|
|
4467
4515
|
"name": "<impl Deserialize for (T1,)>::stream_deserialize",
|
|
4468
|
-
"start":
|
|
4516
|
+
"start": 20877
|
|
4469
4517
|
},
|
|
4470
4518
|
{
|
|
4471
4519
|
"name": "bounded_vec_serialization",
|
|
4472
|
-
"start":
|
|
4520
|
+
"start": 21226
|
|
4473
4521
|
}
|
|
4474
4522
|
],
|
|
4475
4523
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/serde/src/type_impls.nr",
|
|
4476
|
-
"source": "use crate::{reader::Reader, serialization::{Deserialize, Serialize}, writer::Writer};\nuse std::embedded_curve_ops::EmbeddedCurvePoint;\nuse std::embedded_curve_ops::EmbeddedCurveScalar;\n\nglobal U1_SERIALIZED_LEN: u32 = 1;\nglobal BOOL_SERIALIZED_LEN: u32 = 1;\nglobal U8_SERIALIZED_LEN: u32 = 1;\nglobal U16_SERIALIZED_LEN: u32 = 1;\nglobal U32_SERIALIZED_LEN: u32 = 1;\nglobal U64_SERIALIZED_LEN: u32 = 1;\nglobal U128_SERIALIZED_LEN: u32 = 1;\nglobal FIELD_SERIALIZED_LEN: u32 = 1;\nglobal I8_SERIALIZED_LEN: u32 = 1;\nglobal I16_SERIALIZED_LEN: u32 = 1;\nglobal I32_SERIALIZED_LEN: u32 = 1;\nglobal I64_SERIALIZED_LEN: u32 = 1;\n\nimpl Serialize for bool {\n let N: u32 = BOOL_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for bool {\n let N: u32 = BOOL_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> bool {\n reader.read() != 0\n }\n}\n\nimpl Serialize for u1 {\n let N: u32 = U1_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u1 {\n let N: u32 = U1_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u1\n }\n}\n\nimpl Serialize for u8 {\n let N: u32 = U8_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u8 {\n let N: u32 = U8_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u8\n }\n}\n\nimpl Serialize for u16 {\n let N: u32 = U16_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u16 {\n let N: u32 = U16_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u16\n }\n}\n\nimpl Serialize for u32 {\n let N: u32 = U32_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u32 {\n let N: u32 = U32_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u32\n }\n}\n\nimpl Serialize for u64 {\n let N: u32 = U64_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u64 {\n let N: u32 = U64_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u64\n }\n}\n\nimpl Serialize for u128 {\n let N: u32 = U128_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u128 {\n let N: u32 = U128_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u128\n }\n}\n\nimpl Serialize for Field {\n let N: u32 = FIELD_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self);\n }\n}\n\nimpl Deserialize for Field {\n let N: u32 = FIELD_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read()\n }\n}\n\nimpl Serialize for i8 {\n let N: u32 = I8_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u8 as Field);\n }\n}\n\nimpl Deserialize for i8 {\n let N: u32 = I8_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u8 as i8\n }\n}\n\nimpl Serialize for i16 {\n let N: u32 = I16_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u16 as Field);\n }\n}\n\nimpl Deserialize for i16 {\n let N: u32 = I16_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u16 as i16\n }\n}\n\nimpl Serialize for i32 {\n let N: u32 = I32_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u32 as Field);\n }\n}\n\nimpl Deserialize for i32 {\n let N: u32 = I32_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u32 as i32\n }\n}\n\nimpl Serialize for i64 {\n let N: u32 = I64_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u64 as Field);\n }\n}\n\nimpl Deserialize for i64 {\n let N: u32 = I64_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u64 as i64\n }\n}\n\nimpl<T, let M: u32> Serialize for [T; M]\nwhere\n T: Serialize,\n{\n let N: u32 = <T as Serialize>::N * M;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n for i in 0..M {\n self[i].stream_serialize(writer);\n }\n }\n}\n\nimpl<T, let M: u32> Deserialize for [T; M]\nwhere\n T: Deserialize,\n{\n let N: u32 = <T as Deserialize>::N * M;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n let mut result: [T; M] = std::mem::zeroed();\n for i in 0..M {\n result[i] = T::stream_deserialize(reader);\n }\n result\n }\n}\n\nimpl<T> Serialize for Option<T>\nwhere\n T: Serialize,\n{\n let N: u32 = <T as Serialize>::N + 1;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write_bool(self.is_some());\n if self.is_some() {\n self.unwrap_unchecked().stream_serialize(writer);\n } else {\n writer.advance_offset(<T as Serialize>::N);\n }\n }\n}\n\nimpl<T> Deserialize for Option<T>\nwhere\n T: Deserialize,\n{\n let N: u32 = <T as Deserialize>::N + 1;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n if reader.read_bool() {\n Option::some(<T as Deserialize>::stream_deserialize(reader))\n } else {\n reader.advance_offset(<T as Deserialize>::N);\n Option::none()\n }\n }\n}\n\nglobal SCALAR_SIZE: u32 = 2;\n\nimpl Serialize for EmbeddedCurveScalar {\n\n let N: u32 = SCALAR_SIZE;\n\n fn serialize(self) -> [Field; SCALAR_SIZE] {\n [self.lo, self.hi]\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self.lo);\n writer.write(self.hi);\n }\n}\n\nimpl Deserialize for EmbeddedCurveScalar {\n let N: u32 = SCALAR_SIZE;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n Self { lo: fields[0], hi: fields[1] }\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n Self { lo: reader.read(), hi: reader.read() }\n }\n}\n\nglobal POINT_SIZE: u32 = 3;\n\nimpl Serialize for EmbeddedCurvePoint {\n let N: u32 = POINT_SIZE;\n\n fn serialize(self) -> [Field; Self::N] {\n [self.x, self.y, self.is_infinite as Field]\n }\n\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self.x);\n writer.write(self.y);\n writer.write(self.is_infinite as Field);\n }\n}\n\nimpl Deserialize for EmbeddedCurvePoint {\n let N: u32 = POINT_SIZE;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n Self { x: fields[0], y: fields[1], is_infinite: fields[2] != 0 }\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n Self { x: reader.read(), y: reader.read(), is_infinite: reader.read_bool() }\n }\n}\n\nimpl<let M: u32> Deserialize for str<M> {\n let N: u32 = M;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n let u8_arr = <[u8; Self::N] as Deserialize>::stream_deserialize(reader);\n str::<Self::N>::from(u8_arr)\n }\n}\n\nimpl<let M: u32> Serialize for str<M> {\n let N: u32 = M;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n self.as_bytes().stream_serialize(writer);\n }\n}\n\n// Note: Not deriving this because it's not supported to call derive_serialize on a \"remote\" struct (and it will never\n// be supported).\nimpl<T, let M: u32> Deserialize for BoundedVec<T, M>\nwhere\n T: Deserialize,\n{\n let N: u32 = <T as Deserialize>::N * M + 1;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n let mut new_bounded_vec: BoundedVec<T, M> = BoundedVec::new();\n let payload_len = Self::N - 1;\n\n // Length is stored in the last field as we need to match intrinsic Noir serialization and the `len` struct\n // field is after `storage` struct field (see `bounded_vec.nr` in noir-stdlib)\n let len = reader.peek_offset(payload_len) as u32;\n\n for i in 0..M {\n if i < len {\n new_bounded_vec.push(<T as Deserialize>::stream_deserialize(reader));\n }\n }\n\n // +1 for the length of the BoundedVec\n reader.advance_offset((M - len) * <T as Deserialize>::N + 1);\n\n new_bounded_vec\n }\n}\n\n// This may cause issues if used as program input, because noir disallows empty arrays for program input.\n// I think this is okay because I don't foresee a unit type being used as input. But leaving this comment as a hint\n// if someone does run into this in the future.\nimpl Deserialize for () {\n let N: u32 = 0;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(_reader: &mut Reader<K>) -> Self {\n ()\n }\n}\n\n// Note: Not deriving this because it's not supported to call derive_serialize on a \"remote\" struct (and it will never\n// be supported).\nimpl<T, let M: u32> Serialize for BoundedVec<T, M>\nwhere\n T: Serialize,\n{\n let N: u32 = <T as Serialize>::N * M + 1; // +1 for the length of the BoundedVec\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n self.storage().stream_serialize(writer);\n // Length is stored in the last field as we need to match intrinsic Noir serialization and the `len` struct\n // field is after `storage` struct field (see `bounded_vec.nr` in noir-stdlib)\n writer.write_u32(self.len() as u32);\n }\n}\n\n// Create a slice of the given length with each element made from `f(i)` where `i` is the current index\ncomptime fn make_slice<Env, T>(length: u32, f: fn[Env](u32) -> T) -> [T] {\n let mut slice = @[];\n for i in 0..length {\n slice = slice.push_back(f(i));\n }\n slice\n}\n\n// Implements Serialize and Deserialize for an arbitrary tuple type\ncomptime fn impl_serialize_for_tuple(_m: Module, length: u32) -> Quoted {\n // `T0`, `T1`, `T2`\n let type_names = make_slice(length, |i| f\"T{i}\".quoted_contents());\n\n // `result0`, `result1`, `result2`\n let result_names = make_slice(length, |i| f\"result{i}\".quoted_contents());\n\n // `T0, T1, T2`\n let field_generics = type_names.join(quote [,]);\n\n // `<T0 as Serialize>::N + <T1 as Serialize>::N + <T2 as Serialize>::N`\n let full_size_serialize = type_names\n .map(|type_name| quote {\n <$type_name as Serialize>::N\n })\n .join(quote [+]);\n\n // `<T0 as Deserialize>::N + <T1 as Deserialize>::N + <T2 as Deserialize>::N`\n let full_size_deserialize = type_names\n .map(|type_name| quote {\n <$type_name as Deserialize>::N\n })\n .join(quote [+]);\n\n // `T0: Serialize, T1: Serialize, T2: Serialize,`\n let serialize_constraints = type_names\n .map(|field_name| quote {\n $field_name: Serialize,\n })\n .join(quote []);\n\n // `T0: Deserialize, T1: Deserialize, T2: Deserialize,`\n let deserialize_constraints = type_names\n .map(|field_name| quote {\n $field_name: Deserialize,\n })\n .join(quote []);\n\n // Statements to serialize each field\n let serialized_fields = type_names\n .mapi(|i, _type_name| quote {\n $crate::serialization::Serialize::stream_serialize(self.$i, writer);\n })\n .join(quote []);\n\n // Statements to deserialize each field\n let deserialized_fields = type_names\n .mapi(|i, type_name| {\n let result_name = result_names[i];\n quote {\n let $result_name = <$type_name as $crate::serialization::Deserialize>::stream_deserialize(reader);\n }\n })\n .join(quote []);\n let deserialize_results = result_names.join(quote [,]);\n\n quote {\n impl<$field_generics> Serialize for ($field_generics) where $serialize_constraints {\n let N: u32 = $full_size_serialize;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: $crate::writer::Writer<Self::N> = $crate::writer::Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut $crate::writer::Writer<K>) {\n\n $serialized_fields\n }\n }\n\n impl<$field_generics> Deserialize for ($field_generics) where $deserialize_constraints {\n let N: u32 = $full_size_deserialize;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = $crate::reader::Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n \n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut $crate::reader::Reader<K>) -> Self {\n $deserialized_fields\n ($deserialize_results)\n }\n }\n }\n}\n\n// Keeping these manual impls. They are more efficient since they do not\n// require copying sub-arrays from any serialized arrays.\nimpl<T1> Serialize for (T1,)\nwhere\n T1: Serialize,\n{\n let N: u32 = <T1 as Serialize>::N;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: crate::writer::Writer<Self::N> = crate::writer::Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n self.0.stream_serialize(writer);\n }\n}\n\nimpl<T1> Deserialize for (T1,)\nwhere\n T1: Deserialize,\n{\n let N: u32 = <T1 as Deserialize>::N;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = crate::reader::Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n (<T1 as Deserialize>::stream_deserialize(reader),)\n }\n}\n\n#[impl_serialize_for_tuple(2)]\n#[impl_serialize_for_tuple(3)]\n#[impl_serialize_for_tuple(4)]\n#[impl_serialize_for_tuple(5)]\n#[impl_serialize_for_tuple(6)]\nmod impls {\n use crate::serialization::{Deserialize, Serialize};\n}\n\n#[test]\nunconstrained fn bounded_vec_serialization() {\n // Test empty BoundedVec\n let empty_vec: BoundedVec<Field, 3> = BoundedVec::from_array([]);\n let serialized = empty_vec.serialize();\n let deserialized = BoundedVec::<Field, 3>::deserialize(serialized);\n assert_eq(empty_vec, deserialized);\n assert_eq(deserialized.len(), 0);\n\n // Test partially filled BoundedVec\n let partial_vec: BoundedVec<[u32; 2], 3> = BoundedVec::from_array([[1, 2]]);\n let serialized = partial_vec.serialize();\n let deserialized = BoundedVec::<[u32; 2], 3>::deserialize(serialized);\n assert_eq(partial_vec, deserialized);\n assert_eq(deserialized.len(), 1);\n assert_eq(deserialized.get(0), [1, 2]);\n\n // Test full BoundedVec\n let full_vec: BoundedVec<[u32; 2], 3> = BoundedVec::from_array([[1, 2], [3, 4], [5, 6]]);\n let serialized = full_vec.serialize();\n let deserialized = BoundedVec::<[u32; 2], 3>::deserialize(serialized);\n assert_eq(full_vec, deserialized);\n assert_eq(deserialized.len(), 3);\n assert_eq(deserialized.get(0), [1, 2]);\n assert_eq(deserialized.get(1), [3, 4]);\n assert_eq(deserialized.get(2), [5, 6]);\n}\n"
|
|
4477
|
-
},
|
|
4478
|
-
"3": {
|
|
4479
|
-
"function_locations": [
|
|
4480
|
-
{
|
|
4481
|
-
"name": "[T; N]::len",
|
|
4482
|
-
"start": 480
|
|
4483
|
-
},
|
|
4484
|
-
{
|
|
4485
|
-
"name": "[T; N]::as_vector",
|
|
4486
|
-
"start": 735
|
|
4487
|
-
},
|
|
4488
|
-
{
|
|
4489
|
-
"name": "[T; N]::as_slice",
|
|
4490
|
-
"start": 1112
|
|
4491
|
-
},
|
|
4492
|
-
{
|
|
4493
|
-
"name": "[T; N]::map",
|
|
4494
|
-
"start": 1442
|
|
4495
|
-
},
|
|
4496
|
-
{
|
|
4497
|
-
"name": "[T; N]::mapi",
|
|
4498
|
-
"start": 2002
|
|
4499
|
-
},
|
|
4500
|
-
{
|
|
4501
|
-
"name": "[T; N]::for_each",
|
|
4502
|
-
"start": 2549
|
|
4503
|
-
},
|
|
4504
|
-
{
|
|
4505
|
-
"name": "[T; N]::for_eachi",
|
|
4506
|
-
"start": 2966
|
|
4507
|
-
},
|
|
4508
|
-
{
|
|
4509
|
-
"name": "[T; N]::fold",
|
|
4510
|
-
"start": 3832
|
|
4511
|
-
},
|
|
4512
|
-
{
|
|
4513
|
-
"name": "[T; N]::reduce",
|
|
4514
|
-
"start": 4349
|
|
4515
|
-
},
|
|
4516
|
-
{
|
|
4517
|
-
"name": "[T; N]::all",
|
|
4518
|
-
"start": 4858
|
|
4519
|
-
},
|
|
4520
|
-
{
|
|
4521
|
-
"name": "[T; N]::any",
|
|
4522
|
-
"start": 5330
|
|
4523
|
-
},
|
|
4524
|
-
{
|
|
4525
|
-
"name": "[T; N]::concat",
|
|
4526
|
-
"start": 5872
|
|
4527
|
-
},
|
|
4528
|
-
{
|
|
4529
|
-
"name": "[T; N]::sort",
|
|
4530
|
-
"start": 6768
|
|
4531
|
-
},
|
|
4532
|
-
{
|
|
4533
|
-
"name": "[T; N]::sort_via",
|
|
4534
|
-
"start": 7783
|
|
4535
|
-
},
|
|
4536
|
-
{
|
|
4537
|
-
"name": "[u8; N]::as_str_unchecked",
|
|
4538
|
-
"start": 8811
|
|
4539
|
-
},
|
|
4540
|
-
{
|
|
4541
|
-
"name": "<impl From<str<N>> for [u8; N]>::from",
|
|
4542
|
-
"start": 8938
|
|
4543
|
-
},
|
|
4544
|
-
{
|
|
4545
|
-
"name": "test::map_empty",
|
|
4546
|
-
"start": 9012
|
|
4547
|
-
},
|
|
4548
|
-
{
|
|
4549
|
-
"name": "test::sort_u32",
|
|
4550
|
-
"start": 10122
|
|
4551
|
-
},
|
|
4552
|
-
{
|
|
4553
|
-
"name": "test::test_sort",
|
|
4554
|
-
"start": 10177
|
|
4555
|
-
},
|
|
4556
|
-
{
|
|
4557
|
-
"name": "test::test_sort_100_values",
|
|
4558
|
-
"start": 10408
|
|
4559
|
-
},
|
|
4560
|
-
{
|
|
4561
|
-
"name": "test::test_sort_100_values_comptime",
|
|
4562
|
-
"start": 11576
|
|
4563
|
-
},
|
|
4564
|
-
{
|
|
4565
|
-
"name": "test::test_sort_via",
|
|
4566
|
-
"start": 11721
|
|
4567
|
-
},
|
|
4568
|
-
{
|
|
4569
|
-
"name": "test::test_sort_via_100_values",
|
|
4570
|
-
"start": 11968
|
|
4571
|
-
},
|
|
4572
|
-
{
|
|
4573
|
-
"name": "test::mapi_empty",
|
|
4574
|
-
"start": 13129
|
|
4575
|
-
},
|
|
4576
|
-
{
|
|
4577
|
-
"name": "test::for_each_empty",
|
|
4578
|
-
"start": 13224
|
|
4579
|
-
},
|
|
4580
|
-
{
|
|
4581
|
-
"name": "test::for_eachi_empty",
|
|
4582
|
-
"start": 13362
|
|
4583
|
-
},
|
|
4584
|
-
{
|
|
4585
|
-
"name": "test::map_example",
|
|
4586
|
-
"start": 13501
|
|
4587
|
-
},
|
|
4588
|
-
{
|
|
4589
|
-
"name": "test::mapi_example",
|
|
4590
|
-
"start": 13638
|
|
4591
|
-
},
|
|
4592
|
-
{
|
|
4593
|
-
"name": "test::for_each_example",
|
|
4594
|
-
"start": 13787
|
|
4595
|
-
},
|
|
4596
|
-
{
|
|
4597
|
-
"name": "test::for_eachi_example",
|
|
4598
|
-
"start": 14127
|
|
4599
|
-
},
|
|
4600
|
-
{
|
|
4601
|
-
"name": "test::concat",
|
|
4602
|
-
"start": 14338
|
|
4603
|
-
},
|
|
4604
|
-
{
|
|
4605
|
-
"name": "test::concat_zero_length_with_something",
|
|
4606
|
-
"start": 14597
|
|
4607
|
-
},
|
|
4608
|
-
{
|
|
4609
|
-
"name": "test::concat_something_with_zero_length",
|
|
4610
|
-
"start": 14800
|
|
4611
|
-
},
|
|
4612
|
-
{
|
|
4613
|
-
"name": "test::concat_zero_lengths",
|
|
4614
|
-
"start": 14989
|
|
4615
|
-
}
|
|
4616
|
-
],
|
|
4617
|
-
"path": "std/array/mod.nr",
|
|
4618
|
-
"source": "use crate::cmp::{Eq, Ord};\nuse crate::convert::From;\nuse crate::runtime::is_unconstrained;\n\nmod check_shuffle;\nmod quicksort;\n\nimpl<T, let N: u32> [T; N] {\n /// Returns the length of this array.\n ///\n /// ```noir\n /// fn len(self) -> Field\n /// ```\n ///\n /// example\n ///\n /// ```noir\n /// fn main() {\n /// let array = [42, 42];\n /// assert(array.len() == 2);\n /// }\n /// ```\n #[builtin(array_len)]\n pub fn len(self) -> u32 {}\n\n /// Returns this array as a vector.\n ///\n /// ```noir\n /// let array = [1, 2];\n /// let vector = array.as_vector();\n /// assert_eq(vector, [1, 2].as_vector());\n /// ```\n #[builtin(as_vector)]\n pub fn as_vector(self) -> [T] {}\n\n /// Returns this array as a vector.\n /// This method is deprecated in favor of `as_vector`.\n ///\n /// ```noir\n /// let array = [1, 2];\n /// let vector = array.as_slice();\n /// assert_eq(vector, [1, 2].as_vector());\n /// ```\n #[builtin(as_vector)]\n #[deprecated(\"This method has been renamed to `as_vector`\")]\n pub fn as_slice(self) -> [T] {}\n\n /// Applies a function to each element of this array, returning a new array containing the mapped elements.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let b = a.map(|a| a * 2);\n /// assert_eq(b, [2, 4, 6]);\n /// ```\n pub fn map<U, Env>(self, f: fn[Env](T) -> U) -> [U; N] {\n let uninitialized = crate::mem::zeroed();\n let mut ret = [uninitialized; N];\n\n for i in 0..self.len() {\n ret[i] = f(self[i]);\n }\n\n ret\n }\n\n /// Applies a function to each element of this array along with its index,\n /// returning a new array containing the mapped elements.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let b = a.mapi(|i, a| i + a * 2);\n /// assert_eq(b, [2, 5, 8]);\n /// ```\n pub fn mapi<U, Env>(self, f: fn[Env](u32, T) -> U) -> [U; N] {\n let uninitialized = crate::mem::zeroed();\n let mut ret = [uninitialized; N];\n\n for i in 0..self.len() {\n ret[i] = f(i, self[i]);\n }\n\n ret\n }\n\n /// Applies a function to each element of this array.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let mut b = [0; 3];\n /// let mut i = 0;\n /// a.for_each(|x| {\n /// b[i] = x;\n /// i += 1;\n /// });\n /// assert_eq(a, b);\n /// ```\n pub fn for_each<Env>(self, f: fn[Env](T) -> ()) {\n for i in 0..self.len() {\n f(self[i]);\n }\n }\n\n /// Applies a function to each element of this array along with its index.\n ///\n /// Example:\n ///\n /// ```rust\n /// let a = [1, 2, 3];\n /// let mut b = [0; 3];\n /// a.for_eachi(|i, x| {\n /// b[i] = x;\n /// });\n /// assert_eq(a, b);\n /// ```\n pub fn for_eachi<Env>(self, f: fn[Env](u32, T) -> ()) {\n for i in 0..self.len() {\n f(i, self[i]);\n }\n }\n\n /// Applies a function to each element of the array, returning the final accumulated value. The first\n /// parameter is the initial value.\n ///\n /// This is a left fold, so the given function will be applied to the accumulator and first element of\n /// the array, then the second, and so on. For a given call the expected result would be equivalent to:\n ///\n /// ```rust\n /// let a1 = [1];\n /// let a2 = [1, 2];\n /// let a3 = [1, 2, 3];\n ///\n /// let f = |a, b| a - b;\n /// a1.fold(10, f); //=> f(10, 1)\n /// a2.fold(10, f); //=> f(f(10, 1), 2)\n /// a3.fold(10, f); //=> f(f(f(10, 1), 2), 3)\n ///\n /// assert_eq(a3.fold(10, f), 10 - 1 - 2 - 3);\n /// ```\n pub fn fold<U, Env>(self, mut accumulator: U, f: fn[Env](U, T) -> U) -> U {\n for elem in self {\n accumulator = f(accumulator, elem);\n }\n accumulator\n }\n\n /// Same as fold, but uses the first element as the starting element.\n ///\n /// Requires the input array to be non-empty.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr = [1, 2, 3, 4];\n /// let reduced = arr.reduce(|a, b| a + b);\n /// assert(reduced == 10);\n /// }\n /// ```\n pub fn reduce<Env>(self, f: fn[Env](T, T) -> T) -> T {\n let mut accumulator = self[0];\n for i in 1..self.len() {\n accumulator = f(accumulator, self[i]);\n }\n accumulator\n }\n\n /// Returns true if all the elements in this array satisfy the given predicate.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr = [2, 2, 2, 2, 2];\n /// let all = arr.all(|a| a == 2);\n /// assert(all);\n /// }\n /// ```\n pub fn all<Env>(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = true;\n for elem in self {\n ret &= predicate(elem);\n }\n ret\n }\n\n /// Returns true if any of the elements in this array satisfy the given predicate.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr = [2, 2, 2, 2, 5];\n /// let any = arr.any(|a| a == 5);\n /// assert(any);\n /// }\n /// ```\n pub fn any<Env>(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n for elem in self {\n ret |= predicate(elem);\n }\n ret\n }\n\n /// Concatenates this array with another array.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn main() {\n /// let arr1 = [1, 2, 3, 4];\n /// let arr2 = [6, 7, 8, 9, 10, 11];\n /// let concatenated_arr = arr1.concat(arr2);\n /// assert(concatenated_arr == [1, 2, 3, 4, 6, 7, 8, 9, 10, 11]);\n /// }\n /// ```\n pub fn concat<let M: u32>(self, array2: [T; M]) -> [T; N + M] {\n let mut result = [crate::mem::zeroed(); N + M];\n for i in 0..N {\n result[i] = self[i];\n }\n for i in 0..M {\n result[i + N] = array2[i];\n }\n result\n }\n}\n\nimpl<T, let N: u32> [T; N]\nwhere\n T: Ord + Eq,\n{\n /// Returns a new sorted array. The original array remains untouched. Notice that this function will\n /// only work for arrays of fields or integers, not for any arbitrary type. This is because the sorting\n /// logic it uses internally is optimized specifically for these values. If you need a sort function to\n /// sort any type, you should use the [`Self::sort_via`] function.\n ///\n /// Example:\n ///\n /// ```rust\n /// fn main() {\n /// let arr = [42, 32];\n /// let sorted = arr.sort();\n /// assert(sorted == [32, 42]);\n /// }\n /// ```\n pub fn sort(self) -> Self {\n self.sort_via(|a, b| a <= b)\n }\n}\n\nimpl<T, let N: u32> [T; N]\nwhere\n T: Eq,\n{\n /// Returns a new sorted array by sorting it with a custom comparison function.\n /// The original array remains untouched.\n /// The ordering function must return true if the first argument should be sorted to be before the second argument or is equal to the second argument.\n ///\n /// Using this method with an operator like `<` that does not return `true` for equal values will result in an assertion failure for arrays with equal elements.\n ///\n /// Example:\n ///\n /// ```rust\n /// fn main() {\n /// let arr = [42, 32]\n /// let sorted_ascending = arr.sort_via(|a, b| a <= b);\n /// assert(sorted_ascending == [32, 42]); // verifies\n ///\n /// let sorted_descending = arr.sort_via(|a, b| a >= b);\n /// assert(sorted_descending == [32, 42]); // does not verify\n /// }\n /// ```\n pub fn sort_via<Env>(self, ordering: fn[Env](T, T) -> bool) -> Self {\n // Safety: `sorted` array is checked to be:\n // a. a permutation of `input`'s elements\n // b. satisfying the predicate `ordering`\n let sorted = unsafe { quicksort::quicksort(self, ordering) };\n\n if !is_unconstrained() {\n for i in 0..N - 1 {\n assert(\n ordering(sorted[i], sorted[i + 1]),\n \"Array has not been sorted correctly according to `ordering`.\",\n );\n }\n check_shuffle::check_shuffle(self, sorted);\n }\n sorted\n }\n}\n\nimpl<let N: u32> [u8; N] {\n /// Converts a byte array of type `[u8; N]` to a string. Note that this performs no UTF-8 validation -\n /// the given array is interpreted as-is as a string.\n ///\n /// Example:\n ///\n /// ```rust\n /// fn main() {\n /// let hi = [104, 105].as_str_unchecked();\n /// assert_eq(hi, \"hi\");\n /// }\n /// ```\n #[builtin(array_as_str_unchecked)]\n pub fn as_str_unchecked(self) -> str<N> {}\n}\n\nimpl<let N: u32> From<str<N>> for [u8; N] {\n /// Returns an array of the string bytes.\n fn from(s: str<N>) -> Self {\n s.as_bytes()\n }\n}\n\nmod test {\n #[test]\n fn map_empty() {\n assert_eq([].map(|x| x + 1), []);\n }\n\n global arr_with_100_values: [u32; 100] = [\n 42, 123, 87, 93, 48, 80, 50, 5, 104, 84, 70, 47, 119, 66, 71, 121, 3, 29, 42, 118, 2, 54,\n 89, 44, 81, 0, 26, 106, 68, 96, 84, 48, 95, 54, 45, 32, 89, 100, 109, 19, 37, 41, 19, 98,\n 53, 114, 107, 66, 6, 74, 13, 19, 105, 64, 123, 28, 44, 50, 89, 58, 123, 126, 21, 43, 86, 35,\n 21, 62, 82, 0, 108, 120, 72, 72, 62, 80, 12, 71, 70, 86, 116, 73, 38, 15, 127, 81, 30, 8,\n 125, 28, 26, 69, 114, 63, 27, 28, 61, 42, 13, 32,\n ];\n global expected_with_100_values: [u32; 100] = [\n 0, 0, 2, 3, 5, 6, 8, 12, 13, 13, 15, 19, 19, 19, 21, 21, 26, 26, 27, 28, 28, 28, 29, 30, 32,\n 32, 35, 37, 38, 41, 42, 42, 42, 43, 44, 44, 45, 47, 48, 48, 50, 50, 53, 54, 54, 58, 61, 62,\n 62, 63, 64, 66, 66, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 80, 80, 81, 81, 82, 84, 84, 86,\n 86, 87, 89, 89, 89, 93, 95, 96, 98, 100, 104, 105, 106, 107, 108, 109, 114, 114, 116, 118,\n 119, 120, 121, 123, 123, 123, 125, 126, 127,\n ];\n fn sort_u32(a: u32, b: u32) -> bool {\n a <= b\n }\n\n #[test]\n fn test_sort() {\n let arr: [u32; 7] = [3, 6, 8, 10, 1, 2, 1];\n\n let sorted = arr.sort();\n\n let expected: [u32; 7] = [1, 1, 2, 3, 6, 8, 10];\n assert(sorted == expected);\n }\n\n #[test]\n fn test_sort_100_values() {\n let arr: [u32; 100] = [\n 42, 123, 87, 93, 48, 80, 50, 5, 104, 84, 70, 47, 119, 66, 71, 121, 3, 29, 42, 118, 2,\n 54, 89, 44, 81, 0, 26, 106, 68, 96, 84, 48, 95, 54, 45, 32, 89, 100, 109, 19, 37, 41,\n 19, 98, 53, 114, 107, 66, 6, 74, 13, 19, 105, 64, 123, 28, 44, 50, 89, 58, 123, 126, 21,\n 43, 86, 35, 21, 62, 82, 0, 108, 120, 72, 72, 62, 80, 12, 71, 70, 86, 116, 73, 38, 15,\n 127, 81, 30, 8, 125, 28, 26, 69, 114, 63, 27, 28, 61, 42, 13, 32,\n ];\n\n let sorted = arr.sort();\n\n let expected: [u32; 100] = [\n 0, 0, 2, 3, 5, 6, 8, 12, 13, 13, 15, 19, 19, 19, 21, 21, 26, 26, 27, 28, 28, 28, 29, 30,\n 32, 32, 35, 37, 38, 41, 42, 42, 42, 43, 44, 44, 45, 47, 48, 48, 50, 50, 53, 54, 54, 58,\n 61, 62, 62, 63, 64, 66, 66, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 80, 80, 81, 81, 82,\n 84, 84, 86, 86, 87, 89, 89, 89, 93, 95, 96, 98, 100, 104, 105, 106, 107, 108, 109, 114,\n 114, 116, 118, 119, 120, 121, 123, 123, 123, 125, 126, 127,\n ];\n assert(sorted == expected);\n }\n\n #[test]\n fn test_sort_100_values_comptime() {\n let sorted = arr_with_100_values.sort();\n assert(sorted == expected_with_100_values);\n }\n\n #[test]\n fn test_sort_via() {\n let arr: [u32; 7] = [3, 6, 8, 10, 1, 2, 1];\n\n let sorted = arr.sort_via(sort_u32);\n\n let expected: [u32; 7] = [1, 1, 2, 3, 6, 8, 10];\n assert(sorted == expected);\n }\n\n #[test]\n fn test_sort_via_100_values() {\n let arr: [u32; 100] = [\n 42, 123, 87, 93, 48, 80, 50, 5, 104, 84, 70, 47, 119, 66, 71, 121, 3, 29, 42, 118, 2,\n 54, 89, 44, 81, 0, 26, 106, 68, 96, 84, 48, 95, 54, 45, 32, 89, 100, 109, 19, 37, 41,\n 19, 98, 53, 114, 107, 66, 6, 74, 13, 19, 105, 64, 123, 28, 44, 50, 89, 58, 123, 126, 21,\n 43, 86, 35, 21, 62, 82, 0, 108, 120, 72, 72, 62, 80, 12, 71, 70, 86, 116, 73, 38, 15,\n 127, 81, 30, 8, 125, 28, 26, 69, 114, 63, 27, 28, 61, 42, 13, 32,\n ];\n\n let sorted = arr.sort_via(sort_u32);\n\n let expected: [u32; 100] = [\n 0, 0, 2, 3, 5, 6, 8, 12, 13, 13, 15, 19, 19, 19, 21, 21, 26, 26, 27, 28, 28, 28, 29, 30,\n 32, 32, 35, 37, 38, 41, 42, 42, 42, 43, 44, 44, 45, 47, 48, 48, 50, 50, 53, 54, 54, 58,\n 61, 62, 62, 63, 64, 66, 66, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 80, 80, 81, 81, 82,\n 84, 84, 86, 86, 87, 89, 89, 89, 93, 95, 96, 98, 100, 104, 105, 106, 107, 108, 109, 114,\n 114, 116, 118, 119, 120, 121, 123, 123, 123, 125, 126, 127,\n ];\n assert(sorted == expected);\n }\n\n #[test]\n fn mapi_empty() {\n assert_eq([].mapi(|i, x| i * x + 1), []);\n }\n\n #[test]\n fn for_each_empty() {\n let empty_array: [Field; 0] = [];\n empty_array.for_each(|_x| assert(false));\n }\n\n #[test]\n fn for_eachi_empty() {\n let empty_array: [Field; 0] = [];\n empty_array.for_eachi(|_i, _x| assert(false));\n }\n\n #[test]\n fn map_example() {\n let a = [1, 2, 3];\n let b = a.map(|a| a * 2);\n assert_eq(b, [2, 4, 6]);\n }\n\n #[test]\n fn mapi_example() {\n let a = [1, 2, 3];\n let b = a.mapi(|i, a| i + a * 2);\n assert_eq(b, [2, 5, 8]);\n }\n\n #[test]\n fn for_each_example() {\n let a = [1, 2, 3];\n let mut b = [0, 0, 0];\n let b_ref = &mut b;\n let mut i = 0;\n let i_ref = &mut i;\n a.for_each(|x| {\n b_ref[*i_ref] = x * 2;\n *i_ref += 1;\n });\n assert_eq(b, [2, 4, 6]);\n assert_eq(i, 3);\n }\n\n #[test]\n fn for_eachi_example() {\n let a = [1, 2, 3];\n let mut b = [0, 0, 0];\n let b_ref = &mut b;\n a.for_eachi(|i, a| { b_ref[i] = i + a * 2; });\n assert_eq(b, [2, 5, 8]);\n }\n\n #[test]\n fn concat() {\n let arr1 = [1, 2, 3, 4];\n let arr2 = [6, 7, 8, 9, 10, 11];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, [1, 2, 3, 4, 6, 7, 8, 9, 10, 11]);\n }\n\n #[test]\n fn concat_zero_length_with_something() {\n let arr1 = [];\n let arr2 = [1];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, [1]);\n }\n\n #[test]\n fn concat_something_with_zero_length() {\n let arr1 = [1];\n let arr2 = [];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, [1]);\n }\n\n #[test]\n fn concat_zero_lengths() {\n let arr1: [Field; 0] = [];\n let arr2: [Field; 0] = [];\n let concatenated_arr = arr1.concat(arr2);\n assert_eq(concatenated_arr, []);\n }\n}\n"
|
|
4524
|
+
"source": "use crate::{reader::Reader, serialization::{Deserialize, Serialize}, writer::Writer};\nuse std::embedded_curve_ops::EmbeddedCurvePoint;\nuse std::embedded_curve_ops::EmbeddedCurveScalar;\n\nglobal BOOL_SERIALIZED_LEN: u32 = 1;\nglobal U8_SERIALIZED_LEN: u32 = 1;\nglobal U16_SERIALIZED_LEN: u32 = 1;\nglobal U32_SERIALIZED_LEN: u32 = 1;\nglobal U64_SERIALIZED_LEN: u32 = 1;\nglobal U128_SERIALIZED_LEN: u32 = 1;\nglobal FIELD_SERIALIZED_LEN: u32 = 1;\nglobal I8_SERIALIZED_LEN: u32 = 1;\nglobal I16_SERIALIZED_LEN: u32 = 1;\nglobal I32_SERIALIZED_LEN: u32 = 1;\nglobal I64_SERIALIZED_LEN: u32 = 1;\n\nimpl Serialize for bool {\n let N: u32 = BOOL_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for bool {\n let N: u32 = BOOL_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> bool {\n reader.read() != 0\n }\n}\n\nimpl Serialize for u8 {\n let N: u32 = U8_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u8 {\n let N: u32 = U8_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u8\n }\n}\n\nimpl Serialize for u16 {\n let N: u32 = U16_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u16 {\n let N: u32 = U16_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u16\n }\n}\n\nimpl Serialize for u32 {\n let N: u32 = U32_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u32 {\n let N: u32 = U32_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u32\n }\n}\n\nimpl Serialize for u64 {\n let N: u32 = U64_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u64 {\n let N: u32 = U64_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u64\n }\n}\n\nimpl Serialize for u128 {\n let N: u32 = U128_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as Field);\n }\n}\n\nimpl Deserialize for u128 {\n let N: u32 = U128_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u128\n }\n}\n\nimpl Serialize for Field {\n let N: u32 = FIELD_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self);\n }\n}\n\nimpl Deserialize for Field {\n let N: u32 = FIELD_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read()\n }\n}\n\nimpl Serialize for i8 {\n let N: u32 = I8_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u8 as Field);\n }\n}\n\nimpl Deserialize for i8 {\n let N: u32 = I8_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u8 as i8\n }\n}\n\nimpl Serialize for i16 {\n let N: u32 = I16_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u16 as Field);\n }\n}\n\nimpl Deserialize for i16 {\n let N: u32 = I16_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u16 as i16\n }\n}\n\nimpl Serialize for i32 {\n let N: u32 = I32_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u32 as Field);\n }\n}\n\nimpl Deserialize for i32 {\n let N: u32 = I32_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u32 as i32\n }\n}\n\nimpl Serialize for i64 {\n let N: u32 = I64_SERIALIZED_LEN;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self as u64 as Field);\n }\n}\n\nimpl Deserialize for i64 {\n let N: u32 = I64_SERIALIZED_LEN;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n reader.read() as u64 as i64\n }\n}\n\nimpl<T, let M: u32> Serialize for [T; M]\nwhere\n T: Serialize,\n{\n let N: u32 = <T as Serialize>::N * M;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n for i in 0..M {\n self[i].stream_serialize(writer);\n }\n }\n}\n\nimpl<T, let M: u32> Deserialize for [T; M]\nwhere\n T: Deserialize,\n{\n let N: u32 = <T as Deserialize>::N * M;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n let mut result: [T; M] = std::mem::zeroed();\n for i in 0..M {\n result[i] = T::stream_deserialize(reader);\n }\n result\n }\n}\n\nimpl<T> Serialize for Option<T>\nwhere\n T: Serialize,\n{\n let N: u32 = <T as Serialize>::N + 1;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write_bool(self.is_some());\n if self.is_some() {\n self.unwrap_unchecked().stream_serialize(writer);\n } else {\n writer.advance_offset(<T as Serialize>::N);\n }\n }\n}\n\nimpl<T> Deserialize for Option<T>\nwhere\n T: Deserialize,\n{\n let N: u32 = <T as Deserialize>::N + 1;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n if reader.read_bool() {\n Option::some(<T as Deserialize>::stream_deserialize(reader))\n } else {\n reader.advance_offset(<T as Deserialize>::N);\n Option::none()\n }\n }\n}\n\nglobal SCALAR_SIZE: u32 = 2;\n\nimpl Serialize for EmbeddedCurveScalar {\n\n let N: u32 = SCALAR_SIZE;\n\n fn serialize(self) -> [Field; SCALAR_SIZE] {\n [self.lo, self.hi]\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self.lo);\n writer.write(self.hi);\n }\n}\n\nimpl Deserialize for EmbeddedCurveScalar {\n let N: u32 = SCALAR_SIZE;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n Self { lo: fields[0], hi: fields[1] }\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n Self { lo: reader.read(), hi: reader.read() }\n }\n}\n\nglobal POINT_SIZE: u32 = 2;\n\nimpl Serialize for EmbeddedCurvePoint {\n let N: u32 = POINT_SIZE;\n\n fn serialize(self) -> [Field; Self::N] {\n [self.x, self.y]\n }\n\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n writer.write(self.x);\n writer.write(self.y);\n }\n}\n\nimpl Deserialize for EmbeddedCurvePoint {\n let N: u32 = POINT_SIZE;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n Self { x: fields[0], y: fields[1] }\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n Self { x: reader.read(), y: reader.read() }\n }\n}\n\nimpl<let M: u32> Deserialize for str<M> {\n let N: u32 = M;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n let u8_arr = <[u8; Self::N] as Deserialize>::stream_deserialize(reader);\n str::<Self::N>::from(u8_arr)\n }\n}\n\nimpl<let M: u32> Serialize for str<M> {\n let N: u32 = M;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n self.as_bytes().stream_serialize(writer);\n }\n}\n\n// Note: Not deriving this because it's not supported to call derive_serialize on a \"remote\" struct (and it will never\n// be supported).\nimpl<T, let M: u32> Deserialize for BoundedVec<T, M>\nwhere\n T: Deserialize,\n{\n let N: u32 = <T as Deserialize>::N * M + 1;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n let mut new_bounded_vec: BoundedVec<T, M> = BoundedVec::new();\n let payload_len = Self::N - 1;\n\n // Length is stored in the last field as we need to match intrinsic Noir serialization and the `len` struct\n // field is after `storage` struct field (see `bounded_vec.nr` in noir-stdlib)\n let len = reader.peek_offset(payload_len) as u32;\n\n for i in 0..M {\n if i < len {\n new_bounded_vec.push(<T as Deserialize>::stream_deserialize(reader));\n }\n }\n\n // +1 for the length of the BoundedVec\n reader.advance_offset((M - len) * <T as Deserialize>::N + 1);\n\n new_bounded_vec\n }\n}\n\n// This may cause issues if used as program input, because noir disallows empty arrays for program input.\n// I think this is okay because I don't foresee a unit type being used as input. But leaving this comment as a hint\n// if someone does run into this in the future.\nimpl Deserialize for () {\n let N: u32 = 0;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(_reader: &mut Reader<K>) -> Self {\n ()\n }\n}\n\n// Note: Not deriving this because it's not supported to call derive_serialize on a \"remote\" struct (and it will never\n// be supported).\nimpl<T, let M: u32> Serialize for BoundedVec<T, M>\nwhere\n T: Serialize,\n{\n let N: u32 = <T as Serialize>::N * M + 1; // +1 for the length of the BoundedVec\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: Writer<Self::N> = Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n self.storage().stream_serialize(writer);\n // Length is stored in the last field as we need to match intrinsic Noir serialization and the `len` struct\n // field is after `storage` struct field (see `bounded_vec.nr` in noir-stdlib)\n writer.write_u32(self.len() as u32);\n }\n}\n\n// Create a slice of the given length with each element made from `f(i)` where `i` is the current index\ncomptime fn make_slice<Env, T>(length: u32, f: fn[Env](u32) -> T) -> [T] {\n let mut slice = @[];\n for i in 0..length {\n slice = slice.push_back(f(i));\n }\n slice\n}\n\n// Implements Serialize and Deserialize for an arbitrary tuple type\ncomptime fn impl_serialize_for_tuple(_m: Module, length: u32) -> Quoted {\n // `T0`, `T1`, `T2`\n let type_names = make_slice(length, |i| f\"T{i}\".quoted_contents());\n\n // `result0`, `result1`, `result2`\n let result_names = make_slice(length, |i| f\"result{i}\".quoted_contents());\n\n // `T0, T1, T2`\n let field_generics = type_names.join(quote [,]);\n\n // `<T0 as Serialize>::N + <T1 as Serialize>::N + <T2 as Serialize>::N`\n let full_size_serialize = type_names\n .map(|type_name| quote {\n <$type_name as Serialize>::N\n })\n .join(quote [+]);\n\n // `<T0 as Deserialize>::N + <T1 as Deserialize>::N + <T2 as Deserialize>::N`\n let full_size_deserialize = type_names\n .map(|type_name| quote {\n <$type_name as Deserialize>::N\n })\n .join(quote [+]);\n\n // `T0: Serialize, T1: Serialize, T2: Serialize,`\n let serialize_constraints = type_names\n .map(|field_name| quote {\n $field_name: Serialize,\n })\n .join(quote []);\n\n // `T0: Deserialize, T1: Deserialize, T2: Deserialize,`\n let deserialize_constraints = type_names\n .map(|field_name| quote {\n $field_name: Deserialize,\n })\n .join(quote []);\n\n // Statements to serialize each field\n let serialized_fields = type_names\n .mapi(|i, _type_name| quote {\n $crate::serialization::Serialize::stream_serialize(self.$i, writer);\n })\n .join(quote []);\n\n // Statements to deserialize each field\n let deserialized_fields = type_names\n .mapi(|i, type_name| {\n let result_name = result_names[i];\n quote {\n let $result_name = <$type_name as $crate::serialization::Deserialize>::stream_deserialize(reader);\n }\n })\n .join(quote []);\n let deserialize_results = result_names.join(quote [,]);\n\n quote {\n impl<$field_generics> Serialize for ($field_generics) where $serialize_constraints {\n let N: u32 = $full_size_serialize;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: $crate::writer::Writer<Self::N> = $crate::writer::Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut $crate::writer::Writer<K>) {\n\n $serialized_fields\n }\n }\n\n impl<$field_generics> Deserialize for ($field_generics) where $deserialize_constraints {\n let N: u32 = $full_size_deserialize;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = $crate::reader::Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n \n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut $crate::reader::Reader<K>) -> Self {\n $deserialized_fields\n ($deserialize_results)\n }\n }\n }\n}\n\n// Keeping these manual impls. They are more efficient since they do not\n// require copying sub-arrays from any serialized arrays.\nimpl<T1> Serialize for (T1,)\nwhere\n T1: Serialize,\n{\n let N: u32 = <T1 as Serialize>::N;\n\n fn serialize(self) -> [Field; Self::N] {\n let mut writer: crate::writer::Writer<Self::N> = crate::writer::Writer::new();\n self.stream_serialize(&mut writer);\n writer.finish()\n }\n\n #[inline_always]\n fn stream_serialize<let K: u32>(self, writer: &mut Writer<K>) {\n self.0.stream_serialize(writer);\n }\n}\n\nimpl<T1> Deserialize for (T1,)\nwhere\n T1: Deserialize,\n{\n let N: u32 = <T1 as Deserialize>::N;\n\n fn deserialize(fields: [Field; Self::N]) -> Self {\n let mut reader = crate::reader::Reader::new(fields);\n let result = Self::stream_deserialize(&mut reader);\n reader.finish();\n result\n }\n\n #[inline_always]\n fn stream_deserialize<let K: u32>(reader: &mut Reader<K>) -> Self {\n (<T1 as Deserialize>::stream_deserialize(reader),)\n }\n}\n\n#[impl_serialize_for_tuple(2)]\n#[impl_serialize_for_tuple(3)]\n#[impl_serialize_for_tuple(4)]\n#[impl_serialize_for_tuple(5)]\n#[impl_serialize_for_tuple(6)]\nmod impls {\n use crate::serialization::{Deserialize, Serialize};\n}\n\n#[test]\nunconstrained fn bounded_vec_serialization() {\n // Test empty BoundedVec\n let empty_vec: BoundedVec<Field, 3> = BoundedVec::from_array([]);\n let serialized = empty_vec.serialize();\n let deserialized = BoundedVec::<Field, 3>::deserialize(serialized);\n assert_eq(empty_vec, deserialized);\n assert_eq(deserialized.len(), 0);\n\n // Test partially filled BoundedVec\n let partial_vec: BoundedVec<[u32; 2], 3> = BoundedVec::from_array([[1, 2]]);\n let serialized = partial_vec.serialize();\n let deserialized = BoundedVec::<[u32; 2], 3>::deserialize(serialized);\n assert_eq(partial_vec, deserialized);\n assert_eq(deserialized.len(), 1);\n assert_eq(deserialized.get(0), [1, 2]);\n\n // Test full BoundedVec\n let full_vec: BoundedVec<[u32; 2], 3> = BoundedVec::from_array([[1, 2], [3, 4], [5, 6]]);\n let serialized = full_vec.serialize();\n let deserialized = BoundedVec::<[u32; 2], 3>::deserialize(serialized);\n assert_eq(full_vec, deserialized);\n assert_eq(deserialized.len(), 3);\n assert_eq(deserialized.get(0), [1, 2]);\n assert_eq(deserialized.get(1), [3, 4]);\n assert_eq(deserialized.get(2), [5, 6]);\n}\n"
|
|
4619
4525
|
},
|
|
4620
4526
|
"41": {
|
|
4621
4527
|
"function_locations": [
|
|
@@ -4629,91 +4535,91 @@
|
|
|
4629
4535
|
},
|
|
4630
4536
|
{
|
|
4631
4537
|
"name": "Option<T>::is_none",
|
|
4632
|
-
"start":
|
|
4538
|
+
"start": 672
|
|
4633
4539
|
},
|
|
4634
4540
|
{
|
|
4635
4541
|
"name": "Option<T>::is_some",
|
|
4636
|
-
"start":
|
|
4542
|
+
"start": 774
|
|
4637
4543
|
},
|
|
4638
4544
|
{
|
|
4639
4545
|
"name": "Option<T>::unwrap",
|
|
4640
|
-
"start":
|
|
4546
|
+
"start": 898
|
|
4641
4547
|
},
|
|
4642
4548
|
{
|
|
4643
4549
|
"name": "Option<T>::unwrap_unchecked",
|
|
4644
|
-
"start":
|
|
4550
|
+
"start": 1196
|
|
4645
4551
|
},
|
|
4646
4552
|
{
|
|
4647
4553
|
"name": "Option<T>::unwrap_or",
|
|
4648
|
-
"start":
|
|
4554
|
+
"start": 1368
|
|
4649
4555
|
},
|
|
4650
4556
|
{
|
|
4651
4557
|
"name": "Option<T>::unwrap_or_else",
|
|
4652
|
-
"start":
|
|
4558
|
+
"start": 1668
|
|
4653
4559
|
},
|
|
4654
4560
|
{
|
|
4655
4561
|
"name": "Option<T>::expect",
|
|
4656
|
-
"start":
|
|
4562
|
+
"start": 1969
|
|
4657
4563
|
},
|
|
4658
4564
|
{
|
|
4659
4565
|
"name": "Option<T>::map",
|
|
4660
|
-
"start":
|
|
4566
|
+
"start": 2190
|
|
4661
4567
|
},
|
|
4662
4568
|
{
|
|
4663
4569
|
"name": "Option<T>::map_or",
|
|
4664
|
-
"start":
|
|
4570
|
+
"start": 2490
|
|
4665
4571
|
},
|
|
4666
4572
|
{
|
|
4667
4573
|
"name": "Option<T>::map_or_else",
|
|
4668
|
-
"start":
|
|
4574
|
+
"start": 2784
|
|
4669
4575
|
},
|
|
4670
4576
|
{
|
|
4671
4577
|
"name": "Option<T>::and",
|
|
4672
|
-
"start":
|
|
4578
|
+
"start": 3009
|
|
4673
4579
|
},
|
|
4674
4580
|
{
|
|
4675
4581
|
"name": "Option<T>::and_then",
|
|
4676
|
-
"start":
|
|
4582
|
+
"start": 3446
|
|
4677
4583
|
},
|
|
4678
4584
|
{
|
|
4679
4585
|
"name": "Option<T>::or",
|
|
4680
|
-
"start":
|
|
4586
|
+
"start": 3669
|
|
4681
4587
|
},
|
|
4682
4588
|
{
|
|
4683
4589
|
"name": "Option<T>::or_else",
|
|
4684
|
-
"start":
|
|
4590
|
+
"start": 3902
|
|
4685
4591
|
},
|
|
4686
4592
|
{
|
|
4687
4593
|
"name": "Option<T>::xor",
|
|
4688
|
-
"start":
|
|
4594
|
+
"start": 4192
|
|
4689
4595
|
},
|
|
4690
4596
|
{
|
|
4691
4597
|
"name": "Option<T>::filter",
|
|
4692
|
-
"start":
|
|
4598
|
+
"start": 4636
|
|
4693
4599
|
},
|
|
4694
4600
|
{
|
|
4695
4601
|
"name": "Option<T>::flatten",
|
|
4696
|
-
"start":
|
|
4602
|
+
"start": 5065
|
|
4697
4603
|
},
|
|
4698
4604
|
{
|
|
4699
4605
|
"name": "<impl Default for Option<T>>::default",
|
|
4700
|
-
"start":
|
|
4606
|
+
"start": 5242
|
|
4701
4607
|
},
|
|
4702
4608
|
{
|
|
4703
4609
|
"name": "<impl Eq for Option<T>>::eq",
|
|
4704
|
-
"start":
|
|
4610
|
+
"start": 5357
|
|
4705
4611
|
},
|
|
4706
4612
|
{
|
|
4707
4613
|
"name": "<impl Hash for Option<T>>::hash",
|
|
4708
|
-
"start":
|
|
4614
|
+
"start": 5706
|
|
4709
4615
|
},
|
|
4710
4616
|
{
|
|
4711
4617
|
"name": "<impl Ord for Option<T>>::cmp",
|
|
4712
|
-
"start":
|
|
4618
|
+
"start": 5975
|
|
4713
4619
|
}
|
|
4714
4620
|
],
|
|
4715
4621
|
"path": "std/option.nr",
|
|
4716
|
-
"source": "use crate::cmp::{Eq, Ord, Ordering};\nuse crate::default::Default;\nuse crate::hash::{Hash, Hasher};\n\n/// Represents a value of type T or its absence.\n/// Use `Option::some(value)` to construct a value or `Option::none()` to record the absence of one.\npub struct Option<T> {\n _is_some: bool,\n _value: T,\n}\n\nimpl<T> Option<T> {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::mem::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else<Env>(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n pub fn expect<let N: u32, MessageTypes>(self, message: fmtstr<N, MessageTypes>) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map<U, Env>(self, f: fn[Env](T) -> U) -> Option<U> {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or<U, Env>(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else<U, Env1, Env2>(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then<U, Env>(self, f: fn[Env](T) -> Option<U>) -> Option<U> {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else<Env>(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter<Env>(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option<Option<T>> into a Option<T>.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option<Option<T>>) -> Option<T> {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n\nimpl<T> Default for Option<T> {\n fn default() -> Self {\n Option::none()\n }\n}\n\nimpl<T> Eq for Option<T>\nwhere\n T: Eq,\n{\n fn eq(self, other: Self) -> bool {\n if self._is_some == other._is_some {\n if self._is_some {\n self._value == other._value\n } else {\n true\n }\n } else {\n false\n }\n }\n}\n\nimpl<T> Hash for Option<T>\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self._is_some.hash(state);\n if self._is_some {\n self._value.hash(state);\n }\n }\n}\n\n// For this impl we're declaring Option::none < Option::some\nimpl<T> Ord for Option<T>\nwhere\n T: Ord,\n{\n fn cmp(self, other: Self) -> Ordering {\n if self._is_some {\n if other._is_some {\n self._value.cmp(other._value)\n } else {\n Ordering::greater()\n }\n } else if other._is_some {\n Ordering::less()\n } else {\n Ordering::equal()\n }\n }\n}\n"
|
|
4622
|
+
"source": "use crate::cmp::{Eq, Ord, Ordering};\nuse crate::default::Default;\nuse crate::hash::{Hash, Hasher};\n\n/// Represents a value of type T or its absence.\n/// Use `Option::some(value)` to construct a value or `Option::none()` to record the absence of one.\npub struct Option<T> {\n _is_some: bool,\n _value: T,\n}\n\nimpl<T> Option<T> {\n /// Constructs a None value\n pub fn none() -> Self {\n Self { _is_some: false, _value: crate::mem::zeroed() }\n }\n\n /// Constructs a Some wrapper around the given value\n pub fn some(_value: T) -> Self {\n Self { _is_some: true, _value }\n }\n\n /// True if this Option is None\n pub fn is_none(&self) -> bool {\n !self._is_some\n }\n\n /// True if this Option is Some\n pub fn is_some(&self) -> bool {\n self._is_some\n }\n\n /// Asserts `self.is_some()` and returns the wrapped value.\n pub fn unwrap(self) -> T {\n assert(self._is_some);\n self._value\n }\n\n /// Returns the inner value without asserting `self.is_some()`\n /// Note that if `self` is `None`, there is no guarantee what value will be returned,\n /// only that it will be of type `T`.\n pub fn unwrap_unchecked(self) -> T {\n self._value\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, returns the given default value.\n pub fn unwrap_or(self, default: T) -> T {\n if self._is_some {\n self._value\n } else {\n default\n }\n }\n\n /// Returns the wrapped value if `self.is_some()`. Otherwise, calls the given function to return\n /// a default value.\n pub fn unwrap_or_else<Env>(self, default: fn[Env]() -> T) -> T {\n if self._is_some {\n self._value\n } else {\n default()\n }\n }\n\n /// Asserts `self.is_some()` with a provided custom message and returns the contained `Some` value\n pub fn expect<let N: u32, MessageTypes>(self, message: fmtstr<N, MessageTypes>) -> T {\n assert(self.is_some(), message);\n self._value\n }\n\n /// If self is `Some(x)`, this returns `Some(f(x))`. Otherwise, this returns `None`.\n pub fn map<U, Env>(self, f: fn[Env](T) -> U) -> Option<U> {\n if self._is_some {\n Option::some(f(self._value))\n } else {\n Option::none()\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns the given default value.\n pub fn map_or<U, Env>(self, default: U, f: fn[Env](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default\n }\n }\n\n /// If self is `Some(x)`, this returns `f(x)`. Otherwise, this returns `default()`.\n pub fn map_or_else<U, Env1, Env2>(self, default: fn[Env1]() -> U, f: fn[Env2](T) -> U) -> U {\n if self._is_some {\n f(self._value)\n } else {\n default()\n }\n }\n\n /// Returns None if self is None. Otherwise, this returns `other`.\n pub fn and(self, other: Self) -> Self {\n if self.is_none() {\n Option::none()\n } else {\n other\n }\n }\n\n /// If self is None, this returns None. Otherwise, this calls the given function\n /// with the Some value contained within self, and returns the result of that call.\n ///\n /// In some languages this function is called `flat_map` or `bind`.\n pub fn and_then<U, Env>(self, f: fn[Env](T) -> Option<U>) -> Option<U> {\n if self._is_some {\n f(self._value)\n } else {\n Option::none()\n }\n }\n\n /// If self is Some, return self. Otherwise, return `other`.\n pub fn or(self, other: Self) -> Self {\n if self._is_some {\n self\n } else {\n other\n }\n }\n\n /// If self is Some, return self. Otherwise, return `default()`.\n pub fn or_else<Env>(self, default: fn[Env]() -> Self) -> Self {\n if self._is_some {\n self\n } else {\n default()\n }\n }\n\n // If only one of the two Options is Some, return that option.\n // Otherwise, if both options are Some or both are None, None is returned.\n pub fn xor(self, other: Self) -> Self {\n if self._is_some {\n if other._is_some {\n Option::none()\n } else {\n self\n }\n } else if other._is_some {\n other\n } else {\n Option::none()\n }\n }\n\n /// Returns `Some(x)` if self is `Some(x)` and `predicate(x)` is true.\n /// Otherwise, this returns `None`\n pub fn filter<Env>(self, predicate: fn[Env](T) -> bool) -> Self {\n if self._is_some {\n if predicate(self._value) {\n self\n } else {\n Option::none()\n }\n } else {\n Option::none()\n }\n }\n\n /// Flattens an Option<Option<T>> into a Option<T>.\n /// This returns None if the outer Option is None. Otherwise, this returns the inner Option.\n pub fn flatten(option: Option<Option<T>>) -> Option<T> {\n if option._is_some {\n option._value\n } else {\n Option::none()\n }\n }\n}\n\nimpl<T> Default for Option<T> {\n fn default() -> Self {\n Option::none()\n }\n}\n\nimpl<T> Eq for Option<T>\nwhere\n T: Eq,\n{\n fn eq(self, other: Self) -> bool {\n if self._is_some == other._is_some {\n if self._is_some {\n self._value == other._value\n } else {\n true\n }\n } else {\n false\n }\n }\n}\n\nimpl<T> Hash for Option<T>\nwhere\n T: Hash,\n{\n fn hash<H>(self, state: &mut H)\n where\n H: Hasher,\n {\n self._is_some.hash(state);\n if self._is_some {\n self._value.hash(state);\n }\n }\n}\n\n// For this impl we're declaring Option::none < Option::some\nimpl<T> Ord for Option<T>\nwhere\n T: Ord,\n{\n fn cmp(self, other: Self) -> Ordering {\n if self._is_some {\n if other._is_some {\n self._value.cmp(other._value)\n } else {\n Ordering::greater()\n }\n } else if other._is_some {\n Ordering::less()\n } else {\n Ordering::equal()\n }\n }\n}\n"
|
|
4717
4623
|
},
|
|
4718
4624
|
"42": {
|
|
4719
4625
|
"function_locations": [
|
|
@@ -4755,241 +4661,237 @@
|
|
|
4755
4661
|
"name": "<impl Eq for u8>::eq",
|
|
4756
4662
|
"start": 1282
|
|
4757
4663
|
},
|
|
4758
|
-
{
|
|
4759
|
-
"name": "<impl Eq for u1>::eq",
|
|
4760
|
-
"start": 1366
|
|
4761
|
-
},
|
|
4762
4664
|
{
|
|
4763
4665
|
"name": "<impl Eq for i8>::eq",
|
|
4764
|
-
"start":
|
|
4666
|
+
"start": 1366
|
|
4765
4667
|
},
|
|
4766
4668
|
{
|
|
4767
4669
|
"name": "<impl Eq for i16>::eq",
|
|
4768
|
-
"start":
|
|
4670
|
+
"start": 1452
|
|
4769
4671
|
},
|
|
4770
4672
|
{
|
|
4771
4673
|
"name": "<impl Eq for i32>::eq",
|
|
4772
|
-
"start":
|
|
4674
|
+
"start": 1538
|
|
4773
4675
|
},
|
|
4774
4676
|
{
|
|
4775
4677
|
"name": "<impl Eq for i64>::eq",
|
|
4776
|
-
"start":
|
|
4678
|
+
"start": 1624
|
|
4777
4679
|
},
|
|
4778
4680
|
{
|
|
4779
4681
|
"name": "<impl Eq for ()>::eq",
|
|
4780
|
-
"start":
|
|
4682
|
+
"start": 1717
|
|
4781
4683
|
},
|
|
4782
4684
|
{
|
|
4783
4685
|
"name": "<impl Eq for bool>::eq",
|
|
4784
|
-
"start":
|
|
4686
|
+
"start": 1796
|
|
4785
4687
|
},
|
|
4786
4688
|
{
|
|
4787
4689
|
"name": "<impl Eq for [T; N]>::eq",
|
|
4788
|
-
"start":
|
|
4690
|
+
"start": 1921
|
|
4789
4691
|
},
|
|
4790
4692
|
{
|
|
4791
4693
|
"name": "<impl Eq for [T]>::eq",
|
|
4792
|
-
"start":
|
|
4694
|
+
"start": 2139
|
|
4793
4695
|
},
|
|
4794
4696
|
{
|
|
4795
4697
|
"name": "<impl Eq for str<N>>::eq",
|
|
4796
|
-
"start":
|
|
4698
|
+
"start": 2418
|
|
4797
4699
|
},
|
|
4798
4700
|
{
|
|
4799
4701
|
"name": "make_tuple_eq_body",
|
|
4800
|
-
"start":
|
|
4702
|
+
"start": 2598
|
|
4801
4703
|
},
|
|
4802
4704
|
{
|
|
4803
4705
|
"name": "<impl Eq for (A, B)>::eq",
|
|
4804
|
-
"start":
|
|
4706
|
+
"start": 2859
|
|
4805
4707
|
},
|
|
4806
4708
|
{
|
|
4807
4709
|
"name": "<impl Eq for (A, B, C)>::eq",
|
|
4808
|
-
"start":
|
|
4710
|
+
"start": 2991
|
|
4809
4711
|
},
|
|
4810
4712
|
{
|
|
4811
4713
|
"name": "<impl Eq for (A, B, C, D)>::eq",
|
|
4812
|
-
"start":
|
|
4714
|
+
"start": 3136
|
|
4813
4715
|
},
|
|
4814
4716
|
{
|
|
4815
4717
|
"name": "<impl Eq for (A, B, C, D, E)>::eq",
|
|
4816
|
-
"start":
|
|
4718
|
+
"start": 3294
|
|
4817
4719
|
},
|
|
4818
4720
|
{
|
|
4819
4721
|
"name": "<impl Eq for (A, B, C, D, E, F)>::eq",
|
|
4820
|
-
"start":
|
|
4722
|
+
"start": 3465
|
|
4821
4723
|
},
|
|
4822
4724
|
{
|
|
4823
4725
|
"name": "<impl Eq for (A, B, C, D, E, F, G)>::eq",
|
|
4824
|
-
"start":
|
|
4726
|
+
"start": 3649
|
|
4825
4727
|
},
|
|
4826
4728
|
{
|
|
4827
4729
|
"name": "<impl Eq for (A, B, C, D, E, F, G, H)>::eq",
|
|
4828
|
-
"start":
|
|
4730
|
+
"start": 3846
|
|
4829
4731
|
},
|
|
4830
4732
|
{
|
|
4831
4733
|
"name": "<impl Eq for (A, B, C, D, E, F, G, H, I)>::eq",
|
|
4832
|
-
"start":
|
|
4734
|
+
"start": 4056
|
|
4833
4735
|
},
|
|
4834
4736
|
{
|
|
4835
4737
|
"name": "<impl Eq for (A, B, C, D, E, F, G, H, I, J)>::eq",
|
|
4836
|
-
"start":
|
|
4738
|
+
"start": 4279
|
|
4837
4739
|
},
|
|
4838
4740
|
{
|
|
4839
4741
|
"name": "<impl Eq for (A, B, C, D, E, F, G, H, I, J, K)>::eq",
|
|
4840
|
-
"start":
|
|
4742
|
+
"start": 4516
|
|
4841
4743
|
},
|
|
4842
4744
|
{
|
|
4843
4745
|
"name": "<impl Eq for (A, B, C, D, E, F, G, H, I, J, K, L)>::eq",
|
|
4844
|
-
"start":
|
|
4746
|
+
"start": 4766
|
|
4845
4747
|
},
|
|
4846
4748
|
{
|
|
4847
4749
|
"name": "<impl Eq for Ordering>::eq",
|
|
4848
|
-
"start":
|
|
4750
|
+
"start": 4876
|
|
4849
4751
|
},
|
|
4850
4752
|
{
|
|
4851
4753
|
"name": "Ordering::less",
|
|
4852
|
-
"start":
|
|
4754
|
+
"start": 5477
|
|
4853
4755
|
},
|
|
4854
4756
|
{
|
|
4855
4757
|
"name": "Ordering::equal",
|
|
4856
|
-
"start":
|
|
4758
|
+
"start": 5548
|
|
4857
4759
|
},
|
|
4858
4760
|
{
|
|
4859
4761
|
"name": "Ordering::greater",
|
|
4860
|
-
"start":
|
|
4762
|
+
"start": 5621
|
|
4861
4763
|
},
|
|
4862
4764
|
{
|
|
4863
4765
|
"name": "derive_ord",
|
|
4864
|
-
"start":
|
|
4766
|
+
"start": 5992
|
|
4865
4767
|
},
|
|
4866
4768
|
{
|
|
4867
4769
|
"name": "<impl Ord for u128>::cmp",
|
|
4868
|
-
"start":
|
|
4770
|
+
"start": 6642
|
|
4869
4771
|
},
|
|
4870
4772
|
{
|
|
4871
4773
|
"name": "<impl Ord for u64>::cmp",
|
|
4872
|
-
"start":
|
|
4774
|
+
"start": 6889
|
|
4873
4775
|
},
|
|
4874
4776
|
{
|
|
4875
4777
|
"name": "<impl Ord for u32>::cmp",
|
|
4876
|
-
"start":
|
|
4778
|
+
"start": 7137
|
|
4877
4779
|
},
|
|
4878
4780
|
{
|
|
4879
4781
|
"name": "<impl Ord for u16>::cmp",
|
|
4880
|
-
"start":
|
|
4782
|
+
"start": 7385
|
|
4881
4783
|
},
|
|
4882
4784
|
{
|
|
4883
4785
|
"name": "<impl Ord for u8>::cmp",
|
|
4884
|
-
"start":
|
|
4786
|
+
"start": 7631
|
|
4885
4787
|
},
|
|
4886
4788
|
{
|
|
4887
4789
|
"name": "<impl Ord for i8>::cmp",
|
|
4888
|
-
"start":
|
|
4790
|
+
"start": 7877
|
|
4889
4791
|
},
|
|
4890
4792
|
{
|
|
4891
4793
|
"name": "<impl Ord for i16>::cmp",
|
|
4892
|
-
"start":
|
|
4794
|
+
"start": 8125
|
|
4893
4795
|
},
|
|
4894
4796
|
{
|
|
4895
4797
|
"name": "<impl Ord for i32>::cmp",
|
|
4896
|
-
"start":
|
|
4798
|
+
"start": 8373
|
|
4897
4799
|
},
|
|
4898
4800
|
{
|
|
4899
4801
|
"name": "<impl Ord for i64>::cmp",
|
|
4900
|
-
"start":
|
|
4802
|
+
"start": 8621
|
|
4901
4803
|
},
|
|
4902
4804
|
{
|
|
4903
4805
|
"name": "<impl Ord for ()>::cmp",
|
|
4904
|
-
"start":
|
|
4806
|
+
"start": 8875
|
|
4905
4807
|
},
|
|
4906
4808
|
{
|
|
4907
4809
|
"name": "<impl Ord for bool>::cmp",
|
|
4908
|
-
"start":
|
|
4810
|
+
"start": 8974
|
|
4909
4811
|
},
|
|
4910
4812
|
{
|
|
4911
4813
|
"name": "<impl Ord for [T; N]>::cmp",
|
|
4912
|
-
"start":
|
|
4814
|
+
"start": 9444
|
|
4913
4815
|
},
|
|
4914
4816
|
{
|
|
4915
4817
|
"name": "<impl Ord for [T]>::cmp",
|
|
4916
|
-
"start":
|
|
4818
|
+
"start": 9847
|
|
4917
4819
|
},
|
|
4918
4820
|
{
|
|
4919
4821
|
"name": "make_tuple_ord_body",
|
|
4920
|
-
"start":
|
|
4822
|
+
"start": 10415
|
|
4921
4823
|
},
|
|
4922
4824
|
{
|
|
4923
4825
|
"name": "<impl Ord for (A, B)>::cmp",
|
|
4924
|
-
"start":
|
|
4826
|
+
"start": 11037
|
|
4925
4827
|
},
|
|
4926
4828
|
{
|
|
4927
4829
|
"name": "<impl Ord for (A, B, C)>::cmp",
|
|
4928
|
-
"start":
|
|
4830
|
+
"start": 11179
|
|
4929
4831
|
},
|
|
4930
4832
|
{
|
|
4931
4833
|
"name": "<impl Ord for (A, B, C, D)>::cmp",
|
|
4932
|
-
"start":
|
|
4834
|
+
"start": 11335
|
|
4933
4835
|
},
|
|
4934
4836
|
{
|
|
4935
4837
|
"name": "<impl Ord for (A, B, C, D, E)>::cmp",
|
|
4936
|
-
"start":
|
|
4838
|
+
"start": 11505
|
|
4937
4839
|
},
|
|
4938
4840
|
{
|
|
4939
4841
|
"name": "<impl Ord for (A, B, C, D, E, F)>::cmp",
|
|
4940
|
-
"start":
|
|
4842
|
+
"start": 11689
|
|
4941
4843
|
},
|
|
4942
4844
|
{
|
|
4943
4845
|
"name": "<impl Ord for (A, B, C, D, E, F, G)>::cmp",
|
|
4944
|
-
"start":
|
|
4846
|
+
"start": 11887
|
|
4945
4847
|
},
|
|
4946
4848
|
{
|
|
4947
4849
|
"name": "<impl Ord for (A, B, C, D, E, F, G, H)>::cmp",
|
|
4948
|
-
"start":
|
|
4850
|
+
"start": 12099
|
|
4949
4851
|
},
|
|
4950
4852
|
{
|
|
4951
4853
|
"name": "<impl Ord for (A, B, C, D, E, F, G, H, I)>::cmp",
|
|
4952
|
-
"start":
|
|
4854
|
+
"start": 12325
|
|
4953
4855
|
},
|
|
4954
4856
|
{
|
|
4955
4857
|
"name": "<impl Ord for (A, B, C, D, E, F, G, H, I, J)>::cmp",
|
|
4956
|
-
"start":
|
|
4858
|
+
"start": 12565
|
|
4957
4859
|
},
|
|
4958
4860
|
{
|
|
4959
4861
|
"name": "<impl Ord for (A, B, C, D, E, F, G, H, I, J, K)>::cmp",
|
|
4960
|
-
"start":
|
|
4862
|
+
"start": 12820
|
|
4961
4863
|
},
|
|
4962
4864
|
{
|
|
4963
4865
|
"name": "<impl Ord for (A, B, C, D, E, F, G, H, I, J, K, L)>::cmp",
|
|
4964
|
-
"start":
|
|
4866
|
+
"start": 13089
|
|
4965
4867
|
},
|
|
4966
4868
|
{
|
|
4967
4869
|
"name": "max",
|
|
4968
|
-
"start":
|
|
4870
|
+
"start": 13451
|
|
4969
4871
|
},
|
|
4970
4872
|
{
|
|
4971
4873
|
"name": "min",
|
|
4972
|
-
"start":
|
|
4874
|
+
"start": 13828
|
|
4973
4875
|
},
|
|
4974
4876
|
{
|
|
4975
4877
|
"name": "cmp_tests::sanity_check_min",
|
|
4976
|
-
"start":
|
|
4878
|
+
"start": 13982
|
|
4977
4879
|
},
|
|
4978
4880
|
{
|
|
4979
4881
|
"name": "cmp_tests::sanity_check_max",
|
|
4980
|
-
"start":
|
|
4882
|
+
"start": 14178
|
|
4981
4883
|
},
|
|
4982
4884
|
{
|
|
4983
4885
|
"name": "cmp_tests::correctly_handles_unequal_length_vectors",
|
|
4984
|
-
"start":
|
|
4886
|
+
"start": 14400
|
|
4985
4887
|
},
|
|
4986
4888
|
{
|
|
4987
4889
|
"name": "cmp_tests::lexicographic_ordering_for_vectors",
|
|
4988
|
-
"start":
|
|
4890
|
+
"start": 14600
|
|
4989
4891
|
}
|
|
4990
4892
|
],
|
|
4991
4893
|
"path": "std/cmp.nr",
|
|
4992
|
-
"source": "use crate::meta::ctstring::AsCtString;\nuse crate::meta::derive_via;\n\n/// Compare two values for equality\n#[derive_via(derive_eq)]\n// docs:start:eq-trait\npub trait Eq {\n fn eq(self, other: Self) -> bool;\n}\n// docs:end:eq-trait\n\n// docs:start:derive_eq\ncomptime fn derive_eq(s: TypeDefinition) -> Quoted {\n let signature = quote { fn eq(_self: Self, _other: Self) -> bool };\n let for_each_field = |name| quote { (_self.$name == _other.$name) };\n let body = |fields| {\n if s.fields_as_written().len() == 0 {\n quote { true }\n } else {\n fields\n }\n };\n crate::meta::make_trait_impl(\n s,\n quote { $crate::cmp::Eq },\n signature,\n for_each_field,\n quote { & },\n body,\n )\n}\n// docs:end:derive_eq\n\nimpl Eq for Field {\n fn eq(self, other: Field) -> bool {\n self == other\n }\n}\n\nimpl Eq for u128 {\n fn eq(self, other: u128) -> bool {\n self == other\n }\n}\nimpl Eq for u64 {\n fn eq(self, other: u64) -> bool {\n self == other\n }\n}\nimpl Eq for u32 {\n fn eq(self, other: u32) -> bool {\n self == other\n }\n}\nimpl Eq for u16 {\n fn eq(self, other: u16) -> bool {\n self == other\n }\n}\nimpl Eq for u8 {\n fn eq(self, other: u8) -> bool {\n self == other\n }\n}\nimpl Eq for u1 {\n fn eq(self, other: u1) -> bool {\n self == other\n }\n}\n\nimpl Eq for i8 {\n fn eq(self, other: i8) -> bool {\n self == other\n }\n}\nimpl Eq for i16 {\n fn eq(self, other: i16) -> bool {\n self == other\n }\n}\nimpl Eq for i32 {\n fn eq(self, other: i32) -> bool {\n self == other\n }\n}\nimpl Eq for i64 {\n fn eq(self, other: i64) -> bool {\n self == other\n }\n}\n\nimpl Eq for () {\n fn eq(_self: Self, _other: ()) -> bool {\n true\n }\n}\nimpl Eq for bool {\n fn eq(self, other: bool) -> bool {\n self == other\n }\n}\n\nimpl<T, let N: u32> Eq for [T; N]\nwhere\n T: Eq,\n{\n fn eq(self, other: [T; N]) -> bool {\n let mut result = true;\n for i in 0..self.len() {\n result &= self[i].eq(other[i]);\n }\n result\n }\n}\n\nimpl<T> Eq for [T]\nwhere\n T: Eq,\n{\n fn eq(self, other: [T]) -> bool {\n let mut result = self.len() == other.len();\n if result {\n for i in 0..self.len() {\n result &= self[i].eq(other[i]);\n }\n }\n result\n }\n}\n\nimpl<let N: u32> Eq for str<N> {\n fn eq(self, other: str<N>) -> bool {\n let self_bytes = self.as_bytes();\n let other_bytes = other.as_bytes();\n self_bytes == other_bytes\n }\n}\n\ncomptime fn make_tuple_eq_body(n: u32) -> Quoted {\n let mut body = f\"self.0.eq(other.0)\".as_ctstring();\n for i in 1u32..n {\n body = body.append_fmtstr(f\" & self.{i}.eq(other.{i})\");\n }\n f\"{body}\".quoted_contents()\n}\n\nimpl<A: Eq, B: Eq> Eq for (A, B) {\n fn eq(self, other: (A, B)) -> bool {\n make_tuple_eq_body!(2u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq> Eq for (A, B, C) {\n fn eq(self, other: (A, B, C)) -> bool {\n make_tuple_eq_body!(3u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq> Eq for (A, B, C, D) {\n fn eq(self, other: (A, B, C, D)) -> bool {\n make_tuple_eq_body!(4u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq> Eq for (A, B, C, D, E) {\n fn eq(self, other: (A, B, C, D, E)) -> bool {\n make_tuple_eq_body!(5u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq> Eq for (A, B, C, D, E, F) {\n fn eq(self, other: (A, B, C, D, E, F)) -> bool {\n make_tuple_eq_body!(6u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq> Eq for (A, B, C, D, E, F, G) {\n fn eq(self, other: (A, B, C, D, E, F, G)) -> bool {\n make_tuple_eq_body!(7u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq> Eq for (A, B, C, D, E, F, G, H) {\n fn eq(self, other: (A, B, C, D, E, F, G, H)) -> bool {\n make_tuple_eq_body!(8u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq> Eq for (A, B, C, D, E, F, G, H, I) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I)) -> bool {\n make_tuple_eq_body!(9u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq> Eq for (A, B, C, D, E, F, G, H, I, J) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I, J)) -> bool {\n make_tuple_eq_body!(10u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq, K: Eq> Eq for (A, B, C, D, E, F, G, H, I, J, K) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I, J, K)) -> bool {\n make_tuple_eq_body!(11u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq, K: Eq, L: Eq> Eq for (A, B, C, D, E, F, G, H, I, J, K, L) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I, J, K, L)) -> bool {\n make_tuple_eq_body!(12u32)\n }\n}\n\nimpl Eq for Ordering {\n fn eq(self, other: Ordering) -> bool {\n self.result == other.result\n }\n}\n\n// Noir doesn't have enums yet so we emulate (Lt | Eq | Gt) with a struct\n// that has 3 public functions for constructing the struct.\n/// A value with three states: `Ordering::less()`, `Ordering::equal()` or `Ordering::greater()`.\n/// Most often used to encode the result of a comparison operation.\npub struct Ordering {\n result: Field,\n}\n\nimpl Ordering {\n // Implementation note: 0, 1, and 2 for Lt, Eq, and Gt are built\n // into the compiler, do not change these without also updating\n // the compiler itself!\n pub fn less() -> Ordering {\n Ordering { result: 0 }\n }\n\n pub fn equal() -> Ordering {\n Ordering { result: 1 }\n }\n\n pub fn greater() -> Ordering {\n Ordering { result: 2 }\n }\n}\n\n/// Compare one object to another, returning whether it is less-than, equal-to,\n/// or greater-than the other object.\n#[derive_via(derive_ord)]\n// docs:start:ord-trait\npub trait Ord {\n fn cmp(self, other: Self) -> Ordering;\n}\n// docs:end:ord-trait\n\n// docs:start:derive_ord\ncomptime fn derive_ord(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::cmp::Ord };\n let signature = quote { fn cmp(_self: Self, _other: Self) -> $crate::cmp::Ordering };\n let for_each_field = |name| quote {\n if result == $crate::cmp::Ordering::equal() {\n result = _self.$name.cmp(_other.$name);\n }\n };\n let body = |fields| quote {\n let mut result = $crate::cmp::Ordering::equal();\n $fields\n result\n };\n crate::meta::make_trait_impl(s, name, signature, for_each_field, quote {}, body)\n}\n// docs:end:derive_ord\n\n// Note: Field deliberately does not implement Ord\n\nimpl Ord for u128 {\n fn cmp(self, other: u128) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\nimpl Ord for u64 {\n fn cmp(self, other: u64) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u32 {\n fn cmp(self, other: u32) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u16 {\n fn cmp(self, other: u16) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u8 {\n fn cmp(self, other: u8) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i8 {\n fn cmp(self, other: i8) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i16 {\n fn cmp(self, other: i16) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i32 {\n fn cmp(self, other: i32) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i64 {\n fn cmp(self, other: i64) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for () {\n fn cmp(_self: Self, _other: ()) -> Ordering {\n Ordering::equal()\n }\n}\n\nimpl Ord for bool {\n fn cmp(self, other: bool) -> Ordering {\n if self {\n if other {\n Ordering::equal()\n } else {\n Ordering::greater()\n }\n } else if other {\n Ordering::less()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl<T, let N: u32> Ord for [T; N]\nwhere\n T: Ord,\n{\n // The first non-equal element of both arrays determines\n // the ordering for the whole array.\n fn cmp(self, other: [T; N]) -> Ordering {\n let mut result = Ordering::equal();\n for i in 0..self.len() {\n if result == Ordering::equal() {\n result = self[i].cmp(other[i]);\n }\n }\n result\n }\n}\n\nimpl<T> Ord for [T]\nwhere\n T: Ord,\n{\n // The first non-equal element of both arrays determines\n // the ordering for the whole array.\n fn cmp(self, other: [T]) -> Ordering {\n let self_len = self.len();\n let other_len = other.len();\n let min_len = if self_len < other_len {\n self_len\n } else {\n other_len\n };\n\n let mut result = Ordering::equal();\n for i in 0..min_len {\n if result == Ordering::equal() {\n result = self[i].cmp(other[i]);\n }\n }\n\n if result != Ordering::equal() {\n result\n } else {\n self_len.cmp(other_len)\n }\n }\n}\n\ncomptime fn make_tuple_ord_body(n: u32) -> Quoted {\n let last = n - 1u32;\n let mut body = if last == 1 {\n f\"let result = self.0.cmp(other.0);\".as_ctstring()\n } else {\n f\"let mut result = self.0.cmp(other.0);\".as_ctstring()\n };\n for i in 1u32..last {\n body = body.append_fmtstr(\n f\" if result == Ordering::equal() {{ result = self.{i}.cmp(other.{i}); }}\",\n );\n }\n body = body.append_fmtstr(\n f\" if result != Ordering::equal() {{ result }} else {{ self.{last}.cmp(other.{last}) }}\",\n );\n f\"{body}\".quoted_contents()\n}\n\nimpl<A: Ord, B: Ord> Ord for (A, B) {\n fn cmp(self, other: (A, B)) -> Ordering {\n make_tuple_ord_body!(2u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord> Ord for (A, B, C) {\n fn cmp(self, other: (A, B, C)) -> Ordering {\n make_tuple_ord_body!(3u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord> Ord for (A, B, C, D) {\n fn cmp(self, other: (A, B, C, D)) -> Ordering {\n make_tuple_ord_body!(4u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord> Ord for (A, B, C, D, E) {\n fn cmp(self, other: (A, B, C, D, E)) -> Ordering {\n make_tuple_ord_body!(5u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord> Ord for (A, B, C, D, E, F) {\n fn cmp(self, other: (A, B, C, D, E, F)) -> Ordering {\n make_tuple_ord_body!(6u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord> Ord for (A, B, C, D, E, F, G) {\n fn cmp(self, other: (A, B, C, D, E, F, G)) -> Ordering {\n make_tuple_ord_body!(7u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord> Ord for (A, B, C, D, E, F, G, H) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H)) -> Ordering {\n make_tuple_ord_body!(8u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord> Ord for (A, B, C, D, E, F, G, H, I) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I)) -> Ordering {\n make_tuple_ord_body!(9u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord, J: Ord> Ord for (A, B, C, D, E, F, G, H, I, J) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I, J)) -> Ordering {\n make_tuple_ord_body!(10u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord, J: Ord, K: Ord> Ord for (A, B, C, D, E, F, G, H, I, J, K) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I, J, K)) -> Ordering {\n make_tuple_ord_body!(11u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord, J: Ord, K: Ord, L: Ord> Ord for (A, B, C, D, E, F, G, H, I, J, K, L) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I, J, K, L)) -> Ordering {\n make_tuple_ord_body!(12u32)\n }\n}\n\n/// Compares and returns the maximum of two values.\n///\n/// Returns the second argument if the comparison determines them to be equal.\n///\n/// # Examples\n///\n/// ```\n/// use std::cmp;\n///\n/// assert_eq(cmp::max(1, 2), 2);\n/// assert_eq(cmp::max(2, 2), 2);\n/// ```\npub fn max<T>(v1: T, v2: T) -> T\nwhere\n T: Ord,\n{\n if v1 > v2 {\n v1\n } else {\n v2\n }\n}\n\n/// Compares and returns the minimum of two values.\n///\n/// Returns the first argument if the comparison determines them to be equal.\n///\n/// # Examples\n///\n/// ```\n/// use std::cmp;\n///\n/// assert_eq(cmp::min(1, 2), 1);\n/// assert_eq(cmp::min(2, 2), 2);\n/// ```\npub fn min<T>(v1: T, v2: T) -> T\nwhere\n T: Ord,\n{\n if v1 > v2 {\n v2\n } else {\n v1\n }\n}\n\nmod cmp_tests {\n use super::{Eq, max, min, Ord};\n\n #[test]\n fn sanity_check_min() {\n assert_eq(min(0_u64, 1), 0);\n assert_eq(min(0_u64, 0), 0);\n assert_eq(min(1_u64, 1), 1);\n assert_eq(min(255_u8, 0), 0);\n }\n\n #[test]\n fn sanity_check_max() {\n assert_eq(max(0_u64, 1), 1);\n assert_eq(max(0_u64, 0), 0);\n assert_eq(max(1_u64, 1), 1);\n assert_eq(max(255_u8, 0), 255);\n }\n\n #[test]\n fn correctly_handles_unequal_length_vectors() {\n let vector_1 = [0, 1, 2, 3].as_vector();\n let vector_2 = [0, 1, 2].as_vector();\n assert(!vector_1.eq(vector_2));\n }\n\n #[test]\n fn lexicographic_ordering_for_vectors() {\n assert(\n [2_u32].as_vector().cmp([1_u32, 1_u32, 1_u32].as_vector())\n == super::Ordering::greater(),\n );\n assert(\n [1_u32, 2_u32].as_vector().cmp([1_u32, 2_u32, 3_u32].as_vector())\n == super::Ordering::less(),\n );\n }\n}\n"
|
|
4894
|
+
"source": "use crate::meta::ctstring::AsCtString;\nuse crate::meta::derive_via;\n\n/// Compare two values for equality\n#[derive_via(derive_eq)]\n// docs:start:eq-trait\npub trait Eq {\n fn eq(self, other: Self) -> bool;\n}\n// docs:end:eq-trait\n\n// docs:start:derive_eq\ncomptime fn derive_eq(s: TypeDefinition) -> Quoted {\n let signature = quote { fn eq(_self: Self, _other: Self) -> bool };\n let for_each_field = |name| quote { (_self.$name == _other.$name) };\n let body = |fields| {\n if s.fields_as_written().len() == 0 {\n quote { true }\n } else {\n fields\n }\n };\n crate::meta::make_trait_impl(\n s,\n quote { $crate::cmp::Eq },\n signature,\n for_each_field,\n quote { & },\n body,\n )\n}\n// docs:end:derive_eq\n\nimpl Eq for Field {\n fn eq(self, other: Field) -> bool {\n self == other\n }\n}\n\nimpl Eq for u128 {\n fn eq(self, other: u128) -> bool {\n self == other\n }\n}\nimpl Eq for u64 {\n fn eq(self, other: u64) -> bool {\n self == other\n }\n}\nimpl Eq for u32 {\n fn eq(self, other: u32) -> bool {\n self == other\n }\n}\nimpl Eq for u16 {\n fn eq(self, other: u16) -> bool {\n self == other\n }\n}\nimpl Eq for u8 {\n fn eq(self, other: u8) -> bool {\n self == other\n }\n}\nimpl Eq for i8 {\n fn eq(self, other: i8) -> bool {\n self == other\n }\n}\nimpl Eq for i16 {\n fn eq(self, other: i16) -> bool {\n self == other\n }\n}\nimpl Eq for i32 {\n fn eq(self, other: i32) -> bool {\n self == other\n }\n}\nimpl Eq for i64 {\n fn eq(self, other: i64) -> bool {\n self == other\n }\n}\n\nimpl Eq for () {\n fn eq(_self: Self, _other: ()) -> bool {\n true\n }\n}\nimpl Eq for bool {\n fn eq(self, other: bool) -> bool {\n self == other\n }\n}\n\nimpl<T, let N: u32> Eq for [T; N]\nwhere\n T: Eq,\n{\n fn eq(self, other: [T; N]) -> bool {\n let mut result = true;\n for i in 0..self.len() {\n result &= self[i].eq(other[i]);\n }\n result\n }\n}\n\nimpl<T> Eq for [T]\nwhere\n T: Eq,\n{\n fn eq(self, other: [T]) -> bool {\n let mut result = self.len() == other.len();\n if result {\n for i in 0..self.len() {\n result &= self[i].eq(other[i]);\n }\n }\n result\n }\n}\n\nimpl<let N: u32> Eq for str<N> {\n fn eq(self, other: str<N>) -> bool {\n let self_bytes = self.as_bytes();\n let other_bytes = other.as_bytes();\n self_bytes == other_bytes\n }\n}\n\ncomptime fn make_tuple_eq_body(n: u32) -> Quoted {\n let mut body = f\"self.0.eq(other.0)\".as_ctstring();\n for i in 1u32..n {\n body = body.append_fmtstr(f\" & self.{i}.eq(other.{i})\");\n }\n f\"{body}\".quoted_contents()\n}\n\nimpl<A: Eq, B: Eq> Eq for (A, B) {\n fn eq(self, other: (A, B)) -> bool {\n make_tuple_eq_body!(2u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq> Eq for (A, B, C) {\n fn eq(self, other: (A, B, C)) -> bool {\n make_tuple_eq_body!(3u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq> Eq for (A, B, C, D) {\n fn eq(self, other: (A, B, C, D)) -> bool {\n make_tuple_eq_body!(4u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq> Eq for (A, B, C, D, E) {\n fn eq(self, other: (A, B, C, D, E)) -> bool {\n make_tuple_eq_body!(5u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq> Eq for (A, B, C, D, E, F) {\n fn eq(self, other: (A, B, C, D, E, F)) -> bool {\n make_tuple_eq_body!(6u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq> Eq for (A, B, C, D, E, F, G) {\n fn eq(self, other: (A, B, C, D, E, F, G)) -> bool {\n make_tuple_eq_body!(7u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq> Eq for (A, B, C, D, E, F, G, H) {\n fn eq(self, other: (A, B, C, D, E, F, G, H)) -> bool {\n make_tuple_eq_body!(8u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq> Eq for (A, B, C, D, E, F, G, H, I) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I)) -> bool {\n make_tuple_eq_body!(9u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq> Eq for (A, B, C, D, E, F, G, H, I, J) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I, J)) -> bool {\n make_tuple_eq_body!(10u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq, K: Eq> Eq for (A, B, C, D, E, F, G, H, I, J, K) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I, J, K)) -> bool {\n make_tuple_eq_body!(11u32)\n }\n}\n\nimpl<A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq, K: Eq, L: Eq> Eq for (A, B, C, D, E, F, G, H, I, J, K, L) {\n fn eq(self, other: (A, B, C, D, E, F, G, H, I, J, K, L)) -> bool {\n make_tuple_eq_body!(12u32)\n }\n}\n\nimpl Eq for Ordering {\n fn eq(self, other: Ordering) -> bool {\n self.result == other.result\n }\n}\n\n// Noir doesn't have enums yet so we emulate (Lt | Eq | Gt) with a struct\n// that has 3 public functions for constructing the struct.\n/// A value with three states: `Ordering::less()`, `Ordering::equal()` or `Ordering::greater()`.\n/// Most often used to encode the result of a comparison operation.\npub struct Ordering {\n result: Field,\n}\n\nimpl Ordering {\n // Implementation note: 0, 1, and 2 for Lt, Eq, and Gt are built\n // into the compiler, do not change these without also updating\n // the compiler itself!\n pub fn less() -> Ordering {\n Ordering { result: 0 }\n }\n\n pub fn equal() -> Ordering {\n Ordering { result: 1 }\n }\n\n pub fn greater() -> Ordering {\n Ordering { result: 2 }\n }\n}\n\n/// Compare one object to another, returning whether it is less-than, equal-to,\n/// or greater-than the other object.\n#[derive_via(derive_ord)]\n// docs:start:ord-trait\npub trait Ord {\n fn cmp(self, other: Self) -> Ordering;\n}\n// docs:end:ord-trait\n\n// docs:start:derive_ord\ncomptime fn derive_ord(s: TypeDefinition) -> Quoted {\n let name = quote { $crate::cmp::Ord };\n let signature = quote { fn cmp(_self: Self, _other: Self) -> $crate::cmp::Ordering };\n let for_each_field = |name| quote {\n if result == $crate::cmp::Ordering::equal() {\n result = _self.$name.cmp(_other.$name);\n }\n };\n let body = |fields| quote {\n let mut result = $crate::cmp::Ordering::equal();\n $fields\n result\n };\n crate::meta::make_trait_impl(s, name, signature, for_each_field, quote {}, body)\n}\n// docs:end:derive_ord\n\n// Note: Field deliberately does not implement Ord\n\nimpl Ord for u128 {\n fn cmp(self, other: u128) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\nimpl Ord for u64 {\n fn cmp(self, other: u64) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u32 {\n fn cmp(self, other: u32) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u16 {\n fn cmp(self, other: u16) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for u8 {\n fn cmp(self, other: u8) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i8 {\n fn cmp(self, other: i8) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i16 {\n fn cmp(self, other: i16) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i32 {\n fn cmp(self, other: i32) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for i64 {\n fn cmp(self, other: i64) -> Ordering {\n if self < other {\n Ordering::less()\n } else if self > other {\n Ordering::greater()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl Ord for () {\n fn cmp(_self: Self, _other: ()) -> Ordering {\n Ordering::equal()\n }\n}\n\nimpl Ord for bool {\n fn cmp(self, other: bool) -> Ordering {\n if self {\n if other {\n Ordering::equal()\n } else {\n Ordering::greater()\n }\n } else if other {\n Ordering::less()\n } else {\n Ordering::equal()\n }\n }\n}\n\nimpl<T, let N: u32> Ord for [T; N]\nwhere\n T: Ord,\n{\n // The first non-equal element of both arrays determines\n // the ordering for the whole array.\n fn cmp(self, other: [T; N]) -> Ordering {\n let mut result = Ordering::equal();\n for i in 0..self.len() {\n if result == Ordering::equal() {\n result = self[i].cmp(other[i]);\n }\n }\n result\n }\n}\n\nimpl<T> Ord for [T]\nwhere\n T: Ord,\n{\n // The first non-equal element of both arrays determines\n // the ordering for the whole array.\n fn cmp(self, other: [T]) -> Ordering {\n let self_len = self.len();\n let other_len = other.len();\n let min_len = if self_len < other_len {\n self_len\n } else {\n other_len\n };\n\n let mut result = Ordering::equal();\n for i in 0..min_len {\n if result == Ordering::equal() {\n result = self[i].cmp(other[i]);\n }\n }\n\n if result != Ordering::equal() {\n result\n } else {\n self_len.cmp(other_len)\n }\n }\n}\n\ncomptime fn make_tuple_ord_body(n: u32) -> Quoted {\n let last = n - 1u32;\n let mut body = if last == 1 {\n f\"let result = self.0.cmp(other.0);\".as_ctstring()\n } else {\n f\"let mut result = self.0.cmp(other.0);\".as_ctstring()\n };\n for i in 1u32..last {\n body = body.append_fmtstr(\n f\" if result == Ordering::equal() {{ result = self.{i}.cmp(other.{i}); }}\",\n );\n }\n body = body.append_fmtstr(\n f\" if result != Ordering::equal() {{ result }} else {{ self.{last}.cmp(other.{last}) }}\",\n );\n f\"{body}\".quoted_contents()\n}\n\nimpl<A: Ord, B: Ord> Ord for (A, B) {\n fn cmp(self, other: (A, B)) -> Ordering {\n make_tuple_ord_body!(2u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord> Ord for (A, B, C) {\n fn cmp(self, other: (A, B, C)) -> Ordering {\n make_tuple_ord_body!(3u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord> Ord for (A, B, C, D) {\n fn cmp(self, other: (A, B, C, D)) -> Ordering {\n make_tuple_ord_body!(4u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord> Ord for (A, B, C, D, E) {\n fn cmp(self, other: (A, B, C, D, E)) -> Ordering {\n make_tuple_ord_body!(5u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord> Ord for (A, B, C, D, E, F) {\n fn cmp(self, other: (A, B, C, D, E, F)) -> Ordering {\n make_tuple_ord_body!(6u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord> Ord for (A, B, C, D, E, F, G) {\n fn cmp(self, other: (A, B, C, D, E, F, G)) -> Ordering {\n make_tuple_ord_body!(7u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord> Ord for (A, B, C, D, E, F, G, H) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H)) -> Ordering {\n make_tuple_ord_body!(8u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord> Ord for (A, B, C, D, E, F, G, H, I) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I)) -> Ordering {\n make_tuple_ord_body!(9u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord, J: Ord> Ord for (A, B, C, D, E, F, G, H, I, J) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I, J)) -> Ordering {\n make_tuple_ord_body!(10u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord, J: Ord, K: Ord> Ord for (A, B, C, D, E, F, G, H, I, J, K) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I, J, K)) -> Ordering {\n make_tuple_ord_body!(11u32)\n }\n}\n\nimpl<A: Ord, B: Ord, C: Ord, D: Ord, E: Ord, F: Ord, G: Ord, H: Ord, I: Ord, J: Ord, K: Ord, L: Ord> Ord for (A, B, C, D, E, F, G, H, I, J, K, L) {\n fn cmp(self, other: (A, B, C, D, E, F, G, H, I, J, K, L)) -> Ordering {\n make_tuple_ord_body!(12u32)\n }\n}\n\n/// Compares and returns the maximum of two values.\n///\n/// Returns the second argument if the comparison determines them to be equal.\n///\n/// # Examples\n///\n/// ```\n/// use std::cmp;\n///\n/// assert_eq(cmp::max(1, 2), 2);\n/// assert_eq(cmp::max(2, 2), 2);\n/// ```\npub fn max<T>(v1: T, v2: T) -> T\nwhere\n T: Ord,\n{\n if v1 > v2 {\n v1\n } else {\n v2\n }\n}\n\n/// Compares and returns the minimum of two values.\n///\n/// Returns the first argument if the comparison determines them to be equal.\n///\n/// # Examples\n///\n/// ```\n/// use std::cmp;\n///\n/// assert_eq(cmp::min(1, 2), 1);\n/// assert_eq(cmp::min(2, 2), 2);\n/// ```\npub fn min<T>(v1: T, v2: T) -> T\nwhere\n T: Ord,\n{\n if v1 > v2 {\n v2\n } else {\n v1\n }\n}\n\nmod cmp_tests {\n use super::{Eq, max, min, Ord};\n\n #[test]\n fn sanity_check_min() {\n assert_eq(min(0_u64, 1), 0);\n assert_eq(min(0_u64, 0), 0);\n assert_eq(min(1_u64, 1), 1);\n assert_eq(min(255_u8, 0), 0);\n }\n\n #[test]\n fn sanity_check_max() {\n assert_eq(max(0_u64, 1), 1);\n assert_eq(max(0_u64, 0), 0);\n assert_eq(max(1_u64, 1), 1);\n assert_eq(max(255_u8, 0), 255);\n }\n\n #[test]\n fn correctly_handles_unequal_length_vectors() {\n let vector_1 = [0, 1, 2, 3].as_vector();\n let vector_2 = [0, 1, 2].as_vector();\n assert(!vector_1.eq(vector_2));\n }\n\n #[test]\n fn lexicographic_ordering_for_vectors() {\n assert(\n [2_u32].as_vector().cmp([1_u32, 1_u32, 1_u32].as_vector())\n == super::Ordering::greater(),\n );\n assert(\n [1_u32, 2_u32].as_vector().cmp([1_u32, 2_u32, 3_u32].as_vector())\n == super::Ordering::less(),\n );\n }\n}\n"
|
|
4993
4895
|
},
|
|
4994
4896
|
"50": {
|
|
4995
4897
|
"function_locations": [
|
|
@@ -5003,27 +4905,27 @@
|
|
|
5003
4905
|
},
|
|
5004
4906
|
{
|
|
5005
4907
|
"name": "ContractInstanceRegistry::update",
|
|
5006
|
-
"start":
|
|
4908
|
+
"start": 8513
|
|
5007
4909
|
},
|
|
5008
4910
|
{
|
|
5009
4911
|
"name": "ContractInstanceRegistry::set_update_delay",
|
|
5010
|
-
"start":
|
|
4912
|
+
"start": 10807
|
|
5011
4913
|
},
|
|
5012
4914
|
{
|
|
5013
4915
|
"name": "ContractInstanceRegistry::get_update_delay",
|
|
5014
|
-
"start":
|
|
4916
|
+
"start": 12110
|
|
5015
4917
|
},
|
|
5016
4918
|
{
|
|
5017
4919
|
"name": "ContractInstanceRegistry::public_dispatch",
|
|
5018
|
-
"start":
|
|
4920
|
+
"start": 13270
|
|
5019
4921
|
},
|
|
5020
4922
|
{
|
|
5021
4923
|
"name": "ContractInstanceRegistry::Storage<Context>::init",
|
|
5022
|
-
"start":
|
|
4924
|
+
"start": 14435
|
|
5023
4925
|
}
|
|
5024
4926
|
],
|
|
5025
4927
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/contract_instance_registry_contract/src/main.nr",
|
|
5026
|
-
"source": "/// Protocol contract responsible for deploying contract instances and managing contract upgrades.\n///\n/// In Aztec, contracts are split into *classes* (code, registered via ContractClassRegistry) and *instances*\n/// (deployments of a class at a unique address). This contract handles contract instance publishing and contract\n/// updates (updating instance to a new class).\npub contract ContractInstanceRegistry {\n use aztec::{\n context::{PrivateContext, PublicContext},\n hash::hash_args,\n nullifier::utils::compute_nullifier_existence_request,\n oracle::{avm, logging::debug_log_format, version::assert_compatible_oracle_version},\n protocol::{\n abis::function_selector::FunctionSelector,\n address::{AztecAddress, PartialAddress},\n constants::{\n CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS, CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE,\n CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE, DEFAULT_UPDATE_DELAY, MINIMUM_UPDATE_DELAY,\n },\n contract_class_id::ContractClassId,\n public_keys::PublicKeys,\n traits::{Deserialize, Serialize, ToField},\n utils::reader::Reader,\n },\n state_vars::{DelayedPublicMutable, Map, StateVariable},\n };\n\n #[abi(events)]\n struct ContractInstancePublished {\n CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE: Field,\n address: AztecAddress,\n version: u8,\n salt: Field,\n contract_class_id: ContractClassId,\n initialization_hash: Field,\n public_keys: PublicKeys,\n deployer: AztecAddress,\n }\n\n // Custom serialization is required because we don't want to waste one field for the `is_infinite` flag of public\n // key points (public key points will never be the infinity point).\n impl ContractInstancePublished {\n fn serialize_non_standard(self) -> [Field; 15] {\n [\n self.CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE,\n self.address.to_field(),\n self.version.to_field(),\n self.salt,\n self.contract_class_id.to_field(),\n self.initialization_hash,\n self.public_keys.npk_m.serialize()[0],\n self.public_keys.npk_m.serialize()[1],\n self.public_keys.ivpk_m.serialize()[0],\n self.public_keys.ivpk_m.serialize()[1],\n self.public_keys.ovpk_m.serialize()[0],\n self.public_keys.ovpk_m.serialize()[1],\n self.public_keys.tpk_m.serialize()[0],\n self.public_keys.tpk_m.serialize()[1],\n self.deployer.to_field(),\n ]\n }\n }\n\n #[abi(events)]\n #[derive(Serialize)]\n struct ContractInstanceUpdated {\n CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE: Field,\n address: AztecAddress,\n prev_contract_class_id: ContractClassId,\n new_contract_class_id: ContractClassId,\n timestamp_of_change: u64,\n }\n\n struct Storage<Context> {\n /// Map from contract instance address to a `DelayedPublicMutable` holding the updated contract class ID.\n updated_class_ids: Map<AztecAddress, DelayedPublicMutable<ContractClassId, DEFAULT_UPDATE_DELAY, Context>, Context>,\n }\n\n /// Publishes a new contract instance.\n ///\n /// The caller provides deployment parameters (salt, class_id, init_hash, public_keys, universal_deploy).\n /// The `universal_deploy` flag controls whether the deployer address is bound into the contract address:\n /// when true, deployer is zero (anyone can deploy the same instance); when false, deployer is the caller.\n ///\n /// This function:\n /// 1. Verifies the contract class is registered in ContractClassRegistry (nullifier existence check).\n /// 2. Validates public key points are on the Grumpkin curve (preventing AVM DoS via invalid points).\n /// 3. Computes the deterministic contract address from the deployment parameters.\n /// 4. Emits the address as a nullifier (proving publication preventing duplicate deployment)\n /// --> this address nullifier is then checked to exist by the AVM upon public function execution (if it doesn't\n /// exist AVM reverts)\n /// 5. Broadcasts a `ContractInstancePublished` event so nodes can reconstruct the instance.\n #[aztec::macros::internals_functions_generation::abi_attributes::abi_private]\n fn publish_for_public_execution(\n inputs: aztec::context::inputs::PrivateContextInputs,\n salt: Field,\n contract_class_id: ContractClassId,\n initialization_hash: Field,\n public_keys: PublicKeys,\n universal_deploy: bool,\n ) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs {\n // MACRO CODE START\n // Note: The macros initially inserted a phase check here, but since there is no phase change in this function\n // body, I have removed that check.\n assert_compatible_oracle_version();\n\n let serialized_params: [Field; 16] = [\n salt,\n contract_class_id.to_field(),\n initialization_hash,\n ]\n .concat(public_keys.serialize())\n .concat([universal_deploy.to_field()]);\n\n let args_hash: Field = hash_args(serialized_params);\n let mut context: PrivateContext = PrivateContext::new(inputs, args_hash);\n // MACRO CODE END\n\n // Verify the contract class is registered by checking for its nullifier at the ContractClassRegistry address.\n let nullifier_existence_request = compute_nullifier_existence_request(\n contract_class_id.to_field(),\n CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS,\n );\n context.assert_nullifier_exists(nullifier_existence_request);\n\n // For universal deployments, deployer is zero so the resulting address is the same regardless of who initiates\n // deployment.\n let deployer = if universal_deploy {\n AztecAddress::zero()\n } else {\n context.maybe_msg_sender().unwrap()\n };\n\n let partial_address =\n PartialAddress::compute(contract_class_id, salt, initialization_hash, deployer);\n\n // Validate public key points lie on the Grumpkin curve to prevent AVM DoS attacks.\n public_keys.validate_on_curve();\n\n let address = AztecAddress::compute(public_keys, partial_address);\n\n // Emit address as nullifier: prevents duplicate deployment and proves publication.\n // We use no domain separators because these are the only nullifiers this contract uses.\n context.push_nullifier(address.to_field());\n\n // Broadcast deployment event. Uses non-standard serialization (2 fields per point,\n // omitting is_infinite) for TypeScript SDK compatibility.\n let event = ContractInstancePublished {\n CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE,\n contract_class_id,\n address,\n public_keys,\n initialization_hash,\n salt,\n deployer,\n version: 1,\n };\n let payload = event.serialize_non_standard();\n debug_log_format(\"ContractInstancePublished: {}\", payload);\n // We pad the payload with [0] to match the length required by emit_private_log. Since the log is not\n // encrypted, padding with zero rather than a random value is acceptable (we don't care about privacy here).\n let padded_log = payload.concat([0]);\n let length = payload.len();\n context.emit_private_log(padded_log, length);\n\n // MACRO CODE START\n context.finish()\n // MACRO CODE END\n }\n\n /// Schedules an upgrade of the calling contract instance to a new contract class.\n ///\n /// The change is time-delayed via `DelayedPublicMutable` and only takes effect after the configured\n /// delay has elapsed. Only the contract instance itself can call this function (msg.sender == address).\n ///\n /// This function:\n /// 1. Verifies msg.sender is a deployed contract (its address nullifier exists).\n /// 2. Verifies the new class is registered in ContractClassRegistry.\n /// 3. Schedules the class ID change and emits a `ContractInstanceUpdated` event.\n #[aztec::macros::internals_functions_generation::abi_attributes::abi_public]\n unconstrained fn update(new_contract_class_id: ContractClassId) {\n // MACRO CODE START\n let context: PublicContext = PublicContext::new(\n || -> Field {\n let serialized_args: [Field; 1] =\n avm::calldata_copy(1, <ContractClassId as Serialize>::N);\n hash_args(serialized_args)\n },\n );\n let storage: Storage<PublicContext> = Storage::init(context);\n // MACRO CODE END\n\n let address = context.maybe_msg_sender().unwrap();\n\n // Safety: we're using the nullifier's existence as a guarantee of the availability of the contract's\n // information through publishing, which is safe - we just need this information to be _eventually_ available.\n assert(\n context.nullifier_exists_unsafe(address.to_field(), context.this_address()),\n \"msg.sender is not deployed\",\n );\n\n // Safety: we're using the nullifier's existence as a guarantee of the availability of the new contract class'\n // information through registration, which is safe - we just need this information to be _eventually_ available.\n assert(\n context.nullifier_exists_unsafe(\n new_contract_class_id.to_field(),\n CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS,\n ),\n \"New contract class is not registered\",\n );\n\n let scheduled_value_update = storage\n .updated_class_ids\n .at(address)\n .schedule_and_get_value_change(new_contract_class_id);\n let (prev_contract_class_id, timestamp_of_change) = scheduled_value_update.get_previous();\n\n let event = ContractInstanceUpdated {\n CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE,\n address,\n prev_contract_class_id,\n new_contract_class_id,\n timestamp_of_change,\n };\n context.emit_public_log(event);\n }\n\n /// Schedules a change to the upgrade delay for the calling contract instance. The delay change is\n /// itself delayed (preventing atomically reducing delay + scheduling an instant upgrade). The new\n /// delay must be at least `MINIMUM_UPDATE_DELAY`.\n #[aztec::macros::internals_functions_generation::abi_attributes::abi_public]\n unconstrained fn set_update_delay(new_update_delay: u64) {\n // MACRO CODE START\n let context: PublicContext = PublicContext::new(\n || -> Field {\n let serialized_args: [Field; 1] = avm::calldata_copy(1, <u64 as Serialize>::N);\n hash_args(serialized_args)\n },\n );\n let storage: Storage<PublicContext> = Storage::init(context);\n // MACRO CODE END\n\n let msg_sender = context.maybe_msg_sender().unwrap();\n\n // Safety: we're using the nullifier's existence as a guarantee of the availability of the contract's\n // information through publishing, which is safe - we just need this information to be _eventually_ available.\n assert(\n context.nullifier_exists_unsafe(msg_sender.to_field(), context.this_address()),\n \"msg.sender is not deployed\",\n );\n\n assert(new_update_delay >= MINIMUM_UPDATE_DELAY, \"New update delay is too low\");\n\n storage.updated_class_ids.at(msg_sender).schedule_delay_change(new_update_delay);\n }\n\n /// Returns the current update delay for the calling contract instance.\n #[aztec::macros::internals_functions_generation::abi_attributes::abi_public]\n #[aztec::macros::internals_functions_generation::abi_attributes::abi_view]\n unconstrained fn get_update_delay() -> pub u64 {\n // MACRO CODE START\n let context: PublicContext = PublicContext::new(\n || -> Field {\n let serialized_args: [Field; 0] = avm::calldata_copy(1, 0);\n hash_args(serialized_args)\n },\n );\n let storage: Storage<PublicContext> = Storage::init(context);\n assert(context.is_static_call(), \"Function get_update_delay can only be called statically\");\n // MACRO CODE END\n\n storage.updated_class_ids.at(avm::sender()).get_current_delay()\n }\n\n // THE REST OF THE CODE IN THIS CONTRACT WAS ORIGINALLY INJECTED BY THE #[aztec] MACRO.\n\n global UPDATE_SELECTOR: Field =\n comptime { FunctionSelector::from_signature(\"update((Field))\").to_field() };\n global SET_UPDATE_DELAY_SELECTOR: Field =\n comptime { FunctionSelector::from_signature(\"set_update_delay(u64)\").to_field() };\n global GET_UPDATE_DELAY_SELECTOR: Field =\n comptime { FunctionSelector::from_signature(\"get_update_delay()\").to_field() };\n\n #[aztec::macros::internals_functions_generation::abi_attributes::abi_public]\n pub unconstrained fn public_dispatch(selector: Field) {\n if selector == UPDATE_SELECTOR {\n let input_calldata: [Field; 1] =\n avm::calldata_copy(1, <ContractClassId as Serialize>::N);\n let mut reader: Reader<1> = Reader::new(input_calldata);\n let arg0: ContractClassId =\n <ContractClassId as Deserialize>::stream_deserialize(&mut reader);\n update(arg0);\n avm::avm_return([].as_vector());\n };\n if selector == SET_UPDATE_DELAY_SELECTOR {\n let input_calldata: [Field; 1] = avm::calldata_copy(1, <u64 as Serialize>::N);\n let mut reader: Reader<1> = Reader::new(input_calldata);\n let arg0: u64 = <u64 as Deserialize>::stream_deserialize(&mut reader);\n set_update_delay(arg0);\n avm::avm_return([].as_vector());\n };\n if selector == GET_UPDATE_DELAY_SELECTOR {\n let return_value: [Field; 1] = <u64 as Serialize>::serialize(get_update_delay());\n avm::avm_return(return_value.as_vector());\n };\n panic(f\"Unknown selector {selector}\")\n }\n\n impl<Context> Storage<Context> {\n fn init(context: Context) -> Self {\n Self {\n updated_class_ids: <Map<AztecAddress, DelayedPublicMutable<ContractClassId, DEFAULT_UPDATE_DELAY, Context>, Context> as StateVariable<1, Context>>::new(\n context,\n 1,\n ),\n }\n }\n }\n\n pub struct publish_for_public_execution_parameters {\n pub _salt: Field,\n pub _contract_class_id: ContractClassId,\n pub _initialization_hash: Field,\n pub _public_keys: PublicKeys,\n pub _universal_deploy: bool,\n }\n\n pub struct update_parameters {\n pub _new_contract_class_id: ContractClassId,\n }\n\n pub struct set_update_delay_parameters {\n pub _new_update_delay: u64,\n }\n\n pub struct get_update_delay_parameters {}\n\n #[abi(functions)]\n pub struct publish_for_public_execution_abi {\n parameters: publish_for_public_execution_parameters,\n }\n\n #[abi(functions)]\n pub struct update_abi {\n parameters: update_parameters,\n }\n\n #[abi(functions)]\n pub struct set_update_delay_abi {\n parameters: set_update_delay_parameters,\n }\n\n #[abi(functions)]\n pub struct get_update_delay_abi {\n parameters: get_update_delay_parameters,\n return_type: u64,\n }\n}\n"
|
|
4928
|
+
"source": "/// Protocol contract responsible for deploying contract instances and managing contract upgrades.\n///\n/// In Aztec, contracts are split into *classes* (code, registered via ContractClassRegistry) and *instances*\n/// (deployments of a class at a unique address). This contract handles contract instance publishing and contract\n/// updates (updating instance to a new class).\npub contract ContractInstanceRegistry {\n use aztec::{\n context::{PrivateContext, PublicContext},\n hash::hash_args,\n nullifier::utils::compute_nullifier_existence_request,\n oracle::{avm, logging::debug_log_format, version::assert_compatible_oracle_version},\n protocol::{\n abis::function_selector::FunctionSelector,\n address::{AztecAddress, PartialAddress},\n constants::{\n CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS, CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE,\n CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE, DEFAULT_UPDATE_DELAY, MINIMUM_UPDATE_DELAY,\n },\n contract_class_id::ContractClassId,\n public_keys::PublicKeys,\n traits::{Deserialize, Serialize, ToField},\n utils::reader::Reader,\n },\n state_vars::{DelayedPublicMutable, Map, StateVariable},\n };\n\n #[abi(events)]\n struct ContractInstancePublished {\n CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE: Field,\n address: AztecAddress,\n version: u8,\n salt: Field,\n contract_class_id: ContractClassId,\n initialization_hash: Field,\n public_keys: PublicKeys,\n deployer: AztecAddress,\n }\n\n // Custom serialization is required because we don't want to waste one field for the `is_infinite` flag of public\n // key points (public key points will never be the infinity point).\n impl ContractInstancePublished {\n fn serialize_non_standard(self) -> [Field; 15] {\n [\n self.CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE,\n self.address.to_field(),\n self.version.to_field(),\n self.salt,\n self.contract_class_id.to_field(),\n self.initialization_hash,\n self.public_keys.npk_m.serialize()[0],\n self.public_keys.npk_m.serialize()[1],\n self.public_keys.ivpk_m.serialize()[0],\n self.public_keys.ivpk_m.serialize()[1],\n self.public_keys.ovpk_m.serialize()[0],\n self.public_keys.ovpk_m.serialize()[1],\n self.public_keys.tpk_m.serialize()[0],\n self.public_keys.tpk_m.serialize()[1],\n self.deployer.to_field(),\n ]\n }\n }\n\n #[abi(events)]\n #[derive(Serialize)]\n struct ContractInstanceUpdated {\n CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE: Field,\n address: AztecAddress,\n prev_contract_class_id: ContractClassId,\n new_contract_class_id: ContractClassId,\n timestamp_of_change: u64,\n }\n\n struct Storage<Context> {\n /// Map from contract instance address to a `DelayedPublicMutable` holding the updated contract class ID.\n updated_class_ids: Map<AztecAddress, DelayedPublicMutable<ContractClassId, DEFAULT_UPDATE_DELAY, Context>, Context>,\n }\n\n /// Publishes a new contract instance.\n ///\n /// The caller provides deployment parameters (salt, class_id, init_hash, public_keys, universal_deploy).\n /// The `universal_deploy` flag controls whether the deployer address is bound into the contract address:\n /// when true, deployer is zero (anyone can deploy the same instance); when false, deployer is the caller.\n ///\n /// This function:\n /// 1. Verifies the contract class is registered in ContractClassRegistry (nullifier existence check).\n /// 2. Validates public key points are on the Grumpkin curve (preventing AVM DoS via invalid points).\n /// 3. Computes the deterministic contract address from the deployment parameters.\n /// 4. Emits the address as a nullifier (proving publication preventing duplicate deployment)\n /// --> this address nullifier is then checked to exist by the AVM upon public function execution (if it doesn't\n /// exist AVM reverts)\n /// 5. Broadcasts a `ContractInstancePublished` event so nodes can reconstruct the instance.\n #[aztec::macros::internals_functions_generation::abi_attributes::abi_private]\n fn publish_for_public_execution(\n inputs: aztec::context::inputs::PrivateContextInputs,\n salt: Field,\n contract_class_id: ContractClassId,\n initialization_hash: Field,\n public_keys: PublicKeys,\n universal_deploy: bool,\n ) -> return_data aztec::protocol::abis::private_circuit_public_inputs::PrivateCircuitPublicInputs {\n // MACRO CODE START\n // Note: The macros initially inserted a phase check here, but since there is no phase change in this function\n // body, I have removed that check.\n assert_compatible_oracle_version();\n\n let serialized_params: [Field; 16] = [\n salt,\n contract_class_id.to_field(),\n initialization_hash,\n ]\n .concat(public_keys.serialize())\n .concat([universal_deploy.to_field()]);\n\n let args_hash: Field = hash_args(serialized_params);\n let mut context: PrivateContext = PrivateContext::new(inputs, args_hash);\n // MACRO CODE END\n\n // Verify the contract class is registered by checking for its nullifier at the ContractClassRegistry address.\n let nullifier_existence_request = compute_nullifier_existence_request(\n contract_class_id.to_field(),\n CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS,\n );\n context.assert_nullifier_exists(nullifier_existence_request);\n\n // For universal deployments, deployer is zero so the resulting address is the same regardless of who initiates\n // deployment.\n let deployer = if universal_deploy {\n AztecAddress::zero()\n } else {\n context.maybe_msg_sender().unwrap()\n };\n\n let partial_address =\n PartialAddress::compute(contract_class_id, salt, initialization_hash, deployer);\n\n // Validate public key points lie on the Grumpkin curve and are non-0 to prevent AVM DoS attacks.\n public_keys.validate_on_curve();\n public_keys.validate_non_infinity();\n\n let address = AztecAddress::compute(public_keys, partial_address);\n\n // Emit address as nullifier: prevents duplicate deployment and proves publication.\n // We use no domain separators because these are the only nullifiers this contract uses.\n context.push_nullifier(address.to_field());\n\n // Broadcast deployment event. Uses non-standard serialization (2 fields per point,\n // omitting is_infinite) for TypeScript SDK compatibility.\n let event = ContractInstancePublished {\n CONTRACT_INSTANCE_PUBLISHED_MAGIC_VALUE,\n contract_class_id,\n address,\n public_keys,\n initialization_hash,\n salt,\n deployer,\n version: 1,\n };\n let payload = event.serialize_non_standard();\n debug_log_format(\"ContractInstancePublished: {}\", payload);\n // We pad the payload with [0] to match the length required by emit_private_log. Since the log is not\n // encrypted, padding with zero rather than a random value is acceptable (we don't care about privacy here).\n let padded_log = payload.concat([0]);\n let length = payload.len();\n context.emit_private_log(padded_log, length);\n\n // MACRO CODE START\n context.finish()\n // MACRO CODE END\n }\n\n /// Schedules an upgrade of the calling contract instance to a new contract class.\n ///\n /// The change is time-delayed via `DelayedPublicMutable` and only takes effect after the configured\n /// delay has elapsed. Only the contract instance itself can call this function (msg.sender == address).\n ///\n /// This function:\n /// 1. Verifies msg.sender is a deployed contract (its address nullifier exists).\n /// 2. Verifies the new class is registered in ContractClassRegistry.\n /// 3. Schedules the class ID change and emits a `ContractInstanceUpdated` event.\n #[aztec::macros::internals_functions_generation::abi_attributes::abi_public]\n unconstrained fn update(new_contract_class_id: ContractClassId) {\n // MACRO CODE START\n let context: PublicContext = PublicContext::new(\n || -> Field {\n let serialized_args: [Field; 1] =\n avm::calldata_copy(1, <ContractClassId as Serialize>::N);\n hash_args(serialized_args)\n },\n );\n let storage: Storage<PublicContext> = Storage::init(context);\n // MACRO CODE END\n\n let address = context.maybe_msg_sender().unwrap();\n\n // Safety: we're using the nullifier's existence as a guarantee of the availability of the contract's\n // information through publishing, which is safe - we just need this information to be _eventually_ available.\n assert(\n context.nullifier_exists_unsafe(address.to_field(), context.this_address()),\n \"msg.sender is not deployed\",\n );\n\n // Safety: we're using the nullifier's existence as a guarantee of the availability of the new contract class'\n // information through registration, which is safe - we just need this information to be _eventually_ available.\n assert(\n context.nullifier_exists_unsafe(\n new_contract_class_id.to_field(),\n CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS,\n ),\n \"New contract class is not registered\",\n );\n\n let scheduled_value_update = storage\n .updated_class_ids\n .at(address)\n .schedule_and_get_value_change(new_contract_class_id);\n let (prev_contract_class_id, timestamp_of_change) = scheduled_value_update.get_previous();\n\n let event = ContractInstanceUpdated {\n CONTRACT_INSTANCE_UPDATED_MAGIC_VALUE,\n address,\n prev_contract_class_id,\n new_contract_class_id,\n timestamp_of_change,\n };\n context.emit_public_log(event);\n }\n\n /// Schedules a change to the upgrade delay for the calling contract instance. The delay change is\n /// itself delayed (preventing atomically reducing delay + scheduling an instant upgrade). The new\n /// delay must be at least `MINIMUM_UPDATE_DELAY`.\n #[aztec::macros::internals_functions_generation::abi_attributes::abi_public]\n unconstrained fn set_update_delay(new_update_delay: u64) {\n // MACRO CODE START\n let context: PublicContext = PublicContext::new(\n || -> Field {\n let serialized_args: [Field; 1] = avm::calldata_copy(1, <u64 as Serialize>::N);\n hash_args(serialized_args)\n },\n );\n let storage: Storage<PublicContext> = Storage::init(context);\n // MACRO CODE END\n\n let msg_sender = context.maybe_msg_sender().unwrap();\n\n // Safety: we're using the nullifier's existence as a guarantee of the availability of the contract's\n // information through publishing, which is safe - we just need this information to be _eventually_ available.\n assert(\n context.nullifier_exists_unsafe(msg_sender.to_field(), context.this_address()),\n \"msg.sender is not deployed\",\n );\n\n assert(new_update_delay >= MINIMUM_UPDATE_DELAY, \"New update delay is too low\");\n\n storage.updated_class_ids.at(msg_sender).schedule_delay_change(new_update_delay);\n }\n\n /// Returns the current update delay for the calling contract instance.\n #[aztec::macros::internals_functions_generation::abi_attributes::abi_public]\n #[aztec::macros::internals_functions_generation::abi_attributes::abi_view]\n unconstrained fn get_update_delay() -> pub u64 {\n // MACRO CODE START\n let context: PublicContext = PublicContext::new(\n || -> Field {\n let serialized_args: [Field; 0] = avm::calldata_copy(1, 0);\n hash_args(serialized_args)\n },\n );\n let storage: Storage<PublicContext> = Storage::init(context);\n assert(context.is_static_call(), \"Function get_update_delay can only be called statically\");\n // MACRO CODE END\n\n storage.updated_class_ids.at(avm::sender()).get_current_delay()\n }\n\n // THE REST OF THE CODE IN THIS CONTRACT WAS ORIGINALLY INJECTED BY THE #[aztec] MACRO.\n\n global UPDATE_SELECTOR: Field =\n comptime { FunctionSelector::from_signature(\"update((Field))\").to_field() };\n global SET_UPDATE_DELAY_SELECTOR: Field =\n comptime { FunctionSelector::from_signature(\"set_update_delay(u64)\").to_field() };\n global GET_UPDATE_DELAY_SELECTOR: Field =\n comptime { FunctionSelector::from_signature(\"get_update_delay()\").to_field() };\n\n #[aztec::macros::internals_functions_generation::abi_attributes::abi_public]\n pub unconstrained fn public_dispatch(selector: Field) {\n if selector == UPDATE_SELECTOR {\n let input_calldata: [Field; 1] =\n avm::calldata_copy(1, <ContractClassId as Serialize>::N);\n let mut reader: Reader<1> = Reader::new(input_calldata);\n let arg0: ContractClassId =\n <ContractClassId as Deserialize>::stream_deserialize(&mut reader);\n update(arg0);\n avm::avm_return([].as_vector());\n };\n if selector == SET_UPDATE_DELAY_SELECTOR {\n let input_calldata: [Field; 1] = avm::calldata_copy(1, <u64 as Serialize>::N);\n let mut reader: Reader<1> = Reader::new(input_calldata);\n let arg0: u64 = <u64 as Deserialize>::stream_deserialize(&mut reader);\n set_update_delay(arg0);\n avm::avm_return([].as_vector());\n };\n if selector == GET_UPDATE_DELAY_SELECTOR {\n let return_value: [Field; 1] = <u64 as Serialize>::serialize(get_update_delay());\n avm::avm_return(return_value.as_vector());\n };\n panic(f\"Unknown selector {selector}\")\n }\n\n impl<Context> Storage<Context> {\n fn init(context: Context) -> Self {\n Self {\n updated_class_ids: <Map<AztecAddress, DelayedPublicMutable<ContractClassId, DEFAULT_UPDATE_DELAY, Context>, Context> as StateVariable<1, Context>>::new(\n context,\n 1,\n ),\n }\n }\n }\n\n pub struct publish_for_public_execution_parameters {\n pub _salt: Field,\n pub _contract_class_id: ContractClassId,\n pub _initialization_hash: Field,\n pub _public_keys: PublicKeys,\n pub _universal_deploy: bool,\n }\n\n pub struct update_parameters {\n pub _new_contract_class_id: ContractClassId,\n }\n\n pub struct set_update_delay_parameters {\n pub _new_update_delay: u64,\n }\n\n pub struct get_update_delay_parameters {}\n\n #[abi(functions)]\n pub struct publish_for_public_execution_abi {\n parameters: publish_for_public_execution_parameters,\n }\n\n #[abi(functions)]\n pub struct update_abi {\n parameters: update_parameters,\n }\n\n #[abi(functions)]\n pub struct set_update_delay_abi {\n parameters: set_update_delay_parameters,\n }\n\n #[abi(functions)]\n pub struct get_update_delay_abi {\n parameters: get_update_delay_parameters,\n return_type: u64,\n }\n}\n"
|
|
5027
4929
|
},
|
|
5028
4930
|
"57": {
|
|
5029
4931
|
"function_locations": [
|
|
@@ -5147,115 +5049,115 @@
|
|
|
5147
5049
|
},
|
|
5148
5050
|
{
|
|
5149
5051
|
"name": "PublicContext::l1_to_l2_msg_exists",
|
|
5150
|
-
"start":
|
|
5052
|
+
"start": 1786
|
|
5151
5053
|
},
|
|
5152
5054
|
{
|
|
5153
5055
|
"name": "PublicContext::nullifier_exists_unsafe",
|
|
5154
|
-
"start":
|
|
5056
|
+
"start": 2226
|
|
5155
5057
|
},
|
|
5156
5058
|
{
|
|
5157
5059
|
"name": "PublicContext::consume_l1_to_l2_message",
|
|
5158
|
-
"start":
|
|
5060
|
+
"start": 2685
|
|
5159
5061
|
},
|
|
5160
5062
|
{
|
|
5161
5063
|
"name": "PublicContext::message_portal",
|
|
5162
|
-
"start":
|
|
5064
|
+
"start": 3571
|
|
5163
5065
|
},
|
|
5164
5066
|
{
|
|
5165
5067
|
"name": "PublicContext::call_public_function",
|
|
5166
|
-
"start":
|
|
5068
|
+
"start": 3996
|
|
5167
5069
|
},
|
|
5168
5070
|
{
|
|
5169
5071
|
"name": "PublicContext::static_call_public_function",
|
|
5170
|
-
"start":
|
|
5072
|
+
"start": 4896
|
|
5171
5073
|
},
|
|
5172
5074
|
{
|
|
5173
5075
|
"name": "PublicContext::push_note_hash",
|
|
5174
|
-
"start":
|
|
5076
|
+
"start": 5597
|
|
5175
5077
|
},
|
|
5176
5078
|
{
|
|
5177
5079
|
"name": "PublicContext::push_nullifier",
|
|
5178
|
-
"start":
|
|
5080
|
+
"start": 5831
|
|
5179
5081
|
},
|
|
5180
5082
|
{
|
|
5181
5083
|
"name": "PublicContext::this_address",
|
|
5182
|
-
"start":
|
|
5084
|
+
"start": 6077
|
|
5183
5085
|
},
|
|
5184
5086
|
{
|
|
5185
5087
|
"name": "PublicContext::maybe_msg_sender",
|
|
5186
|
-
"start":
|
|
5088
|
+
"start": 6342
|
|
5187
5089
|
},
|
|
5188
5090
|
{
|
|
5189
5091
|
"name": "PublicContext::selector",
|
|
5190
|
-
"start":
|
|
5092
|
+
"start": 6764
|
|
5191
5093
|
},
|
|
5192
5094
|
{
|
|
5193
5095
|
"name": "PublicContext::get_args_hash",
|
|
5194
|
-
"start":
|
|
5096
|
+
"start": 7197
|
|
5195
5097
|
},
|
|
5196
5098
|
{
|
|
5197
5099
|
"name": "PublicContext::transaction_fee",
|
|
5198
|
-
"start":
|
|
5100
|
+
"start": 7485
|
|
5199
5101
|
},
|
|
5200
5102
|
{
|
|
5201
5103
|
"name": "PublicContext::chain_id",
|
|
5202
|
-
"start":
|
|
5104
|
+
"start": 7716
|
|
5203
5105
|
},
|
|
5204
5106
|
{
|
|
5205
5107
|
"name": "PublicContext::version",
|
|
5206
|
-
"start":
|
|
5108
|
+
"start": 7924
|
|
5207
5109
|
},
|
|
5208
5110
|
{
|
|
5209
5111
|
"name": "PublicContext::block_number",
|
|
5210
|
-
"start":
|
|
5112
|
+
"start": 8138
|
|
5211
5113
|
},
|
|
5212
5114
|
{
|
|
5213
5115
|
"name": "PublicContext::timestamp",
|
|
5214
|
-
"start":
|
|
5116
|
+
"start": 8364
|
|
5215
5117
|
},
|
|
5216
5118
|
{
|
|
5217
5119
|
"name": "PublicContext::min_fee_per_l2_gas",
|
|
5218
|
-
"start":
|
|
5120
|
+
"start": 8589
|
|
5219
5121
|
},
|
|
5220
5122
|
{
|
|
5221
5123
|
"name": "PublicContext::min_fee_per_da_gas",
|
|
5222
|
-
"start":
|
|
5124
|
+
"start": 8823
|
|
5223
5125
|
},
|
|
5224
5126
|
{
|
|
5225
5127
|
"name": "PublicContext::l2_gas_left",
|
|
5226
|
-
"start":
|
|
5128
|
+
"start": 9053
|
|
5227
5129
|
},
|
|
5228
5130
|
{
|
|
5229
5131
|
"name": "PublicContext::da_gas_left",
|
|
5230
|
-
"start":
|
|
5132
|
+
"start": 9276
|
|
5231
5133
|
},
|
|
5232
5134
|
{
|
|
5233
5135
|
"name": "PublicContext::is_static_call",
|
|
5234
|
-
"start":
|
|
5136
|
+
"start": 9527
|
|
5235
5137
|
},
|
|
5236
5138
|
{
|
|
5237
5139
|
"name": "PublicContext::raw_storage_read",
|
|
5238
|
-
"start":
|
|
5140
|
+
"start": 9781
|
|
5239
5141
|
},
|
|
5240
5142
|
{
|
|
5241
5143
|
"name": "PublicContext::storage_read",
|
|
5242
|
-
"start":
|
|
5144
|
+
"start": 10216
|
|
5243
5145
|
},
|
|
5244
5146
|
{
|
|
5245
5147
|
"name": "PublicContext::raw_storage_write",
|
|
5246
|
-
"start":
|
|
5148
|
+
"start": 10426
|
|
5247
5149
|
},
|
|
5248
5150
|
{
|
|
5249
5151
|
"name": "PublicContext::storage_write",
|
|
5250
|
-
"start":
|
|
5152
|
+
"start": 10767
|
|
5251
5153
|
},
|
|
5252
5154
|
{
|
|
5253
5155
|
"name": "<impl Empty for PublicContext>::empty",
|
|
5254
|
-
"start":
|
|
5156
|
+
"start": 10892
|
|
5255
5157
|
}
|
|
5256
5158
|
],
|
|
5257
5159
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/aztec_sublib/src/context/public_context.nr",
|
|
5258
|
-
"source": "use crate::{\n context::gas::GasOpts,\n hash::{\n compute_l1_to_l2_message_hash, compute_l1_to_l2_message_nullifier, compute_secret_hash,\n compute_siloed_nullifier,\n },\n oracle::avm,\n};\nuse crate::protocol::{\n abis::function_selector::FunctionSelector,\n address::{AztecAddress, EthAddress},\n constants::{MAX_U32_VALUE, NULL_MSG_SENDER_CONTRACT_ADDRESS},\n traits::{Empty, FromField, Packable, Serialize, ToField},\n};\n\n/// Minimal PublicContext for protocol contracts going to audit.\npub struct PublicContext {\n pub args_hash: Option<Field>,\n pub compute_args_hash: fn() -> Field,\n}\n\nimpl Eq for PublicContext {\n fn eq(self, other: Self) -> bool {\n (self.args_hash == other.args_hash)\n // Can't compare the function compute_args_hash\n }\n}\n\nimpl PublicContext {\n pub fn new(compute_args_hash: fn() -> Field) -> Self {\n PublicContext { args_hash: Option::none(), compute_args_hash }\n }\n\n /// Emits a _public_ log that will be visible onchain to everyone.\n pub fn emit_public_log<T>(_self: Self, log: T)\n where\n T: Serialize,\n {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::emit_public_log(Serialize::serialize(log).as_vector()) };\n }\n\n /// Checks if a given note hash exists in the note hash tree at a particular leaf_index.\n pub fn note_hash_exists(_self: Self, note_hash: Field, leaf_index: u64) -> bool {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::note_hash_exists(note_hash, leaf_index) } == 1\n }\n\n /// Checks if a specific L1-to-L2 message exists in the L1-to-L2 message tree at a particular leaf index.\n pub fn l1_to_l2_msg_exists(_self: Self, msg_hash: Field, msg_leaf_index: Field) -> bool {\n // Safety: AVM opcodes are constrained by the AVM itself TODO(alvaro): Make l1l2msg leaf index a u64 upstream\n unsafe { avm::l1_to_l2_msg_exists(msg_hash, msg_leaf_index as u64) } == 1\n }\n\n /// Returns `true` if an `unsiloed_nullifier` has been emitted by `contract_address`.\n pub fn nullifier_exists_unsafe(\n _self: Self,\n unsiloed_nullifier: Field,\n contract_address: AztecAddress,\n ) -> bool {\n let siloed_nullifier = compute_siloed_nullifier(contract_address, unsiloed_nullifier);\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::nullifier_exists(siloed_nullifier) } == 1\n }\n\n /// Consumes a message sent from Ethereum (L1) to Aztec (L2).\n pub fn consume_l1_to_l2_message(\n self: Self,\n content: Field,\n secret: Field,\n sender: EthAddress,\n leaf_index: Field,\n ) {\n let secret_hash = compute_secret_hash(secret);\n let message_hash = compute_l1_to_l2_message_hash(\n sender,\n self.chain_id(),\n /*recipient=*/\n self.this_address(),\n self.version(),\n content,\n secret_hash,\n leaf_index,\n );\n let nullifier = compute_l1_to_l2_message_nullifier(message_hash, secret);\n\n assert(\n !self.nullifier_exists_unsafe(nullifier, self.this_address()),\n \"L1-to-L2 message is already nullified\",\n );\n assert(\n self.l1_to_l2_msg_exists(message_hash, leaf_index),\n \"Tried to consume nonexistent L1-to-L2 message\",\n );\n\n self.push_nullifier(nullifier);\n }\n\n /// Sends an \"L2 -> L1 message\".\n pub fn message_portal(_self: Self, recipient: EthAddress, content: Field) {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::send_l2_to_l1_msg(recipient, content) };\n }\n\n /// Calls a public function on another contract.\n pub unconstrained fn call_public_function<let N: u32>(\n _self: Self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; N],\n gas_opts: GasOpts,\n ) -> [Field] {\n let calldata = [function_selector.to_field()].concat(args);\n\n avm::call(\n gas_opts.l2_gas.unwrap_or(MAX_U32_VALUE),\n gas_opts.da_gas.unwrap_or(MAX_U32_VALUE),\n contract_address,\n calldata,\n );\n // Use success_copy to determine whether the call succeeded\n let success = avm::success_copy();\n\n let result_data = avm::returndata_copy(0, avm::returndata_size());\n if !success {\n // Rethrow the revert data.\n avm::revert(result_data);\n }\n result_data\n }\n\n /// Makes a read-only call to a public function on another contract.\n pub unconstrained fn static_call_public_function<let N: u32>(\n _self: Self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; N],\n gas_opts: GasOpts,\n ) -> [Field] {\n let calldata = [function_selector.to_field()].concat(args);\n\n avm::call_static(\n gas_opts.l2_gas.unwrap_or(MAX_U32_VALUE),\n gas_opts.da_gas.unwrap_or(MAX_U32_VALUE),\n contract_address,\n calldata,\n );\n // Use success_copy to determine whether the call succeeded\n let success = avm::success_copy();\n\n let result_data = avm::returndata_copy(0, avm::returndata_size());\n if !success {\n // Rethrow the revert data.\n avm::revert(result_data);\n }\n result_data\n }\n\n /// Adds a new note hash to the Note Hash Tree.\n pub fn push_note_hash(_self: Self, note_hash: Field) {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::emit_note_hash(note_hash) };\n }\n\n /// Adds a new nullifier to the Nullifier Tree.\n pub fn push_nullifier(_self: Self, nullifier: Field) {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::emit_nullifier(nullifier) };\n }\n\n /// Returns the address of the current contract being executed.\n pub fn this_address(_self: Self) -> AztecAddress {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::address()\n }\n }\n\n /// Returns the contract address that initiated this function call.\n pub fn maybe_msg_sender(_self: Self) -> Option<AztecAddress> {\n // Safety: AVM opcodes are constrained by the AVM itself\n let maybe_msg_sender = unsafe { avm::sender() };\n if maybe_msg_sender == NULL_MSG_SENDER_CONTRACT_ADDRESS {\n Option::none()\n } else {\n Option::some(maybe_msg_sender)\n }\n }\n\n /// Returns the function selector of the currently-executing function.\n pub fn selector(_self: Self) -> FunctionSelector {\n // The selector is the first element of the calldata when calling a public function through dispatch.\n // Safety: AVM opcodes are constrained by the AVM itself.\n let raw_selector: [Field; 1] = unsafe { avm::calldata_copy(0, 1) };\n FunctionSelector::from_field(raw_selector[0])\n }\n\n /// Returns the hash of the arguments passed to the current function.\n pub fn get_args_hash(mut self) -> Field {\n if !self.args_hash.is_some() {\n self.args_hash = Option::some((self.compute_args_hash)());\n }\n\n self.args_hash.unwrap_unchecked()\n }\n\n /// Returns the \"transaction fee\" for the current transaction.\n pub fn transaction_fee(_self: Self) -> Field {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::transaction_fee()\n }\n }\n\n /// Returns the chain ID of the current network.\n pub fn chain_id(_self: Self) -> Field {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::chain_id()\n }\n }\n\n /// Returns the protocol version.\n pub fn version(_self: Self) -> Field {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::version()\n }\n }\n\n /// Returns the current block number.\n pub fn block_number(_self: Self) -> u32 {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::block_number()\n }\n }\n\n /// Returns the timestamp of the current block.\n pub fn timestamp(_self: Self) -> u64 {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::timestamp()\n }\n }\n\n /// Returns the fee per unit of L2 gas.\n pub fn min_fee_per_l2_gas(_self: Self) -> u128 {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::min_fee_per_l2_gas()\n }\n }\n\n /// Returns the fee per unit of DA gas.\n pub fn min_fee_per_da_gas(_self: Self) -> u128 {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::min_fee_per_da_gas()\n }\n }\n\n /// Returns the remaining L2 gas available.\n pub fn l2_gas_left(_self: Self) -> u32 {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::l2_gas_left()\n }\n }\n\n /// Returns the remaining DA gas available.\n pub fn da_gas_left(_self: Self) -> u32 {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::da_gas_left()\n }\n }\n\n /// Checks if the current execution is within a staticcall context.\n pub fn is_static_call(_self: Self) -> bool {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::is_static_call() } == 1\n }\n\n /// Reads raw field values from public storage.\n pub fn raw_storage_read<let N: u32>(self: Self, storage_slot: Field) -> [Field; N] {\n let mut out = [0; N];\n for i in 0..N {\n // Safety: AVM opcodes are constrained by the AVM itself\n out[i] = unsafe {\n avm::storage_read(storage_slot + i as Field, self.this_address().to_field())\n };\n }\n out\n }\n\n /// Reads a typed value from public storage.\n pub fn storage_read<T>(self, storage_slot: Field) -> T\n where\n T: Packable,\n {\n T::unpack(self.raw_storage_read(storage_slot))\n }\n\n /// Writes raw field values to public storage.\n pub fn raw_storage_write<let N: u32>(_self: Self, storage_slot: Field, values: [Field; N]) {\n for i in 0..N {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::storage_write(storage_slot + i as Field, values[i]) };\n }\n }\n\n /// Writes a typed value to public storage.\n pub fn storage_write<T>(self, storage_slot: Field, value: T)\n where\n T: Packable,\n {\n self.raw_storage_write(storage_slot, value.pack());\n }\n}\n\nimpl Empty for PublicContext {\n fn empty() -> Self {\n PublicContext::new(|| 0)\n }\n}\n"
|
|
5160
|
+
"source": "use crate::{\n context::gas::GasOpts,\n hash::{\n compute_l1_to_l2_message_hash, compute_l1_to_l2_message_nullifier, compute_secret_hash,\n compute_siloed_nullifier,\n },\n oracle::avm,\n};\nuse crate::protocol::{\n abis::function_selector::FunctionSelector,\n address::{AztecAddress, EthAddress},\n constants::{MAX_U32_VALUE, NULL_MSG_SENDER_CONTRACT_ADDRESS},\n traits::{Empty, FromField, Packable, Serialize, ToField},\n};\n\n/// Minimal PublicContext for protocol contracts going to audit.\npub struct PublicContext {\n pub args_hash: Option<Field>,\n pub compute_args_hash: fn() -> Field,\n}\n\nimpl Eq for PublicContext {\n fn eq(self, other: Self) -> bool {\n (self.args_hash == other.args_hash)\n // Can't compare the function compute_args_hash\n }\n}\n\nimpl PublicContext {\n pub fn new(compute_args_hash: fn() -> Field) -> Self {\n PublicContext { args_hash: Option::none(), compute_args_hash }\n }\n\n /// Emits a _public_ log that will be visible onchain to everyone.\n pub fn emit_public_log<T>(_self: Self, log: T)\n where\n T: Serialize,\n {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::emit_public_log(Serialize::serialize(log).as_vector()) };\n }\n\n /// Checks if a given note hash exists in the note hash tree at a particular leaf_index.\n pub fn note_hash_exists(_self: Self, note_hash: Field, leaf_index: u64) -> bool {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::note_hash_exists(note_hash, leaf_index) }\n }\n\n /// Checks if a specific L1-to-L2 message exists in the L1-to-L2 message tree at a particular leaf index.\n pub fn l1_to_l2_msg_exists(_self: Self, msg_hash: Field, msg_leaf_index: Field) -> bool {\n // Safety: AVM opcodes are constrained by the AVM itself TODO(alvaro): Make l1l2msg leaf index a u64 upstream\n unsafe { avm::l1_to_l2_msg_exists(msg_hash, msg_leaf_index as u64) }\n }\n\n /// Returns `true` if an `unsiloed_nullifier` has been emitted by `contract_address`.\n pub fn nullifier_exists_unsafe(\n _self: Self,\n unsiloed_nullifier: Field,\n contract_address: AztecAddress,\n ) -> bool {\n let siloed_nullifier = compute_siloed_nullifier(contract_address, unsiloed_nullifier);\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::nullifier_exists(siloed_nullifier) }\n }\n\n /// Consumes a message sent from Ethereum (L1) to Aztec (L2).\n pub fn consume_l1_to_l2_message(\n self: Self,\n content: Field,\n secret: Field,\n sender: EthAddress,\n leaf_index: Field,\n ) {\n let secret_hash = compute_secret_hash(secret);\n let message_hash = compute_l1_to_l2_message_hash(\n sender,\n self.chain_id(),\n /*recipient=*/\n self.this_address(),\n self.version(),\n content,\n secret_hash,\n leaf_index,\n );\n let nullifier = compute_l1_to_l2_message_nullifier(message_hash, secret);\n\n assert(\n !self.nullifier_exists_unsafe(nullifier, self.this_address()),\n \"L1-to-L2 message is already nullified\",\n );\n assert(\n self.l1_to_l2_msg_exists(message_hash, leaf_index),\n \"Tried to consume nonexistent L1-to-L2 message\",\n );\n\n self.push_nullifier(nullifier);\n }\n\n /// Sends an \"L2 -> L1 message\".\n pub fn message_portal(_self: Self, recipient: EthAddress, content: Field) {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::send_l2_to_l1_msg(recipient, content) };\n }\n\n /// Calls a public function on another contract.\n pub unconstrained fn call_public_function<let N: u32>(\n _self: Self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; N],\n gas_opts: GasOpts,\n ) -> [Field] {\n let calldata = [function_selector.to_field()].concat(args);\n\n avm::call(\n gas_opts.l2_gas.unwrap_or(MAX_U32_VALUE),\n gas_opts.da_gas.unwrap_or(MAX_U32_VALUE),\n contract_address,\n calldata,\n );\n // Use success_copy to determine whether the call succeeded\n let success = avm::success_copy();\n\n let result_data = avm::returndata_copy(0, avm::returndata_size());\n if !success {\n // Rethrow the revert data.\n avm::revert(result_data);\n }\n result_data\n }\n\n /// Makes a read-only call to a public function on another contract.\n pub unconstrained fn static_call_public_function<let N: u32>(\n _self: Self,\n contract_address: AztecAddress,\n function_selector: FunctionSelector,\n args: [Field; N],\n gas_opts: GasOpts,\n ) -> [Field] {\n let calldata = [function_selector.to_field()].concat(args);\n\n avm::call_static(\n gas_opts.l2_gas.unwrap_or(MAX_U32_VALUE),\n gas_opts.da_gas.unwrap_or(MAX_U32_VALUE),\n contract_address,\n calldata,\n );\n // Use success_copy to determine whether the call succeeded\n let success = avm::success_copy();\n\n let result_data = avm::returndata_copy(0, avm::returndata_size());\n if !success {\n // Rethrow the revert data.\n avm::revert(result_data);\n }\n result_data\n }\n\n /// Adds a new note hash to the Note Hash Tree.\n pub fn push_note_hash(_self: Self, note_hash: Field) {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::emit_note_hash(note_hash) };\n }\n\n /// Adds a new nullifier to the Nullifier Tree.\n pub fn push_nullifier(_self: Self, nullifier: Field) {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::emit_nullifier(nullifier) };\n }\n\n /// Returns the address of the current contract being executed.\n pub fn this_address(_self: Self) -> AztecAddress {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::address()\n }\n }\n\n /// Returns the contract address that initiated this function call.\n pub fn maybe_msg_sender(_self: Self) -> Option<AztecAddress> {\n // Safety: AVM opcodes are constrained by the AVM itself\n let maybe_msg_sender = unsafe { avm::sender() };\n if maybe_msg_sender == NULL_MSG_SENDER_CONTRACT_ADDRESS {\n Option::none()\n } else {\n Option::some(maybe_msg_sender)\n }\n }\n\n /// Returns the function selector of the currently-executing function.\n pub fn selector(_self: Self) -> FunctionSelector {\n // The selector is the first element of the calldata when calling a public function through dispatch.\n // Safety: AVM opcodes are constrained by the AVM itself.\n let raw_selector: [Field; 1] = unsafe { avm::calldata_copy(0, 1) };\n FunctionSelector::from_field(raw_selector[0])\n }\n\n /// Returns the hash of the arguments passed to the current function.\n pub fn get_args_hash(mut self) -> Field {\n if !self.args_hash.is_some() {\n self.args_hash = Option::some((self.compute_args_hash)());\n }\n\n self.args_hash.unwrap_unchecked()\n }\n\n /// Returns the \"transaction fee\" for the current transaction.\n pub fn transaction_fee(_self: Self) -> Field {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::transaction_fee()\n }\n }\n\n /// Returns the chain ID of the current network.\n pub fn chain_id(_self: Self) -> Field {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::chain_id()\n }\n }\n\n /// Returns the protocol version.\n pub fn version(_self: Self) -> Field {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::version()\n }\n }\n\n /// Returns the current block number.\n pub fn block_number(_self: Self) -> u32 {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::block_number()\n }\n }\n\n /// Returns the timestamp of the current block.\n pub fn timestamp(_self: Self) -> u64 {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::timestamp()\n }\n }\n\n /// Returns the fee per unit of L2 gas.\n pub fn min_fee_per_l2_gas(_self: Self) -> u128 {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::min_fee_per_l2_gas()\n }\n }\n\n /// Returns the fee per unit of DA gas.\n pub fn min_fee_per_da_gas(_self: Self) -> u128 {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::min_fee_per_da_gas()\n }\n }\n\n /// Returns the remaining L2 gas available.\n pub fn l2_gas_left(_self: Self) -> u32 {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::l2_gas_left()\n }\n }\n\n /// Returns the remaining DA gas available.\n pub fn da_gas_left(_self: Self) -> u32 {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe {\n avm::da_gas_left()\n }\n }\n\n /// Checks if the current execution is within a staticcall context.\n pub fn is_static_call(_self: Self) -> bool {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::is_static_call() }\n }\n\n /// Reads raw field values from public storage.\n pub fn raw_storage_read<let N: u32>(self: Self, storage_slot: Field) -> [Field; N] {\n let mut out = [0; N];\n for i in 0..N {\n // Safety: AVM opcodes are constrained by the AVM itself\n out[i] = unsafe {\n avm::storage_read(storage_slot + i as Field, self.this_address().to_field())\n };\n }\n out\n }\n\n /// Reads a typed value from public storage.\n pub fn storage_read<T>(self, storage_slot: Field) -> T\n where\n T: Packable,\n {\n T::unpack(self.raw_storage_read(storage_slot))\n }\n\n /// Writes raw field values to public storage.\n pub fn raw_storage_write<let N: u32>(_self: Self, storage_slot: Field, values: [Field; N]) {\n for i in 0..N {\n // Safety: AVM opcodes are constrained by the AVM itself\n unsafe { avm::storage_write(storage_slot + i as Field, values[i]) };\n }\n }\n\n /// Writes a typed value to public storage.\n pub fn storage_write<T>(self, storage_slot: Field, value: T)\n where\n T: Packable,\n {\n self.raw_storage_write(storage_slot, value.pack());\n }\n}\n\nimpl Empty for PublicContext {\n fn empty() -> Self {\n PublicContext::new(|| 0)\n }\n}\n"
|
|
5259
5161
|
},
|
|
5260
5162
|
"61": {
|
|
5261
5163
|
"function_locations": [
|
|
@@ -5345,195 +5247,195 @@
|
|
|
5345
5247
|
},
|
|
5346
5248
|
{
|
|
5347
5249
|
"name": "is_static_call",
|
|
5348
|
-
"start":
|
|
5250
|
+
"start": 1080
|
|
5349
5251
|
},
|
|
5350
5252
|
{
|
|
5351
5253
|
"name": "note_hash_exists",
|
|
5352
|
-
"start":
|
|
5254
|
+
"start": 1193
|
|
5353
5255
|
},
|
|
5354
5256
|
{
|
|
5355
5257
|
"name": "emit_note_hash",
|
|
5356
|
-
"start":
|
|
5258
|
+
"start": 1302
|
|
5357
5259
|
},
|
|
5358
5260
|
{
|
|
5359
5261
|
"name": "nullifier_exists",
|
|
5360
|
-
"start":
|
|
5262
|
+
"start": 1414
|
|
5361
5263
|
},
|
|
5362
5264
|
{
|
|
5363
5265
|
"name": "emit_nullifier",
|
|
5364
|
-
"start":
|
|
5266
|
+
"start": 1518
|
|
5365
5267
|
},
|
|
5366
5268
|
{
|
|
5367
5269
|
"name": "emit_public_log",
|
|
5368
|
-
"start":
|
|
5270
|
+
"start": 1614
|
|
5369
5271
|
},
|
|
5370
5272
|
{
|
|
5371
5273
|
"name": "l1_to_l2_msg_exists",
|
|
5372
|
-
"start":
|
|
5274
|
+
"start": 1741
|
|
5373
5275
|
},
|
|
5374
5276
|
{
|
|
5375
5277
|
"name": "send_l2_to_l1_msg",
|
|
5376
|
-
"start":
|
|
5278
|
+
"start": 1880
|
|
5377
5279
|
},
|
|
5378
5280
|
{
|
|
5379
5281
|
"name": "call",
|
|
5380
|
-
"start":
|
|
5282
|
+
"start": 2080
|
|
5381
5283
|
},
|
|
5382
5284
|
{
|
|
5383
5285
|
"name": "call_static",
|
|
5384
|
-
"start":
|
|
5286
|
+
"start": 2310
|
|
5385
5287
|
},
|
|
5386
5288
|
{
|
|
5387
5289
|
"name": "calldata_copy",
|
|
5388
|
-
"start":
|
|
5290
|
+
"start": 2486
|
|
5389
5291
|
},
|
|
5390
5292
|
{
|
|
5391
5293
|
"name": "success_copy",
|
|
5392
|
-
"start":
|
|
5294
|
+
"start": 2669
|
|
5393
5295
|
},
|
|
5394
5296
|
{
|
|
5395
5297
|
"name": "returndata_size",
|
|
5396
|
-
"start":
|
|
5298
|
+
"start": 2746
|
|
5397
5299
|
},
|
|
5398
5300
|
{
|
|
5399
5301
|
"name": "returndata_copy",
|
|
5400
|
-
"start":
|
|
5302
|
+
"start": 2859
|
|
5401
5303
|
},
|
|
5402
5304
|
{
|
|
5403
5305
|
"name": "avm_return",
|
|
5404
|
-
"start":
|
|
5306
|
+
"start": 3044
|
|
5405
5307
|
},
|
|
5406
5308
|
{
|
|
5407
5309
|
"name": "revert",
|
|
5408
|
-
"start":
|
|
5310
|
+
"start": 3421
|
|
5409
5311
|
},
|
|
5410
5312
|
{
|
|
5411
5313
|
"name": "storage_read",
|
|
5412
|
-
"start":
|
|
5314
|
+
"start": 3545
|
|
5413
5315
|
},
|
|
5414
5316
|
{
|
|
5415
5317
|
"name": "storage_write",
|
|
5416
|
-
"start":
|
|
5318
|
+
"start": 3676
|
|
5417
5319
|
},
|
|
5418
5320
|
{
|
|
5419
5321
|
"name": "address_opcode",
|
|
5420
|
-
"start":
|
|
5322
|
+
"start": 3807
|
|
5421
5323
|
},
|
|
5422
5324
|
{
|
|
5423
5325
|
"name": "sender_opcode",
|
|
5424
|
-
"start":
|
|
5326
|
+
"start": 3888
|
|
5425
5327
|
},
|
|
5426
5328
|
{
|
|
5427
5329
|
"name": "transaction_fee_opcode",
|
|
5428
|
-
"start":
|
|
5330
|
+
"start": 3979
|
|
5429
5331
|
},
|
|
5430
5332
|
{
|
|
5431
5333
|
"name": "chain_id_opcode",
|
|
5432
|
-
"start":
|
|
5334
|
+
"start": 4056
|
|
5433
5335
|
},
|
|
5434
5336
|
{
|
|
5435
5337
|
"name": "version_opcode",
|
|
5436
|
-
"start":
|
|
5338
|
+
"start": 4132
|
|
5437
5339
|
},
|
|
5438
5340
|
{
|
|
5439
5341
|
"name": "block_number_opcode",
|
|
5440
|
-
"start":
|
|
5342
|
+
"start": 4215
|
|
5441
5343
|
},
|
|
5442
5344
|
{
|
|
5443
5345
|
"name": "timestamp_opcode",
|
|
5444
|
-
"start":
|
|
5346
|
+
"start": 4293
|
|
5445
5347
|
},
|
|
5446
5348
|
{
|
|
5447
5349
|
"name": "min_fee_per_l2_gas_opcode",
|
|
5448
|
-
"start":
|
|
5350
|
+
"start": 4386
|
|
5449
5351
|
},
|
|
5450
5352
|
{
|
|
5451
5353
|
"name": "min_fee_per_da_gas_opcode",
|
|
5452
|
-
"start":
|
|
5354
|
+
"start": 4479
|
|
5453
5355
|
},
|
|
5454
5356
|
{
|
|
5455
5357
|
"name": "l2_gas_left_opcode",
|
|
5456
|
-
"start":
|
|
5358
|
+
"start": 4559
|
|
5457
5359
|
},
|
|
5458
5360
|
{
|
|
5459
5361
|
"name": "da_gas_left_opcode",
|
|
5460
|
-
"start":
|
|
5362
|
+
"start": 4639
|
|
5461
5363
|
},
|
|
5462
5364
|
{
|
|
5463
5365
|
"name": "is_static_call_opcode",
|
|
5464
|
-
"start":
|
|
5366
|
+
"start": 4726
|
|
5465
5367
|
},
|
|
5466
5368
|
{
|
|
5467
5369
|
"name": "note_hash_exists_opcode",
|
|
5468
|
-
"start":
|
|
5370
|
+
"start": 4850
|
|
5469
5371
|
},
|
|
5470
5372
|
{
|
|
5471
5373
|
"name": "emit_note_hash_opcode",
|
|
5472
|
-
"start":
|
|
5374
|
+
"start": 4945
|
|
5473
5375
|
},
|
|
5474
5376
|
{
|
|
5475
5377
|
"name": "nullifier_exists_opcode",
|
|
5476
|
-
"start":
|
|
5378
|
+
"start": 5060
|
|
5477
5379
|
},
|
|
5478
5380
|
{
|
|
5479
5381
|
"name": "emit_nullifier_opcode",
|
|
5480
|
-
"start":
|
|
5382
|
+
"start": 5156
|
|
5481
5383
|
},
|
|
5482
5384
|
{
|
|
5483
5385
|
"name": "emit_public_log_opcode",
|
|
5484
|
-
"start":
|
|
5386
|
+
"start": 5253
|
|
5485
5387
|
},
|
|
5486
5388
|
{
|
|
5487
5389
|
"name": "l1_to_l2_msg_exists_opcode",
|
|
5488
|
-
"start":
|
|
5390
|
+
"start": 5384
|
|
5489
5391
|
},
|
|
5490
5392
|
{
|
|
5491
5393
|
"name": "send_l2_to_l1_msg_opcode",
|
|
5492
|
-
"start":
|
|
5394
|
+
"start": 5504
|
|
5493
5395
|
},
|
|
5494
5396
|
{
|
|
5495
5397
|
"name": "calldata_copy_opcode",
|
|
5496
|
-
"start":
|
|
5398
|
+
"start": 5637
|
|
5497
5399
|
},
|
|
5498
5400
|
{
|
|
5499
5401
|
"name": "returndata_size_opcode",
|
|
5500
|
-
"start":
|
|
5402
|
+
"start": 5726
|
|
5501
5403
|
},
|
|
5502
5404
|
{
|
|
5503
5405
|
"name": "returndata_copy_opcode",
|
|
5504
|
-
"start":
|
|
5406
|
+
"start": 5848
|
|
5505
5407
|
},
|
|
5506
5408
|
{
|
|
5507
5409
|
"name": "return_opcode",
|
|
5508
|
-
"start":
|
|
5410
|
+
"start": 5932
|
|
5509
5411
|
},
|
|
5510
5412
|
{
|
|
5511
5413
|
"name": "revert_opcode",
|
|
5512
|
-
"start":
|
|
5414
|
+
"start": 6016
|
|
5513
5415
|
},
|
|
5514
5416
|
{
|
|
5515
5417
|
"name": "call_opcode",
|
|
5516
|
-
"start":
|
|
5418
|
+
"start": 6463
|
|
5517
5419
|
},
|
|
5518
5420
|
{
|
|
5519
5421
|
"name": "call_static_opcode",
|
|
5520
|
-
"start":
|
|
5422
|
+
"start": 6923
|
|
5521
5423
|
},
|
|
5522
5424
|
{
|
|
5523
5425
|
"name": "success_copy_opcode",
|
|
5524
|
-
"start":
|
|
5426
|
+
"start": 7007
|
|
5525
5427
|
},
|
|
5526
5428
|
{
|
|
5527
5429
|
"name": "storage_read_opcode",
|
|
5528
|
-
"start":
|
|
5430
|
+
"start": 7136
|
|
5529
5431
|
},
|
|
5530
5432
|
{
|
|
5531
5433
|
"name": "storage_write_opcode",
|
|
5532
|
-
"start":
|
|
5434
|
+
"start": 7247
|
|
5533
5435
|
}
|
|
5534
5436
|
],
|
|
5535
5437
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/aztec_sublib/src/oracle/avm.nr",
|
|
5536
|
-
"source": "//! AVM oracles.\n//!\n//! There are only available during public execution. Calling any of them from a private or utility function will\n//! result in runtime errors.\n\nuse crate::protocol::address::{AztecAddress, EthAddress};\n\npub unconstrained fn address() -> AztecAddress {\n address_opcode()\n}\npub unconstrained fn sender() -> AztecAddress {\n sender_opcode()\n}\npub unconstrained fn transaction_fee() -> Field {\n transaction_fee_opcode()\n}\npub unconstrained fn chain_id() -> Field {\n chain_id_opcode()\n}\npub unconstrained fn version() -> Field {\n version_opcode()\n}\npub unconstrained fn block_number() -> u32 {\n block_number_opcode()\n}\npub unconstrained fn timestamp() -> u64 {\n timestamp_opcode()\n}\npub unconstrained fn min_fee_per_l2_gas() -> u128 {\n min_fee_per_l2_gas_opcode()\n}\npub unconstrained fn min_fee_per_da_gas() -> u128 {\n min_fee_per_da_gas_opcode()\n}\npub unconstrained fn l2_gas_left() -> u32 {\n l2_gas_left_opcode()\n}\npub unconstrained fn da_gas_left() -> u32 {\n da_gas_left_opcode()\n}\npub unconstrained fn is_static_call() ->
|
|
5438
|
+
"source": "//! AVM oracles.\n//!\n//! There are only available during public execution. Calling any of them from a private or utility function will\n//! result in runtime errors.\n\nuse crate::protocol::address::{AztecAddress, EthAddress};\n\npub unconstrained fn address() -> AztecAddress {\n address_opcode()\n}\npub unconstrained fn sender() -> AztecAddress {\n sender_opcode()\n}\npub unconstrained fn transaction_fee() -> Field {\n transaction_fee_opcode()\n}\npub unconstrained fn chain_id() -> Field {\n chain_id_opcode()\n}\npub unconstrained fn version() -> Field {\n version_opcode()\n}\npub unconstrained fn block_number() -> u32 {\n block_number_opcode()\n}\npub unconstrained fn timestamp() -> u64 {\n timestamp_opcode()\n}\npub unconstrained fn min_fee_per_l2_gas() -> u128 {\n min_fee_per_l2_gas_opcode()\n}\npub unconstrained fn min_fee_per_da_gas() -> u128 {\n min_fee_per_da_gas_opcode()\n}\npub unconstrained fn l2_gas_left() -> u32 {\n l2_gas_left_opcode()\n}\npub unconstrained fn da_gas_left() -> u32 {\n da_gas_left_opcode()\n}\npub unconstrained fn is_static_call() -> bool {\n is_static_call_opcode()\n}\npub unconstrained fn note_hash_exists(note_hash: Field, leaf_index: u64) -> bool {\n note_hash_exists_opcode(note_hash, leaf_index)\n}\npub unconstrained fn emit_note_hash(note_hash: Field) {\n emit_note_hash_opcode(note_hash)\n}\npub unconstrained fn nullifier_exists(siloed_nullifier: Field) -> bool {\n nullifier_exists_opcode(siloed_nullifier)\n}\npub unconstrained fn emit_nullifier(nullifier: Field) {\n emit_nullifier_opcode(nullifier)\n}\npub unconstrained fn emit_public_log(message: [Field]) {\n emit_public_log_opcode(message)\n}\npub unconstrained fn l1_to_l2_msg_exists(msg_hash: Field, msg_leaf_index: u64) -> bool {\n l1_to_l2_msg_exists_opcode(msg_hash, msg_leaf_index)\n}\npub unconstrained fn send_l2_to_l1_msg(recipient: EthAddress, content: Field) {\n send_l2_to_l1_msg_opcode(recipient, content)\n}\n\npub unconstrained fn call<let N: u32>(\n l2_gas_allocation: u32,\n da_gas_allocation: u32,\n address: AztecAddress,\n args: [Field; N],\n) {\n call_opcode(l2_gas_allocation, da_gas_allocation, address, N, args)\n}\n\npub unconstrained fn call_static<let N: u32>(\n l2_gas_allocation: u32,\n da_gas_allocation: u32,\n address: AztecAddress,\n args: [Field; N],\n) {\n call_static_opcode(l2_gas_allocation, da_gas_allocation, address, N, args)\n}\n\npub unconstrained fn calldata_copy<let N: u32>(cdoffset: u32, copy_size: u32) -> [Field; N] {\n calldata_copy_opcode(cdoffset, copy_size)\n}\n\n/// `success_copy` is placed immediately after the CALL opcode to get the success value\npub unconstrained fn success_copy() -> bool {\n success_copy_opcode()\n}\n\npub unconstrained fn returndata_size() -> u32 {\n returndata_size_opcode()\n}\n\npub unconstrained fn returndata_copy(rdoffset: u32, copy_size: u32) -> [Field] {\n returndata_copy_opcode(rdoffset, copy_size)\n}\n\n/// The additional prefix is to avoid clashing with the `return` Noir keyword.\npub unconstrained fn avm_return(returndata: [Field]) {\n return_opcode(returndata)\n}\n\n/// This opcode reverts using the exact data given. In general it should only be used to do rethrows, where the revert\n/// data is the same as the original revert data. For normal reverts, use Noir's `assert` which, on top of reverting,\n/// will also add an error selector to the revert data.\npub unconstrained fn revert(revertdata: [Field]) {\n revert_opcode(revertdata)\n}\n\npub unconstrained fn storage_read(storage_slot: Field, contract_address: Field) -> Field {\n storage_read_opcode(storage_slot, contract_address)\n}\n\npub unconstrained fn storage_write(storage_slot: Field, value: Field) {\n storage_write_opcode(storage_slot, value);\n}\n\n#[oracle(aztec_avm_address)]\nunconstrained fn address_opcode() -> AztecAddress {}\n\n#[oracle(aztec_avm_sender)]\nunconstrained fn sender_opcode() -> AztecAddress {}\n\n#[oracle(aztec_avm_transactionFee)]\nunconstrained fn transaction_fee_opcode() -> Field {}\n\n#[oracle(aztec_avm_chainId)]\nunconstrained fn chain_id_opcode() -> Field {}\n\n#[oracle(aztec_avm_version)]\nunconstrained fn version_opcode() -> Field {}\n\n#[oracle(aztec_avm_blockNumber)]\nunconstrained fn block_number_opcode() -> u32 {}\n\n#[oracle(aztec_avm_timestamp)]\nunconstrained fn timestamp_opcode() -> u64 {}\n\n#[oracle(aztec_avm_minFeePerL2Gas)]\nunconstrained fn min_fee_per_l2_gas_opcode() -> u128 {}\n\n#[oracle(aztec_avm_minFeePerDaGas)]\nunconstrained fn min_fee_per_da_gas_opcode() -> u128 {}\n\n#[oracle(aztec_avm_l2GasLeft)]\nunconstrained fn l2_gas_left_opcode() -> u32 {}\n\n#[oracle(aztec_avm_daGasLeft)]\nunconstrained fn da_gas_left_opcode() -> u32 {}\n\n#[oracle(aztec_avm_isStaticCall)]\nunconstrained fn is_static_call_opcode() -> bool {}\n\n#[oracle(aztec_avm_noteHashExists)]\nunconstrained fn note_hash_exists_opcode(note_hash: Field, leaf_index: u64) -> bool {}\n\n#[oracle(aztec_avm_emitNoteHash)]\nunconstrained fn emit_note_hash_opcode(note_hash: Field) {}\n\n#[oracle(aztec_avm_nullifierExists)]\nunconstrained fn nullifier_exists_opcode(siloed_nullifier: Field) -> bool {}\n\n#[oracle(aztec_avm_emitNullifier)]\nunconstrained fn emit_nullifier_opcode(nullifier: Field) {}\n\n#[oracle(aztec_avm_emitPublicLog)]\nunconstrained fn emit_public_log_opcode(message: [Field]) {}\n\n#[oracle(aztec_avm_l1ToL2MsgExists)]\nunconstrained fn l1_to_l2_msg_exists_opcode(msg_hash: Field, msg_leaf_index: u64) -> bool {}\n\n#[oracle(aztec_avm_sendL2ToL1Msg)]\nunconstrained fn send_l2_to_l1_msg_opcode(recipient: EthAddress, content: Field) {}\n\n#[oracle(aztec_avm_calldataCopy)]\nunconstrained fn calldata_copy_opcode<let N: u32>(cdoffset: u32, copy_size: u32) -> [Field; N] {}\n\n#[oracle(aztec_avm_returndataSize)]\nunconstrained fn returndata_size_opcode() -> u32 {}\n\n#[oracle(aztec_avm_returndataCopy)]\nunconstrained fn returndata_copy_opcode(rdoffset: u32, copy_size: u32) -> [Field] {}\n\n#[oracle(aztec_avm_return)]\nunconstrained fn return_opcode(returndata: [Field]) {}\n\n#[oracle(aztec_avm_revert)]\nunconstrained fn revert_opcode(revertdata: [Field]) {}\n\n// While the length parameter might seem unnecessary given that we have N we keep it around because at the AVM bytecode\n// level, we want to support non-comptime-known lengths for such opcodes, even if Noir code will not generally take\n// that route.\n#[oracle(aztec_avm_call)]\nunconstrained fn call_opcode<let N: u32>(\n l2_gas_allocation: u32,\n da_gas_allocation: u32,\n address: AztecAddress,\n length: u32,\n args: [Field; N],\n) {}\n\n// While the length parameter might seem unnecessary given that we have N we keep it around because at the AVM bytecode\n// level, we want to support non-comptime-known lengths for such opcodes, even if Noir code will not generally take\n// that route.\n#[oracle(aztec_avm_staticCall)]\nunconstrained fn call_static_opcode<let N: u32>(\n l2_gas_allocation: u32,\n da_gas_allocation: u32,\n address: AztecAddress,\n length: u32,\n args: [Field; N],\n) {}\n\n#[oracle(aztec_avm_successCopy)]\nunconstrained fn success_copy_opcode() -> bool {}\n\n#[oracle(aztec_avm_storageRead)]\nunconstrained fn storage_read_opcode(storage_slot: Field, contract_address: Field) -> Field {}\n\n#[oracle(aztec_avm_storageWrite)]\nunconstrained fn storage_write_opcode(storage_slot: Field, value: Field) {}\n"
|
|
5537
5439
|
},
|
|
5538
5440
|
"79": {
|
|
5539
5441
|
"function_locations": [
|
|
@@ -5569,27 +5471,27 @@
|
|
|
5569
5471
|
"function_locations": [
|
|
5570
5472
|
{
|
|
5571
5473
|
"name": "assert_compatible_oracle_version",
|
|
5572
|
-
"start":
|
|
5474
|
+
"start": 1191
|
|
5573
5475
|
},
|
|
5574
5476
|
{
|
|
5575
5477
|
"name": "assert_compatible_oracle_version_wrapper",
|
|
5576
|
-
"start":
|
|
5478
|
+
"start": 1500
|
|
5577
5479
|
},
|
|
5578
5480
|
{
|
|
5579
5481
|
"name": "assert_compatible_oracle_version_oracle",
|
|
5580
|
-
"start":
|
|
5482
|
+
"start": 1732
|
|
5581
5483
|
},
|
|
5582
5484
|
{
|
|
5583
5485
|
"name": "test::compatible_oracle_version",
|
|
5584
|
-
"start":
|
|
5486
|
+
"start": 1926
|
|
5585
5487
|
},
|
|
5586
5488
|
{
|
|
5587
|
-
"name": "test::
|
|
5588
|
-
"start":
|
|
5489
|
+
"name": "test::incompatible_oracle_version_major",
|
|
5490
|
+
"start": 2151
|
|
5589
5491
|
}
|
|
5590
5492
|
],
|
|
5591
5493
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/aztec_sublib/src/oracle/version.nr",
|
|
5592
|
-
"source": "/// The
|
|
5494
|
+
"source": "/// The oracle version constants are used to check that the oracle interface is in sync between PXE and Aztec.nr.\n/// We version the oracle interface as `major.minor` where:\n/// - `major` = backward-breaking changes (must match exactly between PXE and Aztec.nr)\n/// - `minor` = oracle additions (non-breaking; PXE minor >= contract minor)\n///\n/// The TypeScript counterparts are in `oracle_version.ts`.\n///\n/// @dev Whenever a contract function or Noir test is run, the `aztec_utl_assertCompatibleOracleVersion` oracle is\n/// called. If the major version is incompatible, an error is thrown immediately. The minor version is recorded by\n/// the PXE and used to provide helpful error messages if a contract calls an oracle that doesn't exist. We don't throw\n/// immediately if AZTEC_NR_MINOR > PXE_MINOR because if a contract is updated to use a newer Aztec.nr dependency\n/// without actually using any of the new oracles then there is no reason to throw.\npub global ORACLE_VERSION_MAJOR: Field = 22;\npub global ORACLE_VERSION_MINOR: Field = 1;\n\n/// Asserts that the version of the oracle is compatible with the version expected by the contract.\npub fn assert_compatible_oracle_version() {\n // Safety: This oracle call returns nothing: we only call it to check Aztec.nr and Oracle interface versions are\n // compatible. It is therefore always safe to call.\n unsafe {\n assert_compatible_oracle_version_wrapper();\n }\n}\n\nunconstrained fn assert_compatible_oracle_version_wrapper() {\n assert_compatible_oracle_version_oracle(ORACLE_VERSION_MAJOR, ORACLE_VERSION_MINOR);\n}\n\n#[oracle(aztec_utl_assertCompatibleOracleVersionV2)]\nunconstrained fn assert_compatible_oracle_version_oracle(major: Field, minor: Field) {}\n\nmod test {\n use super::{\n assert_compatible_oracle_version_oracle, ORACLE_VERSION_MAJOR, ORACLE_VERSION_MINOR,\n };\n\n #[test]\n unconstrained fn compatible_oracle_version() {\n assert_compatible_oracle_version_oracle(ORACLE_VERSION_MAJOR, ORACLE_VERSION_MINOR);\n }\n\n #[test(should_fail_with = \"Incompatible aztec cli version:\")]\n unconstrained fn incompatible_oracle_version_major() {\n let arbitrary_incorrect_major = 318183437;\n assert_compatible_oracle_version_oracle(arbitrary_incorrect_major, ORACLE_VERSION_MINOR);\n }\n}\n"
|
|
5593
5495
|
},
|
|
5594
5496
|
"84": {
|
|
5595
5497
|
"function_locations": [
|