@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
package/artifacts/FeeJuice.json
CHANGED
|
@@ -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": "FeeJuice",
|
|
5
5
|
"functions": [
|
|
6
6
|
{
|
|
@@ -40,10 +40,6 @@
|
|
|
40
40
|
],
|
|
41
41
|
"return_type": null,
|
|
42
42
|
"error_types": {
|
|
43
|
-
"361444214588792908": {
|
|
44
|
-
"error_kind": "string",
|
|
45
|
-
"string": "attempt to multiply with overflow"
|
|
46
|
-
},
|
|
47
43
|
"8637882143979902881": {
|
|
48
44
|
"error_kind": "string",
|
|
49
45
|
"string": "Function _increase_public_balance can only be called by the same contract"
|
|
@@ -55,15 +51,11 @@
|
|
|
55
51
|
"14990209321349310352": {
|
|
56
52
|
"error_kind": "string",
|
|
57
53
|
"string": "attempt to add with overflow"
|
|
58
|
-
},
|
|
59
|
-
"16431471497789672479": {
|
|
60
|
-
"error_kind": "string",
|
|
61
|
-
"string": "Index out of bounds"
|
|
62
54
|
}
|
|
63
55
|
}
|
|
64
56
|
},
|
|
65
|
-
"bytecode": "
|
|
66
|
-
"debug_symbols": "
|
|
57
|
+
"bytecode": "JwACBAEoAAABBIBGJwAABEYlAAAASicCBAQCJwIFBAAfCgAEAAUARBwARUUGLQhEAi0IRQMlAAAAcCcCAgRGJwIDBAA7DgADAAIsAABDADBkTnLhMaApuFBFtoGBWF0oM+hIeblwkUPh9ZPwAAAAJh4CAAQBCiIEQwUWCgUGHAoGBwAEKgcEBicCBAEACioFBAckAgAHAAAAoycCCAQAPAYIAR4CAAUACioGBQckAgAHAAAAuiUAAAG+JwIFAAEpAgAGAO9SU00rAgAHAAAAAAAAAAADAAAAAAAAAAAtCAEIJwIJBAUACAEJAScDCAQBACIIAgktCgkKLQ4GCgAiCgIKLQ4FCgAiCgIKLQ4CCgAiCgIKLQ4HCi0IAQInAgUEBQAIAQUBJwMCBAEAIggCBQAiAgIGPw8ABQAGJwIFBAEAKgIFBi0LBgYnAgUAAAoqBgUHCioHBAUkAgAFAAABZSUAAAHQHgIABAAvKgAGAAQABRwKBQcGHAoHBAAcCgQFBgAqBQMEDioFBAckAgAHAAABmCUAAAHiLQsIAwAiAwIDLQ4DCC0LAgMAIgMCAy0OAwIcCgQCADAKAAIABiYqAQABBXff7AtjnJehPAQCASYqAQABBbq7IdeCMxhkPAQCASYqAQABBdAH6/TLxmeQPAQCASY=",
|
|
58
|
+
"debug_symbols": "pVjbbuIwEP2XPPPgufgy/MpqVVGaVkgIUAorrSr+fcfFk4RKtljygk8m+HA8PjNO+Ore+tfLx8vu8H787Na/vrrXYbff7z5e9sft5rw7HjT61bn8AYDdmlY6xm7tdUQsY7jFCcqo11FHhjKWa89llNsYqFuDyyApAAWRCkhgQOdCUiBwA+hcAWgR9AWQ3SKLsEV4jEgBngykAgIaiAVE+4lYZGBSQnQZsAEpQCwiJUKODVgEVAbqugidgTGSv6PpI2IDFmGLeDSgClEUZM2Up0clpHwr+gKSRVKO6EaROAMlwo4MaBIYFeRNvoFYQM4zcwa+gJznG1BhnDJQqR6u11Vnvnk5D32fbTMzktrrtBn6w7lbHy77/ar7s9lfvr/0edocvsfzZtC7mqr+8KajEr7v9n1G19U029WnRnE2OwrySPCtbmKAOkNglsIQOODEIHcMWGegkYDCpCDi4wpiNAUepaaA6wyMlgTWcpsInsoiUS2Loc4g4AuBYBrnMzyugGRUMF/CPUNqZFHbiWURUqxlUeoMGFMh0OKu7eOjWQxQW0ODIQGEwpCAfNXNDTOC9r5CASgTRQr3FNTIQ7JlkEx7iUD3DA0/CrnRDsRTTUG6L+xsmiqHY9tPceLqHKFVmUZBabYS/sEQG7mAaDuCkPg5DiSTgRgaOhre1P48lji6OMvGwzJIIoz7GqUuo+UuECtTIBdq7sIGhU9jmbppV1N6qka42vGxZU+2fisRaxKw4U1wSCZCsa92G2y1TJE4cjjgKkdc3PQwLex67XV4nNYx6/4/RFBjU8n70ZvBYVVGe09wtiexepJTy99TC9dH0Cmf+vT5lD+9q/mTGv7EscgIpmOE/qNEQholzF3xQ0JYfIxQXHqMUFp+jJAsP0bYLT1GGJYfI02OB48RpsXHyKPekqq3uFWpMG4r6FtkrQFzy54u5eePUuwJq82TGwaFOB1mCbBa7G0hMU5dXAmrQqRF4nlqoV6qLdS3TBqScVBEumuhv/Vqs90Nd6/518w17Dav+75cvl8O29nd89+T3bG/CU7Dcdu/XYY+M83/K9C3veRXKf6+5l/7Bw=="
|
|
67
59
|
},
|
|
68
60
|
{
|
|
69
61
|
"name": "balance_of_public",
|
|
@@ -111,7 +103,7 @@
|
|
|
111
103
|
}
|
|
112
104
|
},
|
|
113
105
|
"bytecode": "JwACBAEoAAABBIBFJwAABEUnAgMEAScCBAQAHwoAAwAEAEMtCEMCJQAAAEAtAgJEJwIDBEQnAgQEATsOAAQAAx4CAAMJJwIEAQEkAgADAAAAVyUAAAEoKQIAAwDvUlNNJwIEAAErAgAFAAAAAAAAAAADAAAAAAAAAAAtCAEGJwIHBAUACAEHAScDBgQBACIGAgctCgcILQ4DCAAiCAIILQ4ECAAiCAIILQ4CCAAiCAIILQ4FCC0IAQInAgMEBQAIAQMBJwMCBAEAIgYCAwAiAgIEPw8AAwAEJwIDBAEAKgIDBC0LBAQnAgIAAAoqBAIDJwICAQAKKgMCBSQCAAUAAAEHJQAAAToeAgACAC8qAAQAAgADHAoDBAYcCgQCABwKAgMGLQoDAiYqAQABBdwbbuv7trxDPAQCASYqAQABBbq7IdeCMxhkPAQCASY=",
|
|
114
|
-
"debug_symbols": "
|
|
106
|
+
"debug_symbols": "nZbLrqMwDIbfJWsWtnN1X+XoqKItPUJCtOK0I40q3n0SirksEo26af465OOPbQIvdWlOz59j219vv+rw9VKnoe269ufY3c71o731MfpSkH6cUQddKcfqYCrlzTQEeg9eHRArxe49IuAsiETIlJYpLREjESMRCyKMCJ6F0yLCLLzcws8uMCSgTsLOgkHEHCEAERJBiWCyEXdFhCIkotM1Lgk7CyMRIxErERtmkTwTJREjlDg+AilNJatvMUXGsVKS+uNjaJqU+U0tYoXu9dD0D3Xon11XqT9195wu+r3X/TQ+6iHOQqWa/hLHCLy2XZPUWK2rIb8UQWOYl0dtVoTFHQPzDHapEBOCnaaVwDsClVwEJyYQeCF4+nQflNtHkWEcLQwTMMewBUZsDUEQ24UQ3I7g8gQKUk7NYVlPqHcAXyiHBrHA20Rg2HdFKCDAaEEAQxbBeYReCDpstmH2ACyUg9BLUxAG8xmDtNiIz3XBR6E5DXqpiCHwm2T8tw3NHpeies7aKDUWMktjaXC5xsICwgbJhYO1piF8+Hywzp4Vpe40XjrLU84EhpIL0sthAWR97rzBQncys18YgCZ7ZhXS4dAv+cSQtUGFk5O8nFnEJnfqlfdh14oAhawJXWhOa5fmdEBZG+Wa0KYmPv8OKHU4gzxnyLjmM76Zx/E7/q3P7bD7VhkTbGjrU9fMf6/P/ryZffy9y4x869yH27m5PIcmkdYPHoyv5i8bKgffY7rbPw=="
|
|
115
107
|
},
|
|
116
108
|
{
|
|
117
109
|
"name": "check_balance",
|
|
@@ -149,7 +141,7 @@
|
|
|
149
141
|
}
|
|
150
142
|
},
|
|
151
143
|
"bytecode": "JwACBAEoAAABBIBFJwAABEUlAAAARicCAwQBJwIEBAAfCgADAAQARBwAREQGLQhEAiUAAABsJwICBEUnAgMEADsOAAMAAiwAAEMAMGROcuExoCm4UEW2gYFYXSgz6Eh5uXCRQ+H1k/AAAAAmHgIAAwknAgQBASQCAAMAAACDJQAAAZUeAgADAQoiA0MEFgoEBRwKBQYABCoGAwUnAgMBAAoqBAMGJAIABgAAALYnAgcEADwGBwEpAgAEAO9SU00nAgYAASsCAAcAAAAAAAAAAAMAAAAAAAAAAC0IAQgnAgkEBQAIAQkBJwMIBAEAIggCCS0KCQotDgQKACIKAgotDgYKACIKAgotDgUKACIKAgotDgcKLQgBBCcCBQQFAAgBBQEnAwQEAQAiCAIFACIEAgY/DwAFAAYnAgUEAQAqBAUGLQsGBicCBAAACioGBAUKKgUDBCQCAAQAAAFhJQAAAaceAgAEAC8qAAYABAAFHAoFBgYcCgYEABwKBAUGDCoFAgQKKgQDAiQCAAIAAAGUJQAAAbkmKgEAAQUO/iBJ6zdOPDwEAgEmKgEAAQW6uyHXgjMYZDwEAgEmKgEAAQWEcoDChCMLRjwEAgEm",
|
|
152
|
-
"debug_symbols": "
|
|
144
|
+
"debug_symbols": "nZZbbuMwDEX34u98iKRezFaKonBTpzBgOIGbDDAIsvehGtGPAhKm+Ymu6fiYIq9k3ZqP7v36+daPx9NXs3+5Ne9TPwz959twOrSX/jRK9NaY9AMmNnvaNQDU7G0a42NE/xgJmn1Io1yzjBby6B5xZ/Io1wAivFGhkUAqYhYRRUQRDCr8QyCELBBU6C3SCGnEaiRl8xCchbMqYhaeVOgrAqoQIBoR0ahwWbBGOEfIGBUaAUkDIQmfBWoE03+kvkRGhUasRmzMwkmGyEmkpqTHvQAp3QqgQiMxRWwSPgvWCHMS9/uu0Ya/XaauS/1eOUB8cW6nbrw0+/E6DLvmTztcv//0dW7H7/HSTnJXptiNHzIK8NgPXVL33fK0KT/KEPRpBsYZ4GBDgArBJ8c8CJ5WBN4QsEwQi/tMADA8EwI+NwtbmkWNQBiVQK5YB1cmeGs5E7z1xTr4MoFmAHlbqkI1gxA0A4dcyiCWCRa1jBbcCvBUFT0U3VRtpVMCxhlgf9FIs6SAoZhCzY+yW6kfZVeZEdFvEVRGyD6lreRlFgi0JdjqPOZCkF3sBHG7tqFiCDaWlGHYlBlVUyqC4mom9gchVGoBQZc3QrTPMZA0DfncVPLgirmXTUJ8HlbV+O80iAPMfQ1cTqPmLmBd5kDGl9yFFYSLWgxvlq7G+NQa8VxaI1izp9WthgOWUkBX2/TllKB1MOhC8cNRMSczh5lhwBYZlZ56Of5oNSGW06hsmxi0nMjFjbs+D4fLPFb73o8kqNJUcm72pjdYTKPeE1z1JBQ/YlTzNxtdZnJ6XOop58Wn/Bm3n/NXuWoP/bQ5Kt8Ta+rb96HLl8freFjdvfw96x09ap+n06H7uE5dIq3O23JGexFHBPd6T2/7Bw=="
|
|
153
145
|
},
|
|
154
146
|
{
|
|
155
147
|
"name": "claim",
|
|
@@ -1329,7 +1321,7 @@
|
|
|
1329
1321
|
"name": "pk_m",
|
|
1330
1322
|
"type": {
|
|
1331
1323
|
"kind": "struct",
|
|
1332
|
-
"path": "
|
|
1324
|
+
"path": "aztec::protocol_types::point::Point",
|
|
1333
1325
|
"fields": [
|
|
1334
1326
|
{
|
|
1335
1327
|
"name": "x",
|
|
@@ -1999,9 +1991,9 @@
|
|
|
1999
1991
|
}
|
|
2000
1992
|
}
|
|
2001
1993
|
},
|
|
2002
|
-
"bytecode": "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25kc21kc29kc2zkc27kc2484tvM4tvM5tgs4tgs5tos4th9zbBdzbJdwbD/h2C7l2H7Ksf2MY0v6UtwXHNsvObZfcWy/5th+w7H9lmP7Hcd2Gcd2Ocf2e45tgGMrOLYrOLYrObarOLarObZrOLZrObY/cGx/5Niu49iu59hu4Nhu5Nhu4thu5thu4dhu5dhu49hu59ju4Nju5Nju4tju5tju4dju5dju49ju59j+xLE9wLE9qP5FKR3bQ5zVHubYHuHYHuXYHuPYHufYnuDYnuTY/syxPcWxPc2x/YVj+yvH9jeO7e8c2z84tn9ybP/i2P7Nsf2HY8vp22tz+vbanL69Nqdvr83p22tz+vbanL69Nqdvr83p22tz+vbanL69Nqdvr83p22tz+vbanL69Nqdvr53jvr1QTwg7XybSE4Lz0aKdn7OnAsiePJwvL9qcHsA2pwewzekBbHN6ANucHsA2pwewzekBbHN6ANucHsA2pwewzekBbHN6ANucHsA2pwewzekBbHN6ANucHsA2pwewzekBbHN6ANucHsA2pwewzekBbHN6ANucHsA2pwewzekBbHN6ANucHsA2pwewzekBbJfn2HJ6ANucHsA2pwewzekBbHN6ANucHsA2pwewzekBbHN6ANucHsA2pwewzekBbHN6ANsPUj6FtTk9gG1OD2Cb0wPY5vQAtjk9gG1OD2Cb0wPY5vQAtqtybKtxbKtzbB/l2Nbg2Nbk2HJ66dqcXro2p5euXYdjy+mla3N66dqcXro2p5euzemla3N66dqcXro2p5euzemla3N66dqcXro2p5euzemla3N66dqcXro2p5euzemla3N66dqcXro2p5euzemla3N66dqcXro2p5euzemla3N66dqcXro2p5euzemla3N66dqcXrp2OseW00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dO1Mji2nl67N6aVrc3rp2pxeujanl67N6aVrc3rp2pxeujbp6+icXro2p5euzemla3N66dqcXro2p5euzemla3N66dqcXro2p5euzemla3N66dqcXro2p5euzemla3N6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",
|
|
2003
|
-
"debug_symbols": "tZ3RjuzGkW3/Rc96qIjIjMj0rwwMQ+PRDAQIsqGxB7gw9O+3yMzN1T6DpsrdPS+ufazuWMwkYxVZzGb947v/+PHf//5ff/rpl//8y39/94d/+8d3//7rTz///NN//ennv/z5h7/99Jdfnv/vP757HP9j8d0fPH77/js7/2X13R/68x829utcr/7Yr7Zffb/Gfm37te/X3K+7nu96vuvFrhfPenm8Pn+/jte+X3O/1n59/v54vrYnbx6vbb/2/ZrrtT+3yx5HCIWm0BWeP2t2hFIYCnOHfCg8N9D8GeoIcYTj19sRSmEozB3GQ+H4rWOg4/itY6SjFIbC3GEev3WMdpqCK4RCU+gKR8FjbuZR8JiEOVfwx0PBFHxtjz/2ZvhjKOzNcHso7M1wc4VQaApdIRWeBf1xhLnDcfCsYAquEGvj/TiA3I7QFVKhFPYA3TXA0ABDAwwNMDTA0ABDA2waYNMAmwbYNMCmATYNsGmATQNsGmDXALsG2DXArgF2DbBrgF0D7Bpg1wC7BpgaYGqAqQGmBpgaYGqApQGWBlgaYGmApQGWBlgaYGmApQEODXBogEMDHBrg0ACHBjg0wKEBHsf8CnOH45hf4ajsR3CFUGgKXSEVSuGo7E+P+eGxc5h9j7LvQfY9xvO19uvYr8tL50D7Hmffw+x7lH0Psu8x9j3EvkeYezi1R1N7MLXHUnsox2QdLfrcm3F06Plq+9X361iyirMrj3B25RlMwZej4uzKMzSFrpAKtTwWRzcdHouzU9oRQqEpdIVUqHXUxdkpeYRQaApdYR9I0UphKMwd+kPBFPaBFKexj0k4jX2GVCiFsbcntRmpzUhtRqaCNiO1GanNKG2GOiXUKXEcOscRHsexs0IqlMJQmHvjxz6e4+yUM7hCKGiAQwMcGuDQAIcGODXAqQFODXBqgFMDnBrg3ANsj4eCKbjCHmB7dIVUKIWhsAfYbA+wmSm4QijsATbrCqlQCnuAzfcAmzeFrpAKe4DNh4IGGBpgaIChAYYGGBpgaIChAYYGGBpg0wCbBtg0wKYBtqbQFVJhG6mdbxNnmDucbxNnMAVXCIW2PRanx54/2I43vPUS66Wtl75enuD2/Pm2zt+++8NxMtePf5zDP3rl+fL8/1I/YL89/6UzwT/97dcffzz+y5tTw+cJ419/+PXHX/723R9++fvPP3//3f/88PPfzx/677/+8Mv5+rcffn3+1+e8/fjLfzxfnwX/86effzzSb9/z24/3fzW99i9nxfXrw179/V6u37e6fr/y1d//xKa3Q6jnL7cxQdfLm26P2AWesV0VnicEL5fwo4dWiec5y4dKtKE90PtjfqzEtRM+XKL74yrRPjYXVU0lauZnS4zH44Mlrp06zD9UYoRdJdqHtiIffrXFI9rHStTjKjH6h0rYY1zN6fbBEo0SH5rOdLu2wiM+P53jY1vxsGsrrH2wxOOzA3leh1wl8kM71R7Hu/VZwp6HCMpuL3uzD81myzfHd/9n6Xt7v8SYuSvMN7vjX9iEMh1WT3fNdzch3y8xH9cm2Bvl+etvHzXjev9406PfbsN4v8TzYluH9vNSmre/9H8uMW+GEY9+TWWjwZ4fXfxTjXjcTUXTSOZjPt6vYe/XiKvE85SX6WzfVPCbCg+/SjzCPlbDrr36vIhq79dod2/reb2JPJv+zWy8vhnZtVOeVy/xsaG8rVH1wRrXu/LzAss/VmOyW2be7Jb5fzulc7AZ8/3NuGtYWr7NfNdb7W4rnJ3ib7aij9dLtJQ9n1fI/b0St+OY1xnf483R9e04+o14+kMb8XxHqXdL3PhzXG8j482Ja//nvdHq7tx3XKeM/uZ8z/75BLzd+DOL9/Vq490Sd1vBBUzP6J8u8WYu/qUSNa4S82MlOue+vT42kPF4c/r8/h65OyqufTrfXEh8c1T0/umjouenj4rbrXjtqHi5xPtHxX2Jl46K2xKvHRW3JT5/VFi4Stjbk5RvbXFbYmqnWrN3D628eWN/3sSa11Y8xrunOXkzGZnXKXy9fx2Rdx3SNI4x3z+Bz5s2fX7Apo14fo52U+POnLNrM+px89nFXY3is5vqc3y6xtsPgP6lGuO6ZK8xHx+sEfOqUV9Q46Pb8XY+HvWx4yOuk5Tnp6HzYzX65Bqvv3/pX/X5Y+yuxqv79r7Ga/v25Rof3Y4X++XVGnfHx8s17nru9upZJZ47+d0K48akZoaO7XlX9v0qd28Lj2bX+8LjqcMPbovn9aGIPe/DvV/lpnfH80xBas8+Plgj51Xj5kPQ+9HEddn3zP39o3Xa3Uc0j7reqG4+mr6rMfmEfD739+dr+OOjNa7D1W4+eZufPzGdnz8xvR/J5eXpj/c77/Y86Hk7+DoPqnz3PGjeXNFXqcR4vDkD8fFyhTH4/O3xwQrXJ1/2sW2ouhr2g9tQtOtHR3Gd4390FPP6QGEO/2AFuyrUxypcpxwfrWCP69PxZxwf24rZXilx+8nInINPId/9kMjM7obSeWt7jLcfNY1vqvjddRd3TlBnzm8qxJ2y+nXhlu99uGzWPv/psln//MfLZvnZz5fN6vOfyv5Okdc+Ur0v8uJnquaPT3+o+jsb8tqnqrcHal5vJ8Pbuweq3xyos2kkM9u7B+rdDaUX353N+6ffnu+347UPjl6v8f4nR79T46WPju5rvPbZ0X2N1z48uj06ni5H6/G+yO5uH7x6fER8/vi43Y4Xj4+Xa9wcH/c1Xjs+bmu8eHzc1viS46M4Pt6M5dvjoz0+f3w0+/zxcbsdLx4fL9e4OT7ua7x2fNzWePH4uK3xFceHXetxnucpj/ePj/EFx8f8guNjfMHxMb7g+BhfcHyMLzg+xv/18cGtBX9zDfbt8XF3z+nV46PX54+P2+148fh4ucbN8XFf47Xj47bGi8fHbY2vOD68X5+X+Ju7Pt8eH/kF56f5Been+QXnp/kF56f5Been+QXnp/l/fX7ar/UYlvb++eltjedNlqvGzTFW8fn7m1btszc4rfpn73Ba5edvcdpX3H+yr7hpY19xx8W+4laYfcW9MPuKm2H2FXey7o+TF2913hd58V6n3d2Ievlguyvy8i6+L/LiLn65yIe35NXeebXI7XHycpHbBuyfvedps33FTU+7uxf1+l3P39maV2972qzP3/f8nSKv3fj8nQG9eufzXIr/2Vuft0Vevff5ehF/fLjIS3c//fH5E1h/fP4E9ncG89oN0PszpRfvgPpjfPYW6G2J1+6B/k6JV26C/s5AXrkLel/ipdug9wN56T7obYnXboT+TolX7oTel3jpVuhtiVfvhd5vx2s3Q29v7TxvDnY+Gsn370Le1XCazd+cBXxTw/3ur0uuO5ntzbmVzW/a1f3u+LqO8rf6+l8lbi+wrvtUz3dOf9dfd5vx5hgt/9hI5vV3R/+0Y/+lGs8Pyvub85CbIjfv2Xa9Jfibxd42vjlI7/4C6tV7w373N1Cv3Rv2uz+BevXe8O8Uee3e8H2RF+8N+92tqhfvDf/OhnzBveHnWSUrv9+ce/xLAgnOUpu/uxTC4/ZQvSbkeQb57me8HuPziyH87k+hXj7g7+6KvHjA392sevWv7e6LvPjndt6+4Fi93ZBX2/e+yKtLO+xerMXdyDcnl/3b8dTdOUReR8nbK+f/VeP21sj1Z9Nvbpr/r8PsbiuSv+bJWe9uRb/7c+PO8pBnznf/4O1uUVb49ffCT4m8++dq3u9WqTzi+tPpx5sL73h9K+J64302YH9/K24uo57nQtdf/LZ491613/1Bzsse6vkFHrq7Y/Wih/r4Ag/dFnnVQ/n59VT3G/Kqh14ucvOXv79T5MVzkdsir56L3N22+pJ5ffFc5LZ923Ut8/xk6H2J5O12XH/y/0Yh3zyt5nYjutW1Efn+QwPqVqkPv24W9bfPs/hWzGVfIObf2Ra7Pih+5rrZlptTgHZ9ptODC4l/4SFCfMLV7c1l6jGrf3z+64c///TrPz8z83iO1XFNeTzGKs7nOu7XuV6PRx228+GH+9X36/HoptjPbor98CY9vel4rWM0x4Pk9utcr8fTrc5X26++X2O/tv3a92vu110vdr3Y9dqu13a9tuu1Xa/tem3Xa7te2/Xartd2vb7r9V2v73p91+u7Xt/1+q7Xd72+6/VdL3e93PVy1zse83bc6Tye8na+9v16PH/vuQ+PR7ydr2O/zvV6PN/tfLX188fT3c7XXe98PuDx3/t+3fVq16tdr3a9seuNXW/semPXG3v7xt6+seuNXW/semPXm7ve8bzA89X3a+zXvX1z1zse+Xa+1n4d+3WuV3vsgvYwBVcIhabQFVKhFIaCKh8PflvBFFwhFFTZVNlU2VTZVNn2HKyHy7qeLut6vKzr+bKmB8yanjBresSs6RmzpofMup4y63rMrO/nzK6gyqHZCG1zaJtD2xyqHENBs9E0G02z0VS5qXJT5abKTZWbZqNpm5u2uWubuyp3zXPXbHTNRtdsdFXuqtxVuatyqnJqNlLbnNrm1Darwyw1z6nZSM1GajbUZudTcldQ5VJltZqp10zNZuo2U7udT9I9Kw/NszrO1HKmnrOhykOV1XamvjM1nqnzTK1n6j1T851P2z0rT82z+s/UgKYOPB+7u35rV3b1oKsHXT3o6kFXD7p60NWD56N5j8rno3lX2LPh6kFXD56P5j1/y1RZPejqQVcPunrQ1YOuHnT14PmM3rOyu0IoNIWuoMquyupBVw+6etDVg64edPWgqwc9VDlSQbOhHnT14Pkc3/O3miqrB1096OpBVw+6etDVg64ePB/oe1bummf1oKsHXT14PtD3/K2uyupBVw+6etDVg64edPWgqwdd73GuNzlXD7p60NWDrjc61zudqwddPejqQVcPunrQ1YOuHlxPxDU9Etf0TFzTQ3FNT8U1PRbX9Vxc14NxXU/GdT0a1/ezcVfQNqsHXT14Pi/3rDw1z+pBVw+6evB8+u/6LVVWD7p6MNSDoR4M9WCoB0M9GI9dOR6pUApDYc/G+SDe87dMldWDoR4M9WCoB0M9GOrBUA+GqbI/FEzBFUJBlV2V1YOhHgz1YKgHQz0Y6sFQD55P/z0rR1PQbKgHQz0YocqhyurBUA+GejDUg6EeDPVgqAfPJwSflZvmWT0Y6sFQD0ZX5a7K6sFQD4Z6MNSDoR4M9WCoByNVOTXP6sFQD4Z6MHSqGTrXDPVgqAdDPRjqwVAPhnow1IPnc4XPyqV5Vg+GejDUg6ETz/O5wiuosnow1IOhHgz1YKgHQz0YQ5Wn5lk9GOrBUA+GTkPPZw+voMrqwVAPhnqwqQeberCpB9tjVz4fQrxCV0iFUhj6LVVWDzb1YFMPNvVgUw829WBTD54PIT4r21DYs9HUg0092HQuej6oeAVVVg829WBTDzb1YFMPNvXg+aDis3K4gmZDPdjUg03noucTi1dQZfVgUw829WBTDzb1YFMPnk8sPis3zbN6sKkHm3qw6Vz0fGLxCqqsHmzqwaYebOrBph5s6sHWVTk1z+rBph5s6sGmc9GmHmx6H2x6H2zqwaZz0VaqrGu+ph5s6sGmHmx6H2xnD7YjHJWPp0efPXiGucPZg2cwBVcIhabQFVJBlYcqD1WeqjxVearyVOWpylOVpypPVZ6qPHfl/ngomIIrhEJT6AqpUApDQZVNlU2VTZXPHjw/FWgKXSGPz9GPUApDYe5w9OAKtn/r7MEzqPLRg+tnuoIquyq7KrsqhyqHKocqhyqHtjm0zaHKocqhyqHKTZWPHlzBFUJB29xU+ezBM5TCUJg7dFXuqtxVuatyV+Wu2eja5q5t7trmrspnD55Bs5GajdRspCqnKqcqpyqnKqdmo7TNpW0ubXOpcmmeS7NRmo3SbJQqlyoPVR6qPFR5aDaGtnlom4e2eajy0DwPzcbUbEzNxlTlqcpTlacqT1Wemo2pbZ57m/PxUNiV8+EKodAUukLqt0phKKiyqbKZgiuEQlNQZUuFUhgKezZSPZiuyq7KrsrqwVQPpnow1YOpHkxX5XgoaDbUg6kezFDlUGX1YKoHUz2Y6sFUD6Z6MNWD2VS5aZ7Vg6keTPVgNlVuqqweTPVgqgdTPZjqwVQPpnowuyp3zbN6MNWDqR7MVOVUZfVgqgdTPZjqwVQPpnow1YNZqlyaZ/VgqgdTPZilyqXK6sFUD6Z6MNWDqR5M9WCqB3Oo8tA8qwdTPZjqwZyqPFVZPZjqwVQPpnow1YOpHkz1YM5duR4PBVNwhVDYlevRFVKhFIbCno1SD5Z6sNSDpffB0vtgqQdLPVjqwdL7YOl9sNSDpR4s9WCpB0s9WOrBUg+Wq7IPBc2GerDUgxWqHKqsHiz1YKkHSz1Y6sFSD5Z6sJoqN82zerDUg6UerKbKTZXVg6UeLPVgqQdLPVjqwVIPVlflrnlWD5Z6sNSDlaqcqqweLPVgqQdLPVjqwVIPlnqwUpVL86weLPVgqQerVLlUWT1Y6sFSD5Z6sNSDpR4s9WANVR6aZ/VgqQdLPVhDlYcqqwdLPVjqwVIPlnqw1IOlHqypylPzrB4c6sGhHhyPXXk8QqEpdIVUKIWhsLd5qAeHqbK5Qig0ha6gyjoXHerBoR4c6sGhHhzqwaEeHOrB4arsqVAKQ0GzoXPREaqsHhzqwaEeHOrBoR4c6sGhHhyhyk3zrB4c6sGhHhw6Fx1NldWDQz041INDPTjUg0M9ONSDo6ty1zyrB4d6cKgHh85FR1dl9eBQDw714FAPDvXgUA8O9eBIVU7Ns3pwqAeHenDoXHSUKqsHh3pwqAeHenCoB4d6cKgHx1DloXlWDw714FAPDp2LjqHK6sGhHhzqwaEeHOrBoR4c6sExVXlqntWDQz041INT56LzYQquEApNoSukQikMBVW2h4IpuEIoqLJ6cOp9cOp9cKoHp85Fp6uyrgenenCqB6d6cOp9cJ7vg36EY5vP3xoKc4ezB89gCq4QCk2hK6SCKocqhyo3VW6q3FT56MFjhcU8enCFrpAKpTAU5g5HD65gCq6gyl2Vuyp3Ve6q3FX56MHjb1Lm0YMrmIIrhEJT6AqpUApD4ag8jrvVDwU7/s73CK4QCk2hK6RCKQyFucPRgyuo8lDlocpDlYcqD1U+evBYRDKPHlxh7nD04ArHd/PVEVwhFJpCV0iFUhgKc4XjrzSuZFfyK8WV2pX6lfJKdaVxpYthF8Muhl0Muxh2Mexi2MWwi2EXwy6GXwy/GH4x/GL4xfCL4RfDL4ZfDL8YcTHiYsTFiIsRFyMuRlyMuBhxMc5vfDtWRNnj/EbQHY3o5x9snDGIjdiJSSziIM4rnt99uKMRoXVoHVqH1qF1aB1ah5bQElpCS2gJLaEltISW0BJaQStoBa2gFbSCVtAK2vkdu8dfhDzjvOL5Pbs7nrR5RicGsRE7MalQRGjnt/Ounz2/n3dHaBPahDahTWgT2oQ2oc1rbOdKHsWLdq7mUQxiI3ZiEos4iNfYztU9m3Z+R+COTgxiI0IzaAbNoBk0fxAZmzM2Z2wO7fxiyB2TWMRBhBbQAlpAC2jBTAZjC8YWjC2gBfutMZONmWzMZIPWoDVoDVqD1pjJxtg6Y+uMrUPr7LfOTHZmsjOTHVqH1qEltISWzGQytmRsydgSWrLfkplMZrKYyYJW0ApaQStoxUwWYyvGVowNl6xv7d6RmRzM5GAmccn6ju8doQ1ouMRwieESwyWGS9Z3fi/aZL/hEsMlhkvW14CfFdYXge9oRCcGsRE7MYlFvGjr68NXxCWOSxyXrK8RXxUMGi5xXOK4xHGJ4xLHJY5L3KF5EBuxE5MIzaHhEscljksclzgucVziuMQDWhSRmcQljkvWd5WvCg0aLnFc4rjEcYnjEscljku8Q+vsN1ziuMRxiXdoHRoucVziuMRxieMSxyWOSzyhJfsNlzgucVyyvhB9VShouMRxieMSxyWOSxyXOC5xzkuc8xLHJY5LHJc45yXOeYnjEscljksclzgucVziuMQntMl+wyWOSxyX+IQ2oeGSwCWBSwKXBC4JXBK4JB4XLR5FHMRrJgOXrC8+XxUMGi4JXBK4JHBJ4JLAJYFLwqG5EZ0YxEaE5tBwSeCSwCWBSwKXBC4JXLK+m33RohOZSVwSuCQCWoOGSwKXBC4JXBK4JHBJ4JL13e6L1thvuCRwSeCS9XXvq0KHhksClwQuCVwSuCRwSeCSSGjJfsMlgUsCl6yvi98VoOGSwCWBSwKXBC4JXBK4JApasd9wSeCSwCXBNU5wjRO4JHBJ4JLAJYFLApcELokJbbLfcEngksAlwTXO+lb6HaHhksAlDZc0XNJwScMl7XHR2qMTk1jEQYRm0HBJwyUNlzRc0nBJwyUNl6yvsl80u/ZbwyUNlzRc0rjGWV99vyM0XNJwScMlDZc0XNJwSQtoEURmEpc0XNK4xmkBDZc0XNJwScMlDZc0XNJwSWvQGvsNlzRc0nBJ4xqndWi4pOGShksaLmm4pOGShktaQkv2Gy5puKThksY1TktouKThkoZLGi5puKThkoZLWkEr9hsuabik4ZLGNU7DJY3zksZ5ScMljWucNqDxeUnDJQ2XNFzSOC8517Wdj1O2c2WbHV+ka+faNsVG7MQkFnEQp+K50k3RiE4MYiN2YhKLOIjQDJpBM2gGzaAZNINm0AyaQXNoDs2hOTSH5tAcmkM7XXL8Oaeda+R2PF2y40mrMzoxiI3YiUmFIkI7XbJ+9nTJjtAatAatQWvQGrQGrUFrjK0ztg6tQ+vQOrQO7XTJjkUcRMaW0E6X7OjEIDYitISW0BJaQitmshhbMbZibAXtdMmOzGQxk8VMFrQBbUAb0Aa0wUwOxjYY22BsA9pgv01mcjKTk5mc0Ca0CW1Cm9AmMzmvseXjQTTiRctHEBuxE5NYVBhEaAbNoJkTg9iInQjNijiI10ymP4jQHJpDc2gOzZPI2JyxOWPDJRlGZCaDmQxmEpdkQAtoAQ2XJC5JXJK4JHFJNmiN/YZLEpckLskGrUPDJYlLEpckLklckrgkcUl2aJ39hksSlyQuyYSW0HBJ4pLEJYlLEpckLklckgWt2G+4JHFJ4pIsaAUNlyQuSVySuCRxSeKSxCU5oA32Gy5JXJK4JCe0CQ2XJC5JXJK4JHFJ4pLEJfW4aPUwohOD2IidCkks4iBCwyWFSwqXFC4pg2admMQiDiI0h4ZLCpcULilcUrikcEnhkuK8pDgvKVxSuKRwSXFeUpyXFC4pXFK4pHBJ4ZLCJYVLqkFr7DdcUrikcEk1aA0aLilcUrikcEnhksIlhUuqQ+vsN1xSuKRwSSW0hIZLCpcULilcUrikcEnhkipoxX7DJYVLCpdUQStouKRwSeGSwiWFSwqXFC6pAW2w33BJ4ZLCJTWgTWi4pHBJ4ZLCJYVLCpcULqkJbV77beCSgUsGLhmPizYejdiJSSziIF5jG7hk4JJh0CyIjdiJSYRm0HDJwCUDlwxcMnDJwCUDlwyH5kUcRGYSlwyucQbXOAOXDFwycMnAJQOXDFwycMlo0Br7DZcMXDJwyeAaZzRouGTgkoFLBi4ZuGTgkoFLRofW2W+4ZOCSgUsG1zgjoeGSgUsGLhm4ZOCSgUsGLhkJLdlvuGTgkoFLBtc4o6DhkoFLBi4ZuGTgkoFLBi4ZA9pgv+GSgUsGLhlc44wBDZcMXDJwycAlA5cMXDJwyZjQJvsNlwxcMnHJ5BpnPpwYxEbsxCQWcRCvsU2DZkZ0YhAbEZpBwyUTl0xcMnHJxCUTl0xcMh2ad2ISiziI0HDJ5Lxkcl4yccnkGmcGND4vmbhk4pKJSybnJXO5ZJ7xoB1foGLn+lLFRuzEJBZxEOcVT5fsaERoHVqH1qF1aB1ah9ahJbSEltASWkJLaAktoSW0hFbQClpBK2gFraAVtIJ2uuR4qped61R3PF2y40k7Hxt2umTHIDZiJyYVigjtdMn62dMlO0Kb0Ca0CW1Cm9AmtAltamx+LmhVFM3PJa2KQWzETkxiEQdxXtGgnS7Z0YlBbERoBs2gGTSD5g8iY3PG5ozNoZ0u2TGJRRxEaAEtoAW0gBbMZDC2YGzB2AJasN8aM9mYycZMNmgNWoPWoDVojZlsjK0zts7YOrTOfuvMZGcmOzPZoXVoHVpCS2jJTCZjS8aWjC2hJfstmclkJouZLGgFraAVtIJWzGQxtmJsxdgGtMF+G8zkYCYHMzmgDWgD2oA2oE1mcjK2ydgmY5vQJvttMpOTmZzM5Lxoa93rjkZ0YhAbsROTWMSLtta9rohLDJcYLlnrXlcFg4ZLDJcYLjFcYrjEcInhkrXuddE8iI3YiUmE5tBwieESwyWGSwyXGC4xXGIBLYrITOISwyVr3euq0KDhEsMlhksMlxguMVxiuGSte120zn7DJYZLDJesda+7AjRcYrjEcInhEsMlhksMl6x1r4uW7DdcYrjEcMla97oqFDRcYrjEcInhEsMlhksMl1hBK/YbLjFcYrjEBrQBDZcYLjFcYrjEcInhEsMla93rok32Gy4xXGK4ZK173RWg4RLHJY5LHJc4LnFc4rhkrXs9aWvd646DeM2k45K17nVVMGi4xHGJ4xLHJY5LHJc4LlnrXhfNjejEIDYiNIeGSxyXOC5xXOK4xHGJ45K17nXRohOZSVziuGSte10VGjRc4rjEcYnjEscljkscl6x1r4vW2G+4xHGJ45K17nVV6NBwieMSxyWOSxyXOC5xXLLWvS5ast9wieMSxyVr3euuAA2XOC5xXOK4xHGJ4xLHJWvd66IV+w2XOC5xXOID2oCGSxyXOC5xXOK4xHGJ45K17nXRJvsNlzgucVziE9qEhksclzguCVwSuCRwSeCSte71pK11rzsmsYiDCM2g4ZLAJYFLApcELglcErhkrXtdNLv2W+CSwCWBS4JrnLXudUdouCRwSeCSwCWBSwKXrHWvixZBZCZxSeCS4BpnrXvdERouCVwSuCRwSeCSwCVr3euiNfYbLglcErgkuMZZ6153hIZLApcELglcErgkcMla97poyX7DJYFLApcE1zhr3euO0HBJ4JLAJYFLApcELlnrXhet2G+4JHBJ4JLgGidwSXBeEpyXBC4JrnHWutcdoeGSwCWBS4LzkrXu9fh+E1/rXo+vKfG17nXHRuzEJBZxEKfiWve6oxGdGMRG7MQkFnEQoRk0g2bQDJpBM2gGzaAZNIPm0ByaQ3NoDs2hOTSHdrrkfMjrWve64umSHU/a+ZD90yU7BrEROzGpUERop0vWz54u2RFag9agNWgNWoPWoDVojbF1xtahdWgdWofWoZ0u2bGIg8jYEtrpkh2dGMRGhJbQElpCS2jFTBZjK8ZWjK2gnS7ZkZksZrKYyYI2oA1oA9qANpjJwdgGYxuMbUAb7LfJTE5mcjKTE9qENqFNaBPaZCbnNba17nVHI160te51x0bsxCQWFQYRmkEzaObEIDZiJ0KzIg7iNZNr3euO0ByaQ3NoDs2TyNicsTljwyVr3euOzGQwk8FM4pK17nVHaAENl3Rc0nFJxyUdl6x1r4vW2G+4pOOSjkvWutdVoUPDJR2XdFzScUnHJR2XdFyy1r0uWme/4ZKOSzouWeteV4WEhks6Lum4pOOSjks6Lum4ZK17XbRiv+GSjks6LlnrXncFaLik45KOSzou6bik45KOS9a610Ub7Ddc0nFJxyVr3euqMKHhko5LOi7puKTjko5LOi5Z615P2lr3uqMTg9iInQpJLOIgQsMliUsSlyQuWeteF806MYlFHERoDg2XJC5JXJK4JHFJ4pLEJcl5SXJekrgkcUnikuS8JDkvSVySuCRxSeKSxCWJSxKXrHWvi9bYb7gkcUnikrXudVeAhksSlyQuSVySuCRxSeKSte510Tr7DZckLklcsta9rgoJDZckLklckrgkcUniksQla93rohX7DZckLklcsta97grQcEniksQliUsSlyQuSVyy1r0u2mC/4ZLEJYlL1rrXVWFCwyWJSxKXJC5JXJK4JHHJWve6aPPab4VLCpcULlnrXs8Ka93rjp2YxCIO4jW2wiWFS9a610WzIDZiJyYRmkHDJYVLCpcULilcUrikcMla97poXsRBZCZxSXGNU1zjFC4pXFK4pHBJ4ZLCJYVL1rrXRWvsN1xSuKRwSXGNs9a97ggNlxQuKVxSuKRwSeGSte510Tr7DZcULilcUlzjrHWvO0LDJYVLCpcULilcUrhkrXtdtGS/4ZLCJYVLimucte51R2i4pHBJ4ZLCJYVLCpesda+LNthvuKRwSeGS4hpnrXvdERouKVxSuKRwSeGSwiVr3euiTfYbLilcMnDJ4BpnrXvdMYiN2IlJLOIgXmNb614XzYzoxCA2IjSDhksGLhm4ZOCSgUsGLhm4ZK17XTTvxCQWcRCh4ZLBecngvGTgksE1zlr3uiM0XDJwycAlg/OSte71+IJSX+tej6/t9LXudcdG7MQkFnEQ5xWXS1Y0IrQOrUPr0Dq0Dq1D69ASWkJLaAktoSW0hJbQElpCK2gFraAVtIJW0ApaQTtdcjwv09e61xVPl+x40PL80qfTJTsGsRE7MalQRGinS9bPni7ZEdqENqFNaBPahDahTWjzGtta97rjRVvrXncMYiN2YhKLOIjX2Na610U7XbKjE4PYiNAMmkEzaAbNH0TG5ozNGZtDO12yYxKLOIjQAlpAC2gBLZjJYGzB2IKxBbRgvzVmsjGTjZls0Bq0Bq1Ba9AaM9kYW2dsnbF1aJ391pnJzkx2ZrJD69A6tISW0JKZTMaWjC0ZW0JL9lsyk8lMFjNZ0ApaQStoBa2YyWJsxdiKseGSte51R2ZyMJODmcQla93rjtAGNFwyccnEJROXTFyy1r0u2mS/4ZKJSyYuWetejwqx1r3uaEQnBrEROzGJRRQt1rrXFS+XxONySTwul8Ra97oqGDSDZtAM2uWSeBhjc8bmjM2heRAbsROTCM2hObSAFtCCmQzGFowtGFtAiyIyk8FMNmayQWvQGrQGrUFrzGRjbI2xNcbWoXX2W2cmOzPZmckOrUPr0Dq0Di2ZyWRsydiSsSW0ZL8lM5nMZDKTCa2gFbSCVtCKmSzGVoytGFtBK/bbYCYHMzmYyQFtQBvQBrQBbTCTg7FNxjYZ24Q22W+TmZzM5GQmJ7QJDZcYLjFcYrjEcInhEsMla93rSVvrXnccxGsmDZesda+rgkHDJYZLDJcYLjFcYrjEcMla97pobkQnBrERoTk0XGK4xHCJ4RLDJYZLDJesda+LFp3ITOISwyVr3euq0KDhEsMlhksMlxguMVxiuGSte120xn7DJYZLDJdYh9ah4RLDJYZLDJcYLjFcYrhkrXtdtGS/4RLDJYZL1rrXXQEaLjFcYrjEcInhEsMlhkvWutdFK/YbLjFcYrjEBrQBDZcYLjFcYrjEcInhEsMla93rok32Gy4xXGK4xCa0CQ2XGC4xXOK4xHGJ4xLHJWvd60lb6153TGIRBxGaQcMljksclzgucVziuMRxyVr3umh27TfHJY5LHJe4Q3NouMRxieMSxyWOSxyXOC5Z614XLYLITOISxyUe0AIaLnFc4rjEcYnjEscljkvWutdFa+w3XOK4xHGJd2gdGi5xXOK4xHGJ4xLHJY5L1rrXRUv2Gy5xXOK4xBNaQsMljksclzgucVziuMRxyVr3umjFfsMljkscl3hBwyXOeYlzXuK4xAe0AW1AwyWOSxyXOOcla91rxhlPWp4xiI3YiUks4iBOxbXudUcjOjGIjdiJSSziIEIzaAbNoBk0g2bQDJpBM2gGzaE5NIfm0ByaQ3NoDm25ZJxxXnG5ZMWTNs/oxCA2YicmFYoIbbnk/NnlkhWhNWgNWoPWoDVoDVqD1hhbZ2wdWofWoXVoHdpyyYpFHETGltCWS1Z0YhAbEVpCS2gJLaEVM1mMrRhbMbaCtlyyIjNZzGQxkwVtQBvQBrQBbTCTg7ENxjYY24A22G+TmZzM5GQmJ7QJbUKb0Ca0yUzOa2xr3euORrxoa93rjo3YiUksKgwiNINm0MyJQWzEToRmRRzEaybXutcdoTk0h+bQHJonkbE5Y3PGhkvWutcdmclgJoOZxCVr3euO0AIaLmm4pOGShksaLlnrXhetsd9wScMlDZesda+rQoeGSxouabik4ZKGSxouabhkrXtdtM5+wyUNlzRcsta9rgoJDZc0XNJwScMlDZc0XNJwyVr3umjFfsMlDZc0XLLWve4K0HBJwyUNlzRc0nBJwyUNl6x1r4s22G+4pOGShkvWutdVYULDJQ2XNFzScEnDJQ2XNFyy1r2etLXudUcnBrEROxWSWMRBhIZLOi7puKTjkrXuddGsE5NYxEGE5tBwScclHZd0XNJxScclHZd0zks65yUdl3Rc0nFJ57ykc17ScUnHJR2XdFzScUnHJR2XrHWvi9bYb7ik45KOS9a6110BGi7puKTjko5LOi7puKTjkrXuddE6+w2XdFzSccla97oqJDRc0nFJxyUdl3Rc0nFJxyVr3euiFfsNl3Rc0nHJWve6K0DDJR2XdFzScUnHJR2XdFyy1r0u2mC/4ZKOSzouWeteV4UJDZd0XNJxScclHZd0XNJxyVr3umjz2m+JSxKXJC5Z617PCmvd646dmMQiDuI1tsQliUvWutdFsyA2YicmEZpBwyWJSxKXJC5JXJK4JHHJWve6aF7EQWQmcUlyjZNc4yQuSVySuCRxSeKSxCWJS9a610Vr7DdckrgkcUlyjbPWve4IDZckLklckrgkcUnikrXuddE6+w2XJC5JXJJc46x1rztCwyWJSxKXJC5JXJK4ZK17XbRkv+GSxCWJS5JrnLXudUdouCRxSeKSxCWJSxKXrHWvizbYb7gkcUnikuQaZ6173REaLklckrgkcUniksQla93rok32Gy5JXFK4pLjGWetedwxiI3ZiEos4iNfY1rrXRTMjOjGIjQjNoOGSwiWFSwqXFC4pXFK4ZK17XTTvxCQWcRCh4ZLivKQ4LylcUlzjrHWvO0LDJYVLCpcU5yVr3evx3bix1r3WWeF0yY6N2IlJLOIgziueLtnxoI3HGZ0YxEbsxCQWcRDnFU+X7AgtoSW0hJbQEtrpktHPOIiMrRjb6ZIdmcliJouZLGaymMliJouZLGgD2oA2oA1oA9qANhjbYCYHMzmYyclMTmZyMpOTmZzM5GQmJ7QJbUKbF22te93RiK5ZX+tez1Gsda87dmISiziI10yuda87GtGJ0AyaQTNoBs2gGTRnbM7Y3IlBbMROTGIRB5GZDGgBLaAFtIAW0E6XrFk/XTLqjIM4r3i6ZEcjOjGIjdiJB23GGYs4iPOKp0t2NKITg9iInQitQ+vQOrSEltAOlzzvNZ4xiO2IecZOTGIRB3Fe8XCJohGdGERoBa2gFbSCVtAGtAFtQBvQBrQBbUAb0Aa0AW1Cm9AmtAltQpvQJrQJbUKbF+1c96poRCcGsRE7MYlFHERoBs2gHS553sA940HzdsZG7MQkFnEQ5xUPlyga0YnQHJpDc2gOzaE5tIAW0AJaQAtoAS2gBbSAFtAatAatQWvQGrQGrUFr0Bq0Bq1DO1zisaITg9iInZjEIg7ivOLhEkVoCS2hJbSEltASWkJLaAWtoBW0glbQClpBK2gFraANaAPagDagDWgD2oA2oA1oA9qENqFNaBPahDahTWgT2oQ2RWvnuldFIzoxiI3YiUks4iBCM2gGzaAZNINm0AyaQTNoBs2hOTSH5tAcmkNzaA7NoTm0gBbQAlpAC2gBLaAFtIAW0Bq0Bq1Ba9AatAatQWvQGrQGrUPr0Dq0Dq1D69A6tA6tQ+vQElpCS2gJLaEltISW0BJaQitoBa2gFbSCVtAKWkEraAVtQBvQBrQBbUAb0Aa0AW1AG9AmtAltQpvQJrQJbUKb0CY0XGK4xHCJ4RLDJYZLDJcYLjFcYrjEcInhEsMlhksMlxguMVxiuMRwieESwyWGSwyXGC4xXGK4xHCJ4RLDJYZLDJcYLjFcYrjEcInhEsMlhksMlxguMVxiuMRwieESwyWGSwyXGC4xXGK4xHCJ4RJbLskzHrS2/t8gNmInHrQ2z3jQup1xEA9anvF0yY5GdOJBy3MbTpfseNDyRJwuKT9jEQ9atd++/+5/fvj1px/+/ecf//u7P/zj+c///Psvf/7bT3/5Zf/zb//vr/ov//7rTz///NN//emvv/7lzz/+x99//fFPP//lz8d/+86O/3lu6L+F1fcR/Y/PN+nnv57t8P3zIH3+6zjA/y0e/ft41B+fpVy/8LzJ/P3zFu3+BU///rl9+oXnXfDvn/e8j1+I4xfiLPJ9exz/T9f/4/FE/vG3337742//Hw==",
|
|
2004
|
-
"verification_key": "
|
|
1994
|
+
"bytecode": "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",
|
|
1995
|
+
"debug_symbols": "tZ3djiXHca3fhde82BGRGZGpVzEEgZJpgwBBCbRk4EDgu59dlbnqa9Homu3u9g1rzXB6rcroiq/rJ7r2P7/79x///I///NNPv/zHX//ruz/82z+/+/OvP/3880//+aef//qXH/7+019/ef7tP797HP+x9t0fPH77/js7/2T13R/68w829naurT/21vbW9zb2tu1t39vc2+3n28+3X2y/ePrlsX1+fR3bvre5t7W3z68fz2175s1j2/a2722ubX/ulz0OERJNoks8/63ZIUpiSMwt8iHx3EHzp6hDxCGOL2+HKIkhMbcYD4njq46FjuOrjpWOkhgSc4t5fNWx2mkSLhESTaJLHIZHbeZheBRhziX88ZAwCV/744+9G/4YEns33B4SezfcXCIkmkSXSImnoT8OMbc4Dp4lTMIlYu28HweQ2yG6REqUxF6guxYYWmBogaEFhhYYWmBogU0LbFpg0wKbFti0wKYFNi2waYFNC+xaYNcCuxbYtcCuBXYtsGuBXQvsWmDXAlMLTC0wtcDUAlMLTC2wtMDSAksLLC2wtMDSAksLLC2wtMChBQ4tcGiBQwscWuDQAocWOLTA45hfYm5xHPNLHM5+CJcIiSbRJVKiJA5nf3LMD46dy+x7lX0vsu81ntva27G3i0vnQvteZ9/L7HuVfS+y7zX2vcS+V5h7ObVXU3sxtddSeylHsY4WfX434+jQc2t763s7Fqzi7MpDnF15CpPwxag4u/IUTaJLpEQtjsXRTQfH4uyUdoiQaBJdIiVqHXVxdkoeIiSaRJfYB1K0khgSc4v+kDCJfSDFSeyjCCexT5ESJTH2/qR2I7Ubqd3IlNBupHYjtRul3VCnhDoljkPnOMLjOHaWSImSGBJz7/zYx3OcnXIKlwgJLXBogUMLHFrg0AKnFji1wKkFTi1waoFTC5x7ge3xkDAJl9gLbI8ukRIlMST2ApvtBTYzCZcIib3AZl0iJUpiL7D5XmDzJtElUmIvsPmQ0AJDCwwtMLTA0AJDCwwtMLTA0AJDC2xaYNMCmxbYtMDWJLpESmwitfPHxCnmFuePiVOYhEuERNsci5Njz3/Yjh94axNr09amr80zuD3/fVvnb9/94TiZ68cfzuUfvfLcPP8u9Q/st+efdCb4p7//+uOPx/95c2r4PGH82w+//vjL37/7wy//+Pnn77/77x9+/sf5j/7rbz/8cm7//sOvz//7rNuPv/z7c/s0/I+ffv7xUL99z1c/3v/S9NpfnBXXlw979et7ub7e6vr6yle//hO73g6gnl/cxiS6Xt51e8Q2eMp2OTxPCF628KOHlsXznOVDFm3oO9D7Y37M4vomfNii++OyaB+rRVWTRc38rMV4PD5ocX1Th/mHLEbYZdE+tBf58KstHtE+ZlGPy2L0D1nYY1zN6fZBi4bFh8qZbtdeeMTnyzk+thcPu/bC2gctHp9dyPM65LLID31TrT9yWzyvl2n20V7mZh+qZss3x3f/V+h7u9mJuKBlz1OAj+xEmQ6sJ73muzuR71uM69sx7M13w1//AVIzrp8gb7r09/sw3rd4Xm7r4H5eTPMDMP1fLeb7FjMefVvM52n9ZfG8efEvHnGzkvloWsl8zMf7Hva+R1wWz5Neytl+5+A3Dg/TUfG8gOof87Dru/q8nrrxaHcnBhc62/MGy5tqvL4b2dRlzwuZ9rGlZB+XR36wpHmd5ER6fMxjXq32vHiZ73vM/9uSzrqWMuv93bhr2Hmxr818l1ztbi+e9320F8+7A1iM1y1aip/Pa+T+nsXtOuZ1zvfIeHcd/QY8/aGdeP5MqXct7vhpqsR4c+ra//W70eru7LfGdfY7aRL711PwdsPPrOu8M6vluxZ3e/H8oaq9yDc/lj9q0exjFpWXxfyYRX9zGl8fW8i4joqnfP87cndUjAc/Sd47Knr/9FHR89NHxe1evHZUvGzx/lFxb/HSUXFr8dpRcWvx+aPCwvUzxN6epPyeFrcW069zRnv30Mq7087n/eFrLx7j3dOcvClGJofW+1cSedchTesY8/1T+Lxp0+ctNn6a3lzb5R05Z9du1OPm7sWdR3FsVZ/j0x5vbwH9rzzGddFeYz4+6BHz8qgv8Pjofrytx6M+dnzEdZLyvB86P+bRJ1d5/f2L/6rPH2N3Hq9+b+89Xvvevuzx0f14sV9e9bg7Pl72uOu5vLtklMXzm/yuw7ghqZmBY/P2/i2/cfdj4dHs+rnweOLwg/vi2a99CXv/7sy46d2RcZ0SPy/ePuiR8/K4uQ16v5q4ToCeur9/tM6bC/rnUV7XD6qbm9N3HpN75PP5/f68hz8+6nEdrnZz721+/sR0fv7E9H4lF5enP97vvNvzoOcD4es8qPLd86B5c0Vf15npeLw5A/HxssMYeX1LHh90uO582cf2oepq2A/uQ9GuH13FdVh9dBXzuqEwh3/QwS6H+pjDdcrxUYfnnbsLWo83Z+f/q72Y7RWL2zsjc1633R7x7k0iM7tbSudH22O8vdU0fufid9ddPDsBnTl/5xB3yLquQEe+d3PZrH3+7rJZ//ztZbP87P1ls/r8XdlvmLx2S/Xe5MV7quaPT99U/caOvHZX9fZAzevHyfD27oHqNwfqbCrHzPbugXr3SOnFn87m/dM/nu/347UbR697vH/n6BseL906uvd47d7RvcdrN49uj44ny8F6vA+yu8cHrx4fEZ8/Pm7348Xj42WPm+Pj3uO14+PW48Xj49bjS46P4viY8e7x0R6fPz6aff74uN2PF4+Plz1ujo97j9eOj1uPF4+PW4+vOD7smsh5nqc83j8+xhccH/MLjo/xBcfH+ILjY3zB8TG+4PgY/9fHB48W/M012O+Pj7tnTq8eH70+f3zc7seLx8fLHjfHx73Ha8fHrceLx8etx1ccH96v+yX+5qnP74+P/ILz0/yC89P8gvPT/ILz0/yC89P8gvPT/L8+P+3XPIalvX9+euvxfMhyedwcYxWff75p1T77gNOqf/YJp1V+/hGnfcXzJ/uKhzb2FU9c7CsehdlXPAuzr3gYZl/xJOv+OHnxUee9yYvPOu3uQdTLB9udycvf4nuTF7/FL5t8eE9e7Z1XTW6Pk5dNbhuwf/aZp832FQ897e5Z1OtPPb+xN68+9rRZn3/u+Q2T1x58fmNBrz75PIfxP/vo89bk1Wefr5v448MmLz399MfnT2D98fkT2G8s5rUHoPdnSi8+AfXH+Owj0FuL156BfsPilYeg31jIK09B7y1eegx6v5CXnoPeWrz2IPQbFq88Cb23eOlR6K3Fq89C7/fjtYeht492ng8HO7dG8v2nkHceTrP5m7OA33m43/12yXXF2d5epM3ftav73fEF08eNxe0FVhvXSvJ9ft3txszrUVd9cCVzvjk4+sc8njfKnfMQuzG5+Zlt17C3vxn2tvG7g/TuN6BefTbsd78D9dqzYb/7FahXnw1/w+S1Z8P3Ji8+G/a7R1UvPhv+xo58wbPh51klk99vzj3+VwAJzlKbvzsK4XF7qF599zyDfPcer8f4/DCE3/0q1MsH/N1TkRcP+LuHVa/+tt29yYu/buftC47V2x15tX3vTV4d7bid/Zm9eBr55uSy/349dXcOkddR8vbK+X943D4auX5x+s1D8/9xmN3tRfLbPDnr3b3ot79wnHTeU7/7C293Q1nh8/r2xvu/rub9bkrl0fgt8M5uxOt7Edcv/D4bsL+/FzeXUc9zoes3flu8+6za734h52UO9fwCDt09sXqRQ318AYduTV7lUH5+nup+R17l0L3Ja7/5+w2TF89Fbk1ePRe5e2z1JXV98Vzktn3bdS3zvDP0PkTydj+uX/l/c//id++rud2JzuHe8/2XBtT9Oxz8eljU377R4vdgLvsCMH9jX+y6UfzUdbMvd6cA18VIjzevg3j9NULc4er25jL1qOofn3/64S8//fqvb8083mR1XFMeL7KK882OezvX9njZYTtff7i3vrfHy5tiv70p9uub9P6mY1vHao5Xye3tXNvj/Vbn1vbW9zb2tu1t39vc2+0X2y+2X9t+bfu17de2X9t+bfu17de2X9t+bfv17de3X99+ffv17de3X99+ffv17de3X26/3H65/Y4XvR1POo/3vJ3bvrfHG/ie38PjJW/nduztXNvjDW/n1ta/P97vdm633/mGwOP/973dfrX9avvV9hvbb2y/sf3G9ht7/8bev7H9xvYb229sv7n9jjcGnlvf2+03t9/cfsdL385t7e3Y27m29tiG9jAJlwiJJtElUqLkMyTkfLz6bQmTcImQkLPJ2eRsJTEkdg3W62Vd75c1vWDW9IZZ0ytmTe+YNb1k1vSWWdNrZl3vmXW9aNb3m2aXUDVC1Qjtc8g55BxyDlUjVI2majTtc5Nzk3OTc1M1mqrRVI2mfW5y7nLucu6qRlc1uqrRtc9dzl3OXc5d1UhVI1WN1D6rv0wNZuowS1UjVY1UNVL7rDY735O7hJxL1VCrmXrN1Gznu3SXj5xLzkPVUMeZWs7UczbkPOSstjP1nanxTJ1nar3zfbunz5Szus/Ufqb+MzWgqQPPF+8un+3s6kFXD7p60NWDrh70x3b2R0qUxJDY1XD1oKsHz5fznj4mZ/WgqwddPejqQVcPnm/pPX1czupBVw+6etDVg64ePN/Se/q4nNWDrh509aCrB1096CHnkLN60NWDrh509aCrB883+Z4+Tc7qQVcPunrQ1YOuHvQm5yZn9aCrB1096OpBVw+er/Q9fbqc1YOuHnT1oKsHXT14vtL39Ek5qwddPejqQVcPunrQ9YPO9ZPO1YOuHnT1oKsHXT243ohreiWu6Z24ppfimt6Ka3otrum9uKYX47rejOt6Na7r3biul+P6fjvuEtrnIecpZ/WgqwddPejqQVcPnu//PX2mnNWDrh4M9WCoB0M9GI/tHI8m0SVSoiSGxN7n81W8p4/JWT0Y6sFQD4Z6MNSD56t4l4+c1YOhHgz1YKgHQz0YLmeXs3ow1IOhHgz1YKgHI+QcclYPhnow1IOhHgz1YIScQ87qwVAPhnow1IOhHjzfEXz6NDmrB0M9GOrBUA+GejC6nLuc1YOhHgz1YKgHQz0YXc4pZ/VgqAdDPRjqwVAPhk41Q+eaoR4M9WCoB0M9GOrB0Bnn+WbhJeSsHgz1YKgHQz0YOvE83yy8hJzVg6EeDPVgqAfPNwsvHzmrB0M9GOrBUA+GevB8+/DpM+WsHgz1YKgHQz3Y1IPn24cPn/Ptw0uERJPoEilREkM+clYPNvVgUw829WBTD56vIT59TM7qwaYebOrBph5s6sHmcnY5qweberCpB5t6sKkHz1cVnz4hZ/VgUw829WBTDzb14PnO4tMn5KwebOrBph5s6sGmHjzfWXz6NDmrB5t6sKkHm3qwqQfPdxafPl3O6sGmHmzqwaYebOrB1uXc5awebOrBph5s6sGmHmwpZ/Vg08/Bpp+DTeeiTeeiTT3YdM3XdNHX1INNPdjUg03nok1Xfk092NSD7ezBdojD+XjH9NmDpwiJJtElUqIkhsTc4uzBU8h5ynnKecp5ynnKecp5ynlu5/54SJiES4REk+gSKVESQ0LOJmeTs8nZ5GxyNjmbnM8ePO8cDIm5xdGDxx3XfvTgEi4REk2i66tSQs5HD65/M7cIOYecQ84h55BzyDnkHHIO7XNon5ucm5ybnJucm5yPHlwiJeTc5NzkfPbgKUzCJUJCzl3OXc5HDy6hanRVI7XPKeeUc8r57MFTqBqpaqT2OeWcci45l6pRqkapGqV9LjmXnEvOpWqUqjFUjaF9HnIech5yHqrGUDWGqjG0z0POU85TzlPVmKrGVDWm9nnKecp5ynnuauTjIWESLrGd89EkukRKlMSQ2PucJmeTs8nZQqJJdImUkLN6MNWD6Q8Jk3AJ7bN6MF3OLmcviSGhaqgHM+Qccg45h6qhHkz1YKoHM+QcclYPpnow1YOpHkz1YDY5NzmrB1M9mOrBVA+mejC7nLuc1YOpHkz1YKoHUz2YXc4pZ/VgqgdTPZjqwVQPZso55aweTPVgqgdTPZjqwSw5l5zVg6keTPVgqgdTPZhDzkPO6sFUD6Z6MNWDqR7MIechZ/VgqgdTPZjqwVQP5pTzlLN6MNWDqR5M9WCpB+uxnevhEiHRJLpESpTEkI+c1YOlHiz1YKkHSz1YJmeTs3qw1IOlHiz1YKkHSz8HSz8HSz1Y6sFSD5Z6sNSD5XIOOasHSz1Y6sFSD5Z6sELOIWf1YKkHSz1Y6sFSD1aTc5OzerDUg6UeLPVgqQery7nLWT1Y6sFSD5Z6sNSD1eXc5aweLPVgqQdLPVjqwUo5p5zVg6UeLPVgqQdLPVgl55KzerDUg6UeLPVgqQer5FxyVg+WerDUg6UeLPVgDTkPOasHSz1Y6sFSD5Z6sKacp5zVg6UeLPVgqQdLPVhzO4/HQ8IkXCIkmkSX2M7jURJDYldjqAeHenCoB4fJ2eSsHhzqwaEeHOrBoR4cOhcdOhcd6sGhHhzqwaEeHOrBoXPR4XJWDw714FAPDvXgUA8OnYuOkLN6cKgHh3pwqAeHenA0OTc5qweHenCoB4d6cKgHR5Nzk7N6cKgHh3pwqAeHenB0OXc5qweHenCoB4d6cKgHR8o55aweHOrBoR4c6sGhHhwp55KzenCoB4d6cKgHh3pwlJxLzurBoR4c6sGhHhzqwTHkPOSsHhzqwaEeHOrBoR4cU85TzurBoR4c6sGhHhzqwTHlPOWsHpzqwakenOrBqR6cj+08H10iJUpiSOxqTPXgNDmbnNWDUz041YNTPTjVg9PkrB6c+jk49XNw6lx06lx0qgenrgenrgenenCqB6d6cOpcdOp6cKoHp3pwnj3ohziqcf5NSpTEkJhbnD14CpNwiZBoEnJucm5ybnJucu5yPnrwmNSYRw8uERJNokukREkMibnF0YNLyDnlnHJOOaecU85HDx6/2zKPHlxibnH04BIm4RIh0SS6REoczuMQQ2Ievy98PP9+SJiES4REk+gSKVESQ0LOU85TzlPOU85TzkcPHsMo8+jBJUpiSByf+lfnM/rHpexSfqm4VLtUv1Reqi41LnVl2JVhV4ZdGXZl2JVhV4ZdGXZl2JVhV4ZfGX5l+JXhV4ZfGX5l+JXhV4ZfGX5lxJURV0ZcGXFlxJURV0ZcGXFlxJURV0a7MtqV0a6MdmW0K6NdGe3KOD/v8JiwesqBnJc8P/Xw+GyZpzSkIwPZkB2ZyEIO5LxkkpakJWlJWpKWpCVpSVqSlqQVaUVakVakFWlFWpFWpBVpRdogbZA2SBukDdIGaednLh6/YfKUhRzIM20e8vxk3i0N6chAtsvh/KTGLUk7P61x/9uBvNLOCR5JQzoykFfaOcsjmchCDiRpRpqRZqQZaecHO27ZkaQZaUaazUv6A2lIR5LmpDlp54dCblnIgWRtQVqQFqSdn326JZUMKhmsLUgL0oK0RiUblWxUsrG2RlojrZHWqGSjko1KdtbWSeukddI6lexUslPJzto6aZ20JC2pZFLJpJLJ2pK0JC1JSyqZVLKoZLG2Iq1IK9KKShaVLCpZrK1IG6QN0gaVHFRyUMnB2mCJwRKDJeszvpecVHJSycnaYMn6tO8tSZtUEpYYLDFYsj4C/PRdHwK+pSMD2ZAdmcjCdyBJgyUOSxyWOCxZHyG+fI00WOKwxGGJwxKHJe6kOWmwxGGJwxKHJQ5L1ueMb1/SYInDEoclDksclniQFqTBEoclDkscljgsWZ9TvnwbabDEYYnDEoclDku8kdZJgyUOSxyWOCxxWOKdtE4aLHFY4rDEYYnDEk/SkjRY4rDEYYnDEocl68PQl2+RBkscljgscVjisMSLtCINljgscVjisMRhiQ/SBmmwxGGJwxKHJQ5LnPMS57zEYYnDEoclDksclvgkbV5pAUsClgQsCVgSsCQeV1o8ElnIgbwqGbAkYMn60PPla6TBkoAlAUsClgQsCSPNSYMlAUsClgQsCVgSTpqTBksClgQsCVgSsGR9JvvyDdJgScCSgCUBSwKWRCOtkQZLApYELAlYErBkfab79iUNlgQsCVgSsCRgyfqo9+XbSYMlAUsClgQsCVgSSVqSBksClgQsCVgSsGR9VPz2JQ2WBCwJWBKwJGBJFGlFGiwJWBKwJGBJwJIYpA3SYEnAkoAlAUsClgTXOME1TsCSgCUBSwKWBCwJrnHWJ9JvSRosabCkwZIGSxrXOO3RkB2ZyEIO5LW2ZqQZabCkwZIGSxosabBkfYT99iUNljRY0mBJgyUNlqwPvV++ThosabCkwZIGSxosaUFakAZLGixpsKTBkgZLWpAWpMGSBksaLGmwpMGS1khrpMGSBksaLGmwpMGS1knrpMGSBksaLGmwpMGS1klL0mBJgyUNljRY0mBJS9KSNFjSYEmDJQ2WNFjSirQiDZY0WNJgSYMlDZa0QdogDZY0WNJgSYMlDZa0QRosaZyXNM5LGtc4jWucBksa90sa90saLGmwpMGSxjVO535JhyUdlpxzbuernO2cdLPjQ3ztnHWTTGQhB3Je8mTJloZ0ZCBJM9KMNCPNSDPSnDQnzUlz0pw0J81Jc9KcNCctSAvSgrQgLUgL0oK0IC1IC9JOlhyv+LFzZk7SkWdanbIhOzKRhRw4zEt20k6WrH97smRL0jppnbROWietk9ZJS9KStSVrS9KStCQtSUvSTpZsOS9ZpBVpRdrJki0bsiMTSVqRVqSdLNmSSg4qOVjbIG2QNkg7WbIllRxUcrK2SdokbZI2qeSkkpNKTtY2SZtX2jmpJ2lIRwayIa+0fCSykAN5VTLtgTQkaUaakWYdmchCDiRpTpqT5o4MZEOyNifNSXPSnEoGlQwqGawtSAvSgrSgkkElg0oGa4MlCUsSlmSjko1KNirZWBssyUZaI61TSViSsCRhSXbSOmmdtE4lYUnCkoQlmaQlabAkYUnCkoQlCUsySUvSYEnCkoQlCUsSlmSRVqTBkoQlCUsSliQsyUHaIA2WJCxJWJKwJGFJDtImabAkYUnCkoQlCUtykjZJgyUJSwqWFCwpWFKPK60eDdmRiSzkQF5rKyPNSIMlBUsKlhQsKVhSRpqRBksKlhQsKVhSsKScNCcNlhQsKVhSsKRgSQVpQRosKVhSsKRgScGSCtKCNFhSsKRgScGSgiXFeUlxXlKwpGBJwZKCJQVLqpPWSYMlBUsKlhQsKVhSnbQkDZYULClYUrCkYEklaUkaLClYUrCkYEnBkirSijRYUrCkYEnBkoIlNUgbpMGSgiUFSwqWFCypQdogDZYULClYUrCkYElN0iZpsKRgScGSgiUDlozHlTYejgxkQ3ZkIgs58CUNlgxYMmDJgCUDlgwjzUiDJQOWDFgyYMmAJcNJc9JgyYAlA5YMWDJgyXDSgjRYMmDJgCUDlgxYMoK0IA2WDFgyYMmAJQOWDK5xBtc4A5YMWDJgyYAlA5YMrnFGJw2WDFgyYMmAJQOWDK5xRicNlgxYMmDJgCUDlowkLUmDJQOWDFgyYMmAJaNIK9JgyYAlA5YMWDJgySjSijRYMmDJgCUDlgxYMgZpgzRYMmDJgCUDlgxYMiZpkzRYMmDJgCUDlgxYMuaVNh8PpCEdGciG7MgrbT4KOZBXJScsmbBkwpJppBlpsGTCkglLJiyZsGQ6aU4aLJmwZMKSCUsmLJlOmpMGSyYsmbBkwpIJS2aQFqTBkglLJiyZsGTCktlIgyWT85LJecnkGmdyjTNhyeR+yeR+yYQlE5ZMWDK5xpncL5mwZMKSuVgyT3mkHW9UtHPudMuTJVsa0pGBbMiOTGQhSUvSirQirUgr0oq0Iq1IK9KKtCJtkDZIG6QN0gZpg7RB2iBtkDZIm6RN0iZpk7STJcfbx+ycX5VM5Jl2vt7sZMmWc0s/B1klDenbwc9ZVsmG7PzbRBZyIEkz0ow0I81IM9KsIxNJmpFmpDlpTtrJki0DSZqT5qSdLNlyIOclT5ZsSVqQFqSdLNmSSgaVDNYWpAVpjbSTJVtSyUYlG2trpDXSGmmNSjYq2alkZ22dtE5aJ61TyU4lO5XsrK2TlqQlaUklk0omlUzWlqQlaUlaUsmikkUli7UVaUVakVZUsqhkUclibYO0QdogbVDJQSUHlRysbZA2SBukTSo5qeSkkpO1TdImaZO0SSUnlZxXJdfc65ZX2pp73TKQDdmRiSzkwJc0I80M6chANiRpRhosMVhisMRgicGSNfe6fJ00WGKwxGCJwRKDJeakBWmwxGCJwRKDJQZLLEgL0mCJwRKDJQZLDJasudfl20iDJQZLDJYYLDFYsuZel28nDZYYLDFYYrDEYMmae92+pMESgyUGSwyWGCxZc6/LN0mDJQZLDJYYLDFYsuZel2+RBksMlhgsMVhisGTNvW5f0mCJwRKDJQZLDJasudflO0iDJQZLDJYYLDFYsuZel+8kDZYYLDFYYrDEYIlxXuKclzgscVjisMRhicOSNfd6+q651y0H8qqkwxKHJQ5L1tzr8jXSYInDEoclDksclqy51+XrpMEShyUOSxyWOCxZc6/blzRY4rDEYYnDEocla+51+QZpsMRhicMShyUOS9bc6/JtpMEShyUOSxyWOCxZc6/blzRY4rDEYYnDEocla+51+XbSYInDEoclDksclqy51+WbpMEShyUOSxyWOCxZc6/Lt0iDJQ5LHJY4LHFYsuZel2+RBkscljgscVjisGTNvS7fQRoscVjisMRhicOSNfe6fCdpsMRhicMShyUOS3ySNkmDJQFLApYELAlYElzjrLnXLRNZyIG8KhmwJLjGWXOvW5IGSwKWBCwJWLLmXrcvabAkYEnAkoAlAUvW3OvyddJgScCSgCUBSwKWrLnX5RukwZKAJQFLApYELFlzr8u3kQZLApYELAlYErBkzb0u30YaLAlYErAkYEnAkjX3unw7abAkYEnAkoAlAUvW3OvyTdJgScCSgCUBSwKWrLnX7UsaLAlYErAkYEnAkjX3unyLNFgSsCRgScCSgCVr7nX5DtJgScCSgCUBSwKWrLnX7UsaLAlYErAkYEnAkjX3unxhSXBeEpyXBNc4jWucBksa90sa90saLGmwpMGSxjVO435JgyUNlqy51+MzW3zNvR4fveJr7nXLhuzIRBZyIOclT5ZsaUjSnDQnzUlz0pw0J81JC9KCtCAtSAvSgrQgLUgL0oK0RlojrZHWSGukNdIaaY20kyX7PcXzkidLtjzTzg8OOFmyZSAbsiMTh0KSdrJk/duTJVuSlqQlaUlakpakJWlJWrK2Ym1FWpFWpBVpRdrJki0LSVqRNkg7WbKlIwPZkKQN0gZpJ0u2pJKTSk7WNkmbpE3STpZsSSUnlZysbV5pa+51S0M6MpAN2ZFX2pp73XIgr0quudctDelI0ow0I80SWciBZG1OmpPmpHkgG7IjWZuT5qQ5aUElg0oGlQzWFqQFaUFaUMmgkkElG2trpDXSGmmNSjYq2ahkY22wpMOSDkvW3OuWVLJTyc7aYMmae92StE4lYUmHJR2WrLnX5ZukJWlJJWFJhyUdlqy51+VbpMGSDks6LOmwpMOSNfe6fIs0WNJhSYclHZZ0WLLmXpfvIA2WdFjSYUmHJR2WrLnX5TtJgyUdlnRY0mFJhyVr7nX7kgZLEpYkLElYkrBkzb2evmvudctEFnIgr0omLFlzr8vXSIMlCUsSliQsSViy5l63L2mwJGFJwpKEJQlL1tzr8nXSYEnCkoQlCUsSlqy51+UbpMGShCUJSxKWJCxZc6/Lt5EGSxKWJCxJWJKwZM29Lt9GGixJWJKwJGFJwpLkvCQ5L0lYkrAkYUnCkoQla+51+SZpsCRhScKShCUJS9bc6/YlDZYkLElYkrAkYcmae12+RRosSViSsCRhScKSNfe6fAdpsCRhScKShCUJS9bc6/YlDZYkLElYkrAkYcmae12+kzRYkrAkYUnBkoIla+719F1zr1s2ZEcmspADSZqRBksKlhQsKVhSsGTNvS5fIw2WFCwpWFKwpGDJmntdvk4aLClYUrCkYEnBkjX3unyDNFhSsKRgScGSgiVr7nX7kgZLCpYULClYUrBkzb0u30YaLClYUrCkYEnBkuIap7jGKVhSsKRgScGSgiXFNc6ae10SlhQsKVhSsKRgSXGNs+ZetyQNlhQsKVhSsGTNvS7fIg2WFCwpWFKwpGDJmntdvoM0WFKwpGBJwZKCJWvudfkO0mBJwZKCJQVLCpasudflO0mDJQVLCpYULClYsuZeT98197qlIwPZkB2ZyMJ3IEmDJQOWDFgyYMmae12+RhosGbBkwJIBSwYsWXOvy9dJgyUDlgxYMmDJgCVr7nX7kgZLBiwZsGTAkgFL1tzr8g3SYMmAJQOWDFgyYMmae12+jTRYMmDJgCUDlgxYsuZely8sGZyXDM5LBtc4g2ucAUsG90sG90sGLBmwZMCSwTXO4H7JgCUDlqy51+PjeX3NvR4fW+pr7nXLgZyXXCxZ0pCODGRDdiRpRVqRVqQN0gZpg7RB2iBtkDZIG6QN0gZpk7RJ2iRtkjZJm6RN0iZpk7R5pa251y0NeaQdb/70Nfe6ZUMeabk+rCqRhRzIecmTJcvhZMmWpJ0s2f+2IUkz0ow0I81Ic9KcNCfNWZuzNifNSXPSnDQn7WTJloYkLUgL0k6WbJnIQg4kaY20RtrJki2pZKOSjbU10hppjbSTJUt2KtmpZGdtnbROWietU8lOJTuV7KwtSUvSkrSkkkklk0oma0vSkrQkrahkUcmiksXairQirUgrKllUsqjkYG2DtEHaIG1QyUElB5UcrG2QNkibpE0qOankpJKTtU3SJmmTtEklpyoZa+51S0MqLR4XS+JxsSTW3OuWiSzkQJJmpBlp5shANmRHkmakGWk2L3mxJB4XS+LhrM1Jc9KctIsl8bhYEo+LJfFw1hakBWlBWlDJoJJBJYO1BWlBWpDWqGSjko1KNtbWSGukNdIalWxUslHJzto6aZ20Tlqnkp1KdirZWVsnrZOWpCWVTCqZVDJZW5KWpCVpSSWTShaVLNZWpBVpRVpRyaKSRSWLtRVpg7RB2qCSg0oOKjlY2yBtkDZIG1RyUslJJSdrm6RN0iZpk0pOKjmpJCxZc6+n75p73dKRgWzIjkxk4TuQpMESgyUGSwyWrLnX5WukwRKDJQZLDJYYLFlzr8vXSYMlBksMlhgsMViy5l63L2mwxGCJwRKDJQZL1tzr8g3SYInBEoMlBksMlqy51+XbSIMlBksMlhgsMViy5l6XbycNlhgsMVhisMRgyZp7Xb6dNFhisMRgicESgyVr7nX5JmmwxGCJwRKDJQZL1tzr8i3SYInBEoMlBksMlqy51+1LGiwxWGKwxGCJwZI197p8B2mwxGCJwRKDJQZL1tzr8p2kwRKDJQZLDJYYLFlzr9v3SnNY4rDEYYnDEoclfl3jhF/XOOGwxGGJwxKHJQ5L3Egz0mCJwxKHJQ5LHJa4keakwRKHJQ5LHJY4LFlzr8vXSYMlDkscljgscViy5l6Xb5AGSxyWOCxxWOKwZM29Lt9GGixxWOKwxGGJw5I197p9SYMlDkscljgscViy5l6XbycNljgscVjisMRhyZp7Xb5JGixxWOKwxGGJw5I197p9SYMlDkscljgscViy5l6Xb5EGSxyWOCxxWOKwZM29Lt9BGixxWOKwxGGJw5I197p8J2mwxGGJwxKHJQ5L1tzr8p2kwRKHJQFLApYELFlzr6dvwJLgvCQ4LwmucYJrnIAlYaQZabAkYEnAkuAaJ677JRGwJGDJmnvNOORiSZ7SkI4MZEN2ZCILOZDzkkFakBakBWlBWpAWpAVpQVqQ1khrpDXSGmmNtEZaI62R1khrpHXSOmmdtE5aJ62TtlgyTlnIgTzT5iEXS5Y0pCMD2S6HxZIlSVssWf92IEkr0oq0Iq1IK9KKtCKtWFuxtiJtkDZIG6QN0hZLluxI0gZpg7TFklMulixpSEeSNkmbpC2WLEklJ5Wc19rW3Ovpu+Zet3RkIBuyIxNZ+A4kafZAGtKRgSTNSDPSrJADeVVyzb1uSZqT5qR5Q3ZkIlmbk+akBWlBJYNKBpUM1hakBWlBWlDJoJKNSjbW1khrpDXSGpVsVLJRycbaGmmdtE5ap5KdSnYq2VkbLGmwpMGSNfe6ZFLJpJLJ2mDJmnvdkrSkkrCkwZIGS9bc6/It0oq0opKwpMGSBkvW3Ov2JQ2WNFjSYEmDJQ2WrLnX5TtIgyUNljRY0mBJgyVr7nX5TtJgSYMlDZY0WNJgyZp73b5XWoclHZZ0WNJhSYcla+719F1zr1sWciCvSnZY0mHJmntdvkYaLOmwpMOSDks6LFlzr8vXSYMlHZZ0WNJhSYcla+51+TppsKTDkg5LOizpsGTNvS7fIA2WdFjSYUmHJR2WrLnX5dtIgyUdlnRY0mFJhyVr7nX7kgZLOizpsKTDkg5L1tzr8u2kwZIOSzos6bCkw5LOeUnnvKTDkg5LOizpsKTDkjX3un1JgyUdlnRY0mFJhyVr7nX5FmmwpMOSDks6LOmwZM29Lt9BGizpsKTDkg5LOixZc6/Ld5IGSzos6bCkw5IOS9bc6/KdpMGSDksSliQsSViy5l5P3zX3umVHJrKQA3mtbc29Ll8jDZYkLElYkrAkYcmae92+pMGShCUJSxKWJCxZc6/L10mDJQlLEpYkLElYsuZel2+QBksSliQsSViSsGTNvW5f0mBJwpKEJQlLEpasudfl20iDJQlLEpYkLElYsuZel28nDZYkLElYkrAkYUlyjZNc4yQsSViSsCRhScKS5Bpnzb1uSRosSViSsCRhSXKNs+ZetyQNliQsSViSsGTNvS7fQRosSViSsCRhScKSNfe6fUmDJQlLEpYkLElYsuZel+8kDZYkLElYkrCkYMmaez1919zrloFsyI5MZCEHvqTBkoIlBUsKlhQsWXOvy9dIgyUFSwqWFCwpWLLmXpevkwZLCpYULClYUrBkzb0u3yANlhQsKVhSsKRgyZp7Xb5BGiwpWFKwpGBJwZI197p8G2mwpGBJwZKCJQVL1tzr8u2kwZKCJQVLCpYULFlzr9uXtXFeUpyXFNc4xTVOwZLifklxv6RgScGSgiXFNU5xv6RgScGSNfd6fFZwrLnXWn/bkYks5EDOS54s2dKQjjzSxuOUDdmRiSzkQM5LnizZ0pCOJG2SNkmbpE3SJmknS0Z/yjX3uuW1tjX3umUgG7IjE1nIgbwqueZetyTNSDPSjDQjzUgz0uxa25p7XdIfSEM6MpAN2ZGJLCRpTlqQFqQFaUHayZJV9WBtwdqCtQWVDCrZqGSjko1KNirZqGQjrZHWSGukNdI6aZ20zto6a+tUslPJTiU7lexUslPJpJJJJZO0JC1JS9KStCTtZMmq+smSUYc8WbKlIR0ZyIbsyEQW8kibccp5yZMlWxrSkYFsyI5MZCFJG6RN0iZpk7RJ2sGS57PcU3ZkHjJPWciBnJLn3KukIR0ZyIbsyEQWciBJM9KMNCPNSDPSjDQjzUgz0ow0J81Jc9KcNCfNSXPSnDQnzUkL0oK0IC1IC9KCtCAtSAvSgrRGWiOtkdZIO1jyfEB+yiPN2ykTWciBnJc8WCJpSEcGsiFJ66R10jppnbQkLUlL0pK0JC1JS9KStCQtSSvSirQirUgr0oq0Iq1IK9KKtEHaIG2QdrDEY8mG7MhEFnIg5yUPlkga0pGkTdImaZO0SdokbSqtnXOvkoZ0ZCAbsiMTWciBJM1IM9KMNCPNSDPSjDQjzUgz0pw0J81Jc9KcNCfNSXPSnDQnLUgL0oK0IC1IC9KCtCAtSAvSGmmNtEZaI62R1khrpDXSGmmNtE5aJ62T1knrpHXSOmmdtE5aJy1JS9KStCQtSUvSkrQkLUlL0oq0Iq1IK9KKtCKtSCvSirQibZA2SBukDdIGaYO0QdogbZA2SJukTdImaZO0SdokbZI2SZukwRKDJQZLDJYYLDFYYrDEYInBEoMlBksMlhgsMVhisMRgicESgyUGSwyWGCwxWGKwxGCJwRKDJQZLDJYYLDFYYrDEYInBEoMlBksMlhgsMVhisMRgicESgyUGSwyWGCwxWGKwxGCJwRKDJQZLDJYYLDFYYrDEYInBEoMlBksMlhgsMVhisMRgicESgyUGSwyWGCwxWGKwxGCJwRKDJQZLDJYYLDFYYrDEYInBEoMlBksMlthiSZ7ySGvrbzsykYU80to85ZHW7ZAnS7Y80nJJRwayIY+0PPfhZMmWR1qeESdLyk85Jc+5V6/22/ff/fcPv/70w59//vG/vvvDP59//I9//PKXv//011/2H//+//6m//PnX3/6+eef/vNPf/v1r3/58d//8euPf/r5r385/t93dvznafhvYfV9RP/j8yTo+acnbr5/QuD5pwMg/xaP/n086o9PK9cXPB/if/98BL6/wNO/f+6fvqA9V9gyji+I4wviNPm+PY6/6fobj2fkH3/77bc//vb/AQ==",
|
|
1996
|
+
"verification_key": "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"
|
|
2005
1997
|
},
|
|
2006
1998
|
{
|
|
2007
1999
|
"name": "claim_and_end_setup",
|
|
@@ -3181,7 +3173,7 @@
|
|
|
3181
3173
|
"name": "pk_m",
|
|
3182
3174
|
"type": {
|
|
3183
3175
|
"kind": "struct",
|
|
3184
|
-
"path": "
|
|
3176
|
+
"path": "aztec::protocol_types::point::Point",
|
|
3185
3177
|
"fields": [
|
|
3186
3178
|
{
|
|
3187
3179
|
"name": "x",
|
|
@@ -3851,9 +3843,9 @@
|
|
|
3851
3843
|
}
|
|
3852
3844
|
}
|
|
3853
3845
|
},
|
|
3854
|
-
"bytecode": "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",
|
|
3855
|
-
"debug_symbols": "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",
|
|
3856
|
-
"verification_key": "
|
|
3846
|
+
"bytecode": "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c3rp2pxeujanl67N6aVrc3rp2pxeujanl67N6aVrc3rp2pxeujanl67N6aVrc3rp2pxeujanl67N6aVrc3rp2pxeujanl67N6aVrc3rp2pxeunYWx5bTS9fm9NK1Ob10bU4vXZvTS9fm9NK1Ob10bU4vXZv0dXROL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vXnsix5fTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL12b00vX5vTStTm9dG1OL137Z44tp5euzemla3N66dqcXro2p5euzemla3N66dqcXro2p5euzemla5MaunB66dqcXro2p5euzemla3N66dqcXro2p5euzemla3N66dqcXro2p5euzemla2/h2HJ66dqcXro2p5euzemla3N66dqcXro2p5euvYdjy+mla3N66dqcXro2p5euzemla3N66dqcXro2p5euzemla3N66dqcXro2p5euzeml6+H00vVweul6OL10PZxeuh5OL10Pp5euh9NL18Pppevh9NL1cHrpeji9dD2cXroeTi9dD6eXrofTS9fj59jm5djm49jm59hy+t96OP1vPZz+tx5O/1sPp/+th9P/1sPpf+vh9L/1cPrfejj9bz2c/rceTv9bD6f/rYfT/9bD6X/r4fS/9XD633o4/W89nP63Hk7/Ww+n/62H0//Ww+l/6+H0v/Vw+t96OP1vPZz+tx5O/1sPp/+th9P/1sPpf+spw7Hl9L/1cPrfejj9bz2c/rceTv9bD6f/rYfT/9bD6X/r4fS/9XD633o4/W89nP63Hk7/W899HFtO/1sPp/+th9P/1sPpf+vh9L/1cPrfejj9bz2c/rceTv9bD6f/rYfT/9bD6X/r4fS/9XD633o4/W89nP63Hk7/W8/DHFtO/1sPp/+th9P/1sPpf+vh9L/1cPrfejj9bz2c/rceTv9bD6f/rYfT/9bD6X/r4fS/9XD633o4/W89nP63Hk7/Ww+n/62H0//Ww+l/6+H0v/Vw+t96OP1vPZz+tx5O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",
|
|
3847
|
+
"debug_symbols": "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",
|
|
3848
|
+
"verification_key": "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"
|
|
3857
3849
|
},
|
|
3858
3850
|
{
|
|
3859
3851
|
"name": "public_dispatch",
|
|
@@ -3873,10 +3865,6 @@
|
|
|
3873
3865
|
],
|
|
3874
3866
|
"return_type": null,
|
|
3875
3867
|
"error_types": {
|
|
3876
|
-
"361444214588792908": {
|
|
3877
|
-
"error_kind": "string",
|
|
3878
|
-
"string": "attempt to multiply with overflow"
|
|
3879
|
-
},
|
|
3880
3868
|
"1080336462466469436": {
|
|
3881
3869
|
"error_kind": "string",
|
|
3882
3870
|
"string": "Function check_balance can only be called statically"
|
|
@@ -3889,7 +3877,7 @@
|
|
|
3889
3877
|
"error_kind": "string",
|
|
3890
3878
|
"string": "Balance too low"
|
|
3891
3879
|
},
|
|
3892
|
-
"
|
|
3880
|
+
"11194752367584870169": {
|
|
3893
3881
|
"error_kind": "fmtstring",
|
|
3894
3882
|
"length": 27,
|
|
3895
3883
|
"item_types": [
|
|
@@ -3909,15 +3897,11 @@
|
|
|
3909
3897
|
"15860392472534760515": {
|
|
3910
3898
|
"error_kind": "string",
|
|
3911
3899
|
"string": "Function balance_of_public can only be called statically"
|
|
3912
|
-
},
|
|
3913
|
-
"16431471497789672479": {
|
|
3914
|
-
"error_kind": "string",
|
|
3915
|
-
"string": "Index out of bounds"
|
|
3916
3900
|
}
|
|
3917
3901
|
}
|
|
3918
3902
|
},
|
|
3919
|
-
"bytecode": "
|
|
3920
|
-
"debug_symbols": "
|
|
3903
|
+
"bytecode": "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",
|
|
3904
|
+
"debug_symbols": "tZvdbhu5DoDfxde5EKkfkn2VRVGkrbsIEKRFNjnAQZF3X1IjifYupJ160pvOZ9pDUhJFUVLz8/T1/Pn1z08PT9++/3X68MfP0+fnh8fHhz8/PX7/cv/y8P1JpT9Pwf6BqA+402c+fUB9ptCe7XNun3NqT9mepX0u7TPF9uTtydieVJ9YVE+yZ25P2Z6U2rN95vaZ22fR9/nuFAO2Z1F/1eEI0EE1gpqIGDp0SW1cMTCJvW7N2yC1r5I0qC0MBtKgUAPCDmodowKrdUwGpYGkDvp6VMdSiB24AXQJdAl2CVKDCB1KA/N5g9yhmzCfNzCF6lgq2IEaUJdQl3CXcJeIuZEMeINs/R2LATWALrF+3sDGUvs5Wz8neyvq68m+SrFDl2STsAE3KF1C0EGbnLMChw65gzY5k4K5ugFvUMzVAgbqalE3ivVzyQbUALGDmij2lvXzBrmB9fMGXZLtx+pYsegkDYDCsQM3kC6RJqHQJGQhStGgNLCuo2SQG8QuMTdIbZG5QWLADazrGA1UwvZj67oNqH1lo7yBSbTDyUa5goQOuYM2R9QfNlc34AbQJdAl2CUWohWs6zYoDcznDXKHbsJCdANTqEPAFqIbUAPqEuoS7hLuEutnKQa8gdi4CxtQA+gS6+cNbOIH7SmpuSDYexakEOxbi9JGQ5arTIy4UxkyC9VGpSY24dCeuT0tn1hiEssIjbgRBOvxji6F+pLlyxDJMBkmcCwDs0uzS4tLS1XGhpQczRpWExbEYGlMWwKOpixq3IK65pgHgkvBpehSTI48MEZHGpjQ0Q3XtjWsJrCiDCzJ0aXkUnIpu1Sqk7Fidqy/1eDSRiRHlwINtAQCCSqaNJkGrOtKqj+oK0vDKi2GOTi6tLi0NqihDCSXkkvruDXkgYKO1LGulx3LwDqElmphWzYbysA6hA1durWNKuaB2aXZpcWlxaXkUnIpu5RdKi6VIU0hOLoUXArJUQaiS9Gl0aU1G2xYY7IhDawx2bAM9GYmb2YqboLcBLmJbQg3dBPihmWYyAEch4nsLc7e4uwtzhgdh+Ec0XEYzslNJDfsA5t9YHN2E8UNFzdBbpjcBLthdhPihn2Mi49xCclxGK4Le8dhuCA6DsN1ge84DBcP5eKhXJKbyG44u4nihoubIDdsy4GOk6HVhh1lYF0NGnLHWit0dKmtYw3rArZhXcEaujS5NCVHV5ZdWaaBxaXFpQSOo0HEboI3w29vd6e+mfj08nw+217iYnehe44f98/np5fTh6fXx8e70//uH1/rj/76cf9Uny/3z/qtKj0/fdWnKvz28Hg2ervzt8P8VVvduL2uLDhUZNitA4NVl5sODIVu0RG0/Ok6dL0MMx1xrgM1BTQVmGMcGgh3e6HLThxexJBnXuS5DtHp01SIFrhDA6Z0paLMVegUlqZC6/JwoaJcqaBVX/QRwYvx0Nbt74po25PeFTIdEJnr0CzaxzRjgmk7IBxtyF4n8tyJZV8kq35bX+hWctYXsIhO3UF0P3SapamKtIgL3bP2uNA9qquQaxWL6IxDQyxpNkPWPlAP75JRpj4sYjNh74ikC5druK0rLyb6P7tyERUCPawEfY6mXxnOKMOHy1Zcq0BYdCVQTza6ENOsK227MZ0d1JM3ynw493ZlgVsCmwF6otCN7zRlYl6tIMkXEHEVfD1FcZEzkXs7olwkXbjOE7gIS93cjpiIyWcX8PVqirzQEcb6IeEiZ/5Lh6ymaFcRr5aPaw1xlTO1HOlhoRu423Rg7G4gloUfi+hMQGOmY6CL3tjtRtTDgjGuJFM3ltGle9QeXbqPm0VXXKjIPGZq8FFlvm2SpGn2j6v4TKOuIJz5EHlVY6Ev6QHzNOPEVeIUoaEjQJrpSOFw4ktwMPGt25HR23GxBvzTicWg6o59BKcWalM31mOCF2NC00U9rQLckzgIXFRJeGMWn5ffaVVzjmmm9wpDQfyVSVJ4+MDTbUSSwytJDkdXkgzHV5KMx1eSHI+uJDkdX0mWOnauJLkcXkl2B5dMgyuvJiuMcdUtEcxycJblPhfGViIwTvNnWe1HyBc0BpzO97UjRHSx8Z9W8gVXSnLyLJplmkXLKkoLdx16R3jbtj2xD0ySmw4g9GDS93g5TDNgWYSpzvuROwLlm5qS8cKNzDc1pQTfulOc6ijyew9TBP0wRWg6KgTHjxAIjx4h7Pbi1jMEEfBDMpjGF63OljwNCszP6qisjqcAxvFUnJYbRMsc5uEVZBYa+xuSbuqLiDwW2TztCw6Hz1MYDp6nrH3YdZ7C8eB5yu6unB8CcD54nrL2IbgPOM0VTIdrP+ajtR/L8dpPwvHaT+Bo7Sd4vPZb6thZ+0k6XPut3Nh7irCMrn2nCEIHTxF2T5IyPXQUOXiKACG8wzECBDh+jqAWDh8kQIhHj1DXTdl3lFB3DwfPEv5rZPYdJmjBf/w0YXegcrrtUtELYZ328zuX1e3ROxTkGMT9gHjbBSmMdQUw4qItv/d6U2vXUZHrxM1zP97hgrMeKB294gT4rZecWEafAhIsOmS5lY7gd+hxcT2I4XBhDqsbpZ2V+S+1Bm/sk1Q8KSae3yxhOlzRwer0f19JB6u7pb01HSyvl3YWdbC6X9pX1cHqemlvWbdWsrOugwjHD/WWl2U7K7t1mO0r7SCmozdEvzBlZH6vHcvR+i7Se9R3q4uN3fXd6pJmb323umzaeUXO71DfJTxe3/3HyOys71I6Xt8t100qfphFHG8qiiiGCx1lGu6rO6f3KPA4jEhFTov/mbNKiKOcwYtY17Xi7aN+uv/y8Hz1d0Nvpun54f7z47l9/Pb69OXi25f//+jf9L87+vH8/cv56+vz2TT5Hx/F04c/oh5KRyof7f9j20c9yY65fHwz638D"
|
|
3921
3905
|
}
|
|
3922
3906
|
],
|
|
3923
3907
|
"outputs": {
|
|
@@ -4188,215 +4172,215 @@
|
|
|
4188
4172
|
},
|
|
4189
4173
|
{
|
|
4190
4174
|
"name": "Field::to_le_bits",
|
|
4191
|
-
"start":
|
|
4175
|
+
"start": 1196
|
|
4192
4176
|
},
|
|
4193
4177
|
{
|
|
4194
4178
|
"name": "Field::to_be_bits",
|
|
4195
|
-
"start":
|
|
4179
|
+
"start": 2387
|
|
4196
4180
|
},
|
|
4197
4181
|
{
|
|
4198
4182
|
"name": "Field::to_le_bytes",
|
|
4199
|
-
"start":
|
|
4183
|
+
"start": 3562
|
|
4200
4184
|
},
|
|
4201
4185
|
{
|
|
4202
4186
|
"name": "Field::to_be_bytes",
|
|
4203
|
-
"start":
|
|
4187
|
+
"start": 5033
|
|
4204
4188
|
},
|
|
4205
4189
|
{
|
|
4206
4190
|
"name": "Field::to_le_radix",
|
|
4207
|
-
"start":
|
|
4191
|
+
"start": 5904
|
|
4208
4192
|
},
|
|
4209
4193
|
{
|
|
4210
4194
|
"name": "Field::to_be_radix",
|
|
4211
|
-
"start":
|
|
4195
|
+
"start": 6362
|
|
4212
4196
|
},
|
|
4213
4197
|
{
|
|
4214
4198
|
"name": "Field::pow_32",
|
|
4215
|
-
"start":
|
|
4199
|
+
"start": 7053
|
|
4216
4200
|
},
|
|
4217
4201
|
{
|
|
4218
4202
|
"name": "Field::sgn0",
|
|
4219
|
-
"start":
|
|
4203
|
+
"start": 7455
|
|
4220
4204
|
},
|
|
4221
4205
|
{
|
|
4222
4206
|
"name": "Field::lt",
|
|
4223
|
-
"start":
|
|
4207
|
+
"start": 7538
|
|
4224
4208
|
},
|
|
4225
4209
|
{
|
|
4226
4210
|
"name": "Field::from_le_bytes",
|
|
4227
|
-
"start":
|
|
4211
|
+
"start": 7918
|
|
4228
4212
|
},
|
|
4229
4213
|
{
|
|
4230
4214
|
"name": "Field::from_be_bytes",
|
|
4231
|
-
"start":
|
|
4215
|
+
"start": 8476
|
|
4232
4216
|
},
|
|
4233
4217
|
{
|
|
4234
4218
|
"name": "__assert_max_bit_size",
|
|
4235
|
-
"start":
|
|
4219
|
+
"start": 8757
|
|
4236
4220
|
},
|
|
4237
4221
|
{
|
|
4238
4222
|
"name": "__to_le_radix",
|
|
4239
|
-
"start":
|
|
4223
|
+
"start": 8885
|
|
4240
4224
|
},
|
|
4241
4225
|
{
|
|
4242
4226
|
"name": "__to_be_radix",
|
|
4243
|
-
"start":
|
|
4227
|
+
"start": 9013
|
|
4244
4228
|
},
|
|
4245
4229
|
{
|
|
4246
4230
|
"name": "__to_le_bits",
|
|
4247
|
-
"start":
|
|
4231
|
+
"start": 9734
|
|
4248
4232
|
},
|
|
4249
4233
|
{
|
|
4250
4234
|
"name": "__to_be_bits",
|
|
4251
|
-
"start":
|
|
4235
|
+
"start": 10452
|
|
4252
4236
|
},
|
|
4253
4237
|
{
|
|
4254
4238
|
"name": "modulus_num_bits",
|
|
4255
|
-
"start":
|
|
4239
|
+
"start": 10527
|
|
4256
4240
|
},
|
|
4257
4241
|
{
|
|
4258
4242
|
"name": "modulus_be_bits",
|
|
4259
|
-
"start":
|
|
4243
|
+
"start": 10603
|
|
4260
4244
|
},
|
|
4261
4245
|
{
|
|
4262
4246
|
"name": "modulus_le_bits",
|
|
4263
|
-
"start":
|
|
4247
|
+
"start": 10679
|
|
4264
4248
|
},
|
|
4265
4249
|
{
|
|
4266
4250
|
"name": "modulus_be_bytes",
|
|
4267
|
-
"start":
|
|
4251
|
+
"start": 10755
|
|
4268
4252
|
},
|
|
4269
4253
|
{
|
|
4270
4254
|
"name": "modulus_le_bytes",
|
|
4271
|
-
"start":
|
|
4255
|
+
"start": 10831
|
|
4272
4256
|
},
|
|
4273
4257
|
{
|
|
4274
4258
|
"name": "__field_less_than",
|
|
4275
|
-
"start":
|
|
4259
|
+
"start": 10992
|
|
4276
4260
|
},
|
|
4277
4261
|
{
|
|
4278
4262
|
"name": "field_less_than",
|
|
4279
|
-
"start":
|
|
4263
|
+
"start": 11068
|
|
4280
4264
|
},
|
|
4281
4265
|
{
|
|
4282
4266
|
"name": "bytes32_to_field",
|
|
4283
|
-
"start":
|
|
4267
|
+
"start": 11210
|
|
4284
4268
|
},
|
|
4285
4269
|
{
|
|
4286
4270
|
"name": "lt_fallback",
|
|
4287
|
-
"start":
|
|
4271
|
+
"start": 11617
|
|
4288
4272
|
},
|
|
4289
4273
|
{
|
|
4290
4274
|
"name": "tests::test_to_be_bits",
|
|
4291
|
-
"start":
|
|
4275
|
+
"start": 12579
|
|
4292
4276
|
},
|
|
4293
4277
|
{
|
|
4294
4278
|
"name": "tests::test_to_le_bits",
|
|
4295
|
-
"start":
|
|
4279
|
+
"start": 12852
|
|
4296
4280
|
},
|
|
4297
4281
|
{
|
|
4298
4282
|
"name": "tests::test_to_be_bytes",
|
|
4299
|
-
"start":
|
|
4283
|
+
"start": 13127
|
|
4300
4284
|
},
|
|
4301
4285
|
{
|
|
4302
4286
|
"name": "tests::test_to_le_bytes",
|
|
4303
|
-
"start":
|
|
4287
|
+
"start": 13433
|
|
4304
4288
|
},
|
|
4305
4289
|
{
|
|
4306
4290
|
"name": "tests::test_to_be_radix",
|
|
4307
|
-
"start":
|
|
4291
|
+
"start": 13739
|
|
4308
4292
|
},
|
|
4309
4293
|
{
|
|
4310
4294
|
"name": "tests::test_to_le_radix",
|
|
4311
|
-
"start":
|
|
4295
|
+
"start": 14321
|
|
4312
4296
|
},
|
|
4313
4297
|
{
|
|
4314
4298
|
"name": "tests::test_to_le_radix_1",
|
|
4315
|
-
"start":
|
|
4299
|
+
"start": 14921
|
|
4316
4300
|
},
|
|
4317
4301
|
{
|
|
4318
4302
|
"name": "tests::test_to_le_radix_brillig_1",
|
|
4319
|
-
"start":
|
|
4303
|
+
"start": 15374
|
|
4320
4304
|
},
|
|
4321
4305
|
{
|
|
4322
4306
|
"name": "tests::test_to_le_radix_3",
|
|
4323
|
-
"start":
|
|
4307
|
+
"start": 15728
|
|
4324
4308
|
},
|
|
4325
4309
|
{
|
|
4326
4310
|
"name": "tests::test_to_le_radix_brillig_3",
|
|
4327
|
-
"start":
|
|
4311
|
+
"start": 16039
|
|
4328
4312
|
},
|
|
4329
4313
|
{
|
|
4330
4314
|
"name": "tests::test_to_le_radix_512",
|
|
4331
|
-
"start":
|
|
4315
|
+
"start": 16467
|
|
4332
4316
|
},
|
|
4333
4317
|
{
|
|
4334
4318
|
"name": "tests::not_enough_limbs_brillig",
|
|
4335
|
-
"start":
|
|
4319
|
+
"start": 16876
|
|
4336
4320
|
},
|
|
4337
4321
|
{
|
|
4338
4322
|
"name": "tests::not_enough_limbs",
|
|
4339
|
-
"start":
|
|
4323
|
+
"start": 17072
|
|
4340
4324
|
},
|
|
4341
4325
|
{
|
|
4342
4326
|
"name": "tests::test_field_less_than",
|
|
4343
|
-
"start":
|
|
4327
|
+
"start": 17214
|
|
4344
4328
|
},
|
|
4345
4329
|
{
|
|
4346
4330
|
"name": "tests::test_large_field_values_unconstrained",
|
|
4347
|
-
"start":
|
|
4331
|
+
"start": 17469
|
|
4348
4332
|
},
|
|
4349
4333
|
{
|
|
4350
4334
|
"name": "tests::test_large_field_values",
|
|
4351
|
-
"start":
|
|
4335
|
+
"start": 17922
|
|
4352
4336
|
},
|
|
4353
4337
|
{
|
|
4354
4338
|
"name": "tests::test_decomposition_edge_cases",
|
|
4355
|
-
"start":
|
|
4339
|
+
"start": 18369
|
|
4356
4340
|
},
|
|
4357
4341
|
{
|
|
4358
4342
|
"name": "tests::test_pow_32",
|
|
4359
|
-
"start":
|
|
4343
|
+
"start": 18959
|
|
4360
4344
|
},
|
|
4361
4345
|
{
|
|
4362
4346
|
"name": "tests::test_sgn0",
|
|
4363
|
-
"start":
|
|
4347
|
+
"start": 19288
|
|
4364
4348
|
},
|
|
4365
4349
|
{
|
|
4366
4350
|
"name": "tests::test_bit_decomposition_overflow",
|
|
4367
|
-
"start":
|
|
4351
|
+
"start": 19710
|
|
4368
4352
|
},
|
|
4369
4353
|
{
|
|
4370
4354
|
"name": "tests::test_byte_decomposition_overflow",
|
|
4371
|
-
"start":
|
|
4355
|
+
"start": 19992
|
|
4372
4356
|
},
|
|
4373
4357
|
{
|
|
4374
4358
|
"name": "tests::test_to_from_be_bytes_bn254_edge_cases",
|
|
4375
|
-
"start":
|
|
4359
|
+
"start": 20209
|
|
4376
4360
|
},
|
|
4377
4361
|
{
|
|
4378
4362
|
"name": "tests::test_to_from_le_bytes_bn254_edge_cases",
|
|
4379
|
-
"start":
|
|
4363
|
+
"start": 22160
|
|
4380
4364
|
},
|
|
4381
4365
|
{
|
|
4382
4366
|
"name": "tests::from_le_bits",
|
|
4383
|
-
"start":
|
|
4367
|
+
"start": 24245
|
|
4384
4368
|
},
|
|
4385
4369
|
{
|
|
4386
4370
|
"name": "tests::from_be_bits",
|
|
4387
|
-
"start":
|
|
4371
|
+
"start": 24792
|
|
4388
4372
|
},
|
|
4389
4373
|
{
|
|
4390
4374
|
"name": "tests::test_to_from_be_bits_bn254_edge_cases",
|
|
4391
|
-
"start":
|
|
4375
|
+
"start": 25038
|
|
4392
4376
|
},
|
|
4393
4377
|
{
|
|
4394
4378
|
"name": "tests::test_to_from_le_bits_bn254_edge_cases",
|
|
4395
|
-
"start":
|
|
4379
|
+
"start": 26971
|
|
4396
4380
|
}
|
|
4397
4381
|
],
|
|
4398
4382
|
"path": "std/field/mod.nr",
|
|
4399
|
-
"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"
|
|
4383
|
+
"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"
|
|
4400
4384
|
},
|
|
4401
4385
|
"18": {
|
|
4402
4386
|
"function_locations": [
|
|
@@ -4434,131 +4418,123 @@
|
|
|
4434
4418
|
},
|
|
4435
4419
|
{
|
|
4436
4420
|
"name": "pedersen_hash",
|
|
4437
|
-
"start":
|
|
4421
|
+
"start": 2380
|
|
4438
4422
|
},
|
|
4439
4423
|
{
|
|
4440
4424
|
"name": "pedersen_hash_with_separator",
|
|
4441
|
-
"start":
|
|
4425
|
+
"start": 2537
|
|
4442
4426
|
},
|
|
4443
4427
|
{
|
|
4444
4428
|
"name": "derive_generators",
|
|
4445
|
-
"start":
|
|
4429
|
+
"start": 3531
|
|
4446
4430
|
},
|
|
4447
4431
|
{
|
|
4448
4432
|
"name": "__derive_generators",
|
|
4449
|
-
"start":
|
|
4450
|
-
},
|
|
4451
|
-
{
|
|
4452
|
-
"name": "from_field_unsafe",
|
|
4453
|
-
"start": 4265
|
|
4433
|
+
"start": 3890
|
|
4454
4434
|
},
|
|
4455
4435
|
{
|
|
4456
4436
|
"name": "poseidon2_permutation",
|
|
4457
|
-
"start":
|
|
4437
|
+
"start": 3968
|
|
4458
4438
|
},
|
|
4459
4439
|
{
|
|
4460
4440
|
"name": "poseidon2_permutation_internal",
|
|
4461
|
-
"start":
|
|
4441
|
+
"start": 4324
|
|
4462
4442
|
},
|
|
4463
4443
|
{
|
|
4464
4444
|
"name": "poseidon2_config_state_size",
|
|
4465
|
-
"start":
|
|
4445
|
+
"start": 4417
|
|
4466
4446
|
},
|
|
4467
4447
|
{
|
|
4468
4448
|
"name": "derive_hash",
|
|
4469
|
-
"start":
|
|
4449
|
+
"start": 4728
|
|
4470
4450
|
},
|
|
4471
4451
|
{
|
|
4472
4452
|
"name": "<impl BuildHasher for BuildHasherDefault<H>>::build_hasher",
|
|
4473
|
-
"start":
|
|
4453
|
+
"start": 5953
|
|
4474
4454
|
},
|
|
4475
4455
|
{
|
|
4476
4456
|
"name": "<impl Default for BuildHasherDefault<H>>::default",
|
|
4477
|
-
"start":
|
|
4457
|
+
"start": 6085
|
|
4478
4458
|
},
|
|
4479
4459
|
{
|
|
4480
4460
|
"name": "<impl Hash for Field>::hash",
|
|
4481
|
-
"start":
|
|
4482
|
-
},
|
|
4483
|
-
{
|
|
4484
|
-
"name": "<impl Hash for u1>::hash",
|
|
4485
|
-
"start": 7087
|
|
4461
|
+
"start": 6217
|
|
4486
4462
|
},
|
|
4487
4463
|
{
|
|
4488
4464
|
"name": "<impl Hash for u8>::hash",
|
|
4489
|
-
"start":
|
|
4465
|
+
"start": 6347
|
|
4490
4466
|
},
|
|
4491
4467
|
{
|
|
4492
4468
|
"name": "<impl Hash for u16>::hash",
|
|
4493
|
-
"start":
|
|
4469
|
+
"start": 6487
|
|
4494
4470
|
},
|
|
4495
4471
|
{
|
|
4496
4472
|
"name": "<impl Hash for u32>::hash",
|
|
4497
|
-
"start":
|
|
4473
|
+
"start": 6627
|
|
4498
4474
|
},
|
|
4499
4475
|
{
|
|
4500
4476
|
"name": "<impl Hash for u64>::hash",
|
|
4501
|
-
"start":
|
|
4477
|
+
"start": 6767
|
|
4502
4478
|
},
|
|
4503
4479
|
{
|
|
4504
4480
|
"name": "<impl Hash for u128>::hash",
|
|
4505
|
-
"start":
|
|
4481
|
+
"start": 6908
|
|
4506
4482
|
},
|
|
4507
4483
|
{
|
|
4508
4484
|
"name": "<impl Hash for i8>::hash",
|
|
4509
|
-
"start":
|
|
4485
|
+
"start": 7047
|
|
4510
4486
|
},
|
|
4511
4487
|
{
|
|
4512
4488
|
"name": "<impl Hash for i16>::hash",
|
|
4513
|
-
"start":
|
|
4489
|
+
"start": 7193
|
|
4514
4490
|
},
|
|
4515
4491
|
{
|
|
4516
4492
|
"name": "<impl Hash for i32>::hash",
|
|
4517
|
-
"start":
|
|
4493
|
+
"start": 7340
|
|
4518
4494
|
},
|
|
4519
4495
|
{
|
|
4520
4496
|
"name": "<impl Hash for i64>::hash",
|
|
4521
|
-
"start":
|
|
4497
|
+
"start": 7487
|
|
4522
4498
|
},
|
|
4523
4499
|
{
|
|
4524
4500
|
"name": "<impl Hash for bool>::hash",
|
|
4525
|
-
"start":
|
|
4501
|
+
"start": 7635
|
|
4526
4502
|
},
|
|
4527
4503
|
{
|
|
4528
4504
|
"name": "<impl Hash for ()>::hash",
|
|
4529
|
-
"start":
|
|
4505
|
+
"start": 7782
|
|
4530
4506
|
},
|
|
4531
4507
|
{
|
|
4532
4508
|
"name": "<impl Hash for [T; N]>::hash",
|
|
4533
|
-
"start":
|
|
4509
|
+
"start": 7914
|
|
4534
4510
|
},
|
|
4535
4511
|
{
|
|
4536
4512
|
"name": "<impl Hash for [T]>::hash",
|
|
4537
|
-
"start":
|
|
4513
|
+
"start": 8103
|
|
4538
4514
|
},
|
|
4539
4515
|
{
|
|
4540
4516
|
"name": "<impl Hash for (A, B)>::hash",
|
|
4541
|
-
"start":
|
|
4517
|
+
"start": 8343
|
|
4542
4518
|
},
|
|
4543
4519
|
{
|
|
4544
4520
|
"name": "<impl Hash for (A, B, C)>::hash",
|
|
4545
|
-
"start":
|
|
4521
|
+
"start": 8559
|
|
4546
4522
|
},
|
|
4547
4523
|
{
|
|
4548
4524
|
"name": "<impl Hash for (A, B, C, D)>::hash",
|
|
4549
|
-
"start":
|
|
4525
|
+
"start": 8822
|
|
4550
4526
|
},
|
|
4551
4527
|
{
|
|
4552
4528
|
"name": "<impl Hash for (A, B, C, D, E)>::hash",
|
|
4553
|
-
"start":
|
|
4529
|
+
"start": 9132
|
|
4554
4530
|
},
|
|
4555
4531
|
{
|
|
4556
4532
|
"name": "assert_pedersen",
|
|
4557
|
-
"start":
|
|
4533
|
+
"start": 9528
|
|
4558
4534
|
}
|
|
4559
4535
|
],
|
|
4560
4536
|
"path": "std/hash/mod.nr",
|
|
4561
|
-
"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"
|
|
4537
|
+
"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"
|
|
4562
4538
|
},
|
|
4563
4539
|
"180": {
|
|
4564
4540
|
"function_locations": [
|
|
@@ -4736,39 +4712,39 @@
|
|
|
4736
4712
|
},
|
|
4737
4713
|
{
|
|
4738
4714
|
"name": "compute_tree_root",
|
|
4739
|
-
"start":
|
|
4715
|
+
"start": 1207
|
|
4740
4716
|
},
|
|
4741
4717
|
{
|
|
4742
4718
|
"name": "compute_sha_tree_root",
|
|
4743
|
-
"start":
|
|
4719
|
+
"start": 1337
|
|
4744
4720
|
},
|
|
4745
4721
|
{
|
|
4746
4722
|
"name": "compute_tree_root_with_hasher",
|
|
4747
|
-
"start":
|
|
4723
|
+
"start": 1521
|
|
4748
4724
|
},
|
|
4749
4725
|
{
|
|
4750
4726
|
"name": "compute_empty_tree_root",
|
|
4751
|
-
"start":
|
|
4727
|
+
"start": 1642
|
|
4752
4728
|
},
|
|
4753
4729
|
{
|
|
4754
4730
|
"name": "compute_empty_sha_tree_root",
|
|
4755
|
-
"start":
|
|
4731
|
+
"start": 1781
|
|
4756
4732
|
},
|
|
4757
4733
|
{
|
|
4758
4734
|
"name": "compute_empty_tree_root_with_hasher",
|
|
4759
|
-
"start":
|
|
4735
|
+
"start": 1972
|
|
4760
4736
|
},
|
|
4761
4737
|
{
|
|
4762
4738
|
"name": "test_merkle_roots_match_typescript",
|
|
4763
|
-
"start":
|
|
4739
|
+
"start": 2187
|
|
4764
4740
|
},
|
|
4765
4741
|
{
|
|
4766
4742
|
"name": "test_empty_tree_root",
|
|
4767
|
-
"start":
|
|
4743
|
+
"start": 3089
|
|
4768
4744
|
}
|
|
4769
4745
|
],
|
|
4770
4746
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/merkle_tree/root.nr",
|
|
4771
|
-
"source": "use crate::merkle_tree::merkle_tree::{compute_merkle_tree_nodes, merkle_hash, sha_merkle_hash};\n\n/// Calculate the Merkle tree root from the sibling path and leaf, using the default merkle hash.\npub fn root_from_sibling_path<let N: u32>(\n leaf: Field,\n leaf_index: Field,\n sibling_path: [Field; N],\n) -> Field {\n root_from_sibling_path_with_hasher(leaf, leaf_index, sibling_path, merkle_hash)\n}\n\n/// Calculate the Merkle tree root from the sibling path and leaf, using a custom hasher.\n///\n/// The leaf is hashed with its sibling, the result is then hashed with the next sibling in the path. and so on.\n/// The last hash is the root.\npub fn root_from_sibling_path_with_hasher<let N: u32>(\n leaf: Field,\n leaf_index: Field,\n sibling_path: [Field; N],\n hasher: fn(Field, Field) -> Field,\n) -> Field {\n let mut node = leaf;\n let indices: [
|
|
4747
|
+
"source": "use crate::merkle_tree::merkle_tree::{compute_merkle_tree_nodes, merkle_hash, sha_merkle_hash};\n\n/// Calculate the Merkle tree root from the sibling path and leaf, using the default merkle hash.\npub fn root_from_sibling_path<let N: u32>(\n leaf: Field,\n leaf_index: Field,\n sibling_path: [Field; N],\n) -> Field {\n root_from_sibling_path_with_hasher(leaf, leaf_index, sibling_path, merkle_hash)\n}\n\n/// Calculate the Merkle tree root from the sibling path and leaf, using a custom hasher.\n///\n/// The leaf is hashed with its sibling, the result is then hashed with the next sibling in the path. and so on.\n/// The last hash is the root.\npub fn root_from_sibling_path_with_hasher<let N: u32>(\n leaf: Field,\n leaf_index: Field,\n sibling_path: [Field; N],\n hasher: fn(Field, Field) -> Field,\n) -> Field {\n let mut node = leaf;\n let indices: [bool; N] = leaf_index.to_le_bits();\n\n for i in 0..N {\n let (hash_left, hash_right) = if indices[i] {\n (sibling_path[i], node)\n } else {\n (node, sibling_path[i])\n };\n node = hasher(hash_left, hash_right);\n }\n node\n}\n\npub fn compute_tree_root<let N: u32>(leaves: [Field; N]) -> Field {\n compute_tree_root_with_hasher(leaves, merkle_hash)\n}\n\npub fn compute_sha_tree_root<let N: u32>(leaves: [Field; N]) -> Field {\n compute_tree_root_with_hasher(leaves, sha_merkle_hash)\n}\n\nfn compute_tree_root_with_hasher<let N: u32>(\n leaves: [Field; N],\n hasher: fn(Field, Field) -> Field,\n) -> Field {\n compute_merkle_tree_nodes(leaves, hasher)[N - 2]\n}\n\npub fn compute_empty_tree_root<let TreeHeight: u32>() -> Field {\n compute_empty_tree_root_with_hasher::<TreeHeight>(merkle_hash)\n}\n\npub fn compute_empty_sha_tree_root<let TreeHeight: u32>() -> Field {\n compute_empty_tree_root_with_hasher::<TreeHeight>(sha_merkle_hash)\n}\n\npub fn compute_empty_tree_root_with_hasher<let TreeHeight: u32>(\n hasher: fn(Field, Field) -> Field,\n) -> Field {\n let mut hashes = [0; TreeHeight + 1];\n for i in 1..TreeHeight + 1 {\n hashes[i] = hasher(hashes[i - 1], hashes[i - 1]);\n }\n hashes[TreeHeight]\n}\n\n#[test]\nfn test_merkle_roots_match_typescript() {\n // The following hardcoded values are generated from yarn-project/foundation/src/trees/balanced_merkle_tree_root.test.ts\n\n let root = compute_tree_root([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n let expected_tree_root_from_ts =\n 0x1528946361c480e8dc1e9ae3f8c31c997625fa1ddeddc7db5ad0dce3ac58fc4c;\n assert_eq(root, expected_tree_root_from_ts);\n\n let empty_root = compute_tree_root([0; 16]);\n let expected_empty_root_from_ts =\n 0x2373ea368857ec7af97e7b470d705848e2bf93ed7bef142a490f2119bcf82d8e;\n assert_eq(empty_root, expected_empty_root_from_ts);\n\n let sha_root = compute_sha_tree_root([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);\n let expected_sha_root_from_ts =\n 0x00b007869b8a5e2a9b3b580a318e702cea04b2f5438f2e26743f545e4d1ecbdb;\n assert_eq(sha_root, expected_sha_root_from_ts);\n}\n\n#[test]\nfn test_empty_tree_root() {\n assert_eq(compute_empty_tree_root::<0>(), 0);\n\n assert_eq(\n compute_empty_tree_root::<1>(),\n 0x0b63a53787021a4a962a452c2921b3663aff1ffd8d5510540f8e659e782956f1,\n );\n\n assert_eq(\n compute_empty_tree_root::<2>(),\n 0x0e34ac2c09f45a503d2908bcb12f1cbae5fa4065759c88d501c097506a8b2290,\n );\n\n assert_eq(\n compute_empty_tree_root::<6>(),\n 0x01c28fe1059ae0237b72334700697bdf465e03df03986fe05200cadeda66bd76,\n );\n\n assert_eq(\n compute_empty_tree_root::<10>(),\n 0x2a775ea761d20435b31fa2c33ff07663e24542ffb9e7b293dfce3042eb104686,\n );\n}\n"
|
|
4772
4748
|
},
|
|
4773
4749
|
"213": {
|
|
4774
4750
|
"function_locations": [
|
|
@@ -4796,115 +4772,115 @@
|
|
|
4796
4772
|
},
|
|
4797
4773
|
{
|
|
4798
4774
|
"name": "<impl Packable for u8>::pack",
|
|
4799
|
-
"start":
|
|
4775
|
+
"start": 767
|
|
4800
4776
|
},
|
|
4801
4777
|
{
|
|
4802
4778
|
"name": "<impl Packable for u8>::unpack",
|
|
4803
|
-
"start":
|
|
4779
|
+
"start": 869
|
|
4804
4780
|
},
|
|
4805
4781
|
{
|
|
4806
4782
|
"name": "<impl Packable for u16>::pack",
|
|
4807
|
-
"start":
|
|
4783
|
+
"start": 1021
|
|
4808
4784
|
},
|
|
4809
4785
|
{
|
|
4810
4786
|
"name": "<impl Packable for u16>::unpack",
|
|
4811
|
-
"start":
|
|
4787
|
+
"start": 1123
|
|
4812
4788
|
},
|
|
4813
4789
|
{
|
|
4814
4790
|
"name": "<impl Packable for u32>::pack",
|
|
4815
|
-
"start":
|
|
4791
|
+
"start": 1276
|
|
4816
4792
|
},
|
|
4817
4793
|
{
|
|
4818
4794
|
"name": "<impl Packable for u32>::unpack",
|
|
4819
|
-
"start":
|
|
4795
|
+
"start": 1378
|
|
4820
4796
|
},
|
|
4821
4797
|
{
|
|
4822
4798
|
"name": "<impl Packable for u64>::pack",
|
|
4823
|
-
"start":
|
|
4799
|
+
"start": 1531
|
|
4824
4800
|
},
|
|
4825
4801
|
{
|
|
4826
4802
|
"name": "<impl Packable for u64>::unpack",
|
|
4827
|
-
"start":
|
|
4803
|
+
"start": 1633
|
|
4828
4804
|
},
|
|
4829
4805
|
{
|
|
4830
4806
|
"name": "<impl Packable for u128>::pack",
|
|
4831
|
-
"start":
|
|
4807
|
+
"start": 1788
|
|
4832
4808
|
},
|
|
4833
4809
|
{
|
|
4834
4810
|
"name": "<impl Packable for u128>::unpack",
|
|
4835
|
-
"start":
|
|
4811
|
+
"start": 1890
|
|
4836
4812
|
},
|
|
4837
4813
|
{
|
|
4838
4814
|
"name": "<impl Packable for Field>::pack",
|
|
4839
|
-
"start":
|
|
4815
|
+
"start": 2048
|
|
4840
4816
|
},
|
|
4841
4817
|
{
|
|
4842
4818
|
"name": "<impl Packable for Field>::unpack",
|
|
4843
|
-
"start":
|
|
4819
|
+
"start": 2141
|
|
4844
4820
|
},
|
|
4845
4821
|
{
|
|
4846
4822
|
"name": "<impl Packable for i8>::pack",
|
|
4847
|
-
"start":
|
|
4823
|
+
"start": 2285
|
|
4848
4824
|
},
|
|
4849
4825
|
{
|
|
4850
4826
|
"name": "<impl Packable for i8>::unpack",
|
|
4851
|
-
"start":
|
|
4827
|
+
"start": 2393
|
|
4852
4828
|
},
|
|
4853
4829
|
{
|
|
4854
4830
|
"name": "<impl Packable for i16>::pack",
|
|
4855
|
-
"start":
|
|
4831
|
+
"start": 2551
|
|
4856
4832
|
},
|
|
4857
4833
|
{
|
|
4858
4834
|
"name": "<impl Packable for i16>::unpack",
|
|
4859
|
-
"start":
|
|
4835
|
+
"start": 2660
|
|
4860
4836
|
},
|
|
4861
4837
|
{
|
|
4862
4838
|
"name": "<impl Packable for i32>::pack",
|
|
4863
|
-
"start":
|
|
4839
|
+
"start": 2820
|
|
4864
4840
|
},
|
|
4865
4841
|
{
|
|
4866
4842
|
"name": "<impl Packable for i32>::unpack",
|
|
4867
|
-
"start":
|
|
4843
|
+
"start": 2929
|
|
4868
4844
|
},
|
|
4869
4845
|
{
|
|
4870
4846
|
"name": "<impl Packable for i64>::pack",
|
|
4871
|
-
"start":
|
|
4847
|
+
"start": 3089
|
|
4872
4848
|
},
|
|
4873
4849
|
{
|
|
4874
4850
|
"name": "<impl Packable for i64>::unpack",
|
|
4875
|
-
"start":
|
|
4851
|
+
"start": 3198
|
|
4876
4852
|
},
|
|
4877
4853
|
{
|
|
4878
4854
|
"name": "<impl Packable for [T; M]>::pack",
|
|
4879
|
-
"start":
|
|
4855
|
+
"start": 3407
|
|
4880
4856
|
},
|
|
4881
4857
|
{
|
|
4882
4858
|
"name": "<impl Packable for [T; M]>::unpack",
|
|
4883
|
-
"start":
|
|
4859
|
+
"start": 3769
|
|
4884
4860
|
},
|
|
4885
4861
|
{
|
|
4886
4862
|
"name": "test_u16_packing",
|
|
4887
|
-
"start":
|
|
4863
|
+
"start": 4014
|
|
4888
4864
|
},
|
|
4889
4865
|
{
|
|
4890
4866
|
"name": "test_i8_packing",
|
|
4891
|
-
"start":
|
|
4867
|
+
"start": 4110
|
|
4892
4868
|
},
|
|
4893
4869
|
{
|
|
4894
4870
|
"name": "test_i16_packing",
|
|
4895
|
-
"start":
|
|
4871
|
+
"start": 4206
|
|
4896
4872
|
},
|
|
4897
4873
|
{
|
|
4898
4874
|
"name": "test_i32_packing",
|
|
4899
|
-
"start":
|
|
4875
|
+
"start": 4304
|
|
4900
4876
|
},
|
|
4901
4877
|
{
|
|
4902
4878
|
"name": "test_i64_packing",
|
|
4903
|
-
"start":
|
|
4879
|
+
"start": 4402
|
|
4904
4880
|
}
|
|
4905
4881
|
],
|
|
4906
4882
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/types/src/type_packing.nr",
|
|
4907
|
-
"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
|
|
4883
|
+
"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"
|
|
4908
4884
|
},
|
|
4909
4885
|
"240": {
|
|
4910
4886
|
"function_locations": [
|
|
@@ -4922,31 +4898,31 @@
|
|
|
4922
4898
|
},
|
|
4923
4899
|
{
|
|
4924
4900
|
"name": "Poseidon2::absorb",
|
|
4925
|
-
"start":
|
|
4901
|
+
"start": 923
|
|
4926
4902
|
},
|
|
4927
4903
|
{
|
|
4928
4904
|
"name": "Poseidon2::squeeze",
|
|
4929
|
-
"start":
|
|
4905
|
+
"start": 1453
|
|
4930
4906
|
},
|
|
4931
4907
|
{
|
|
4932
4908
|
"name": "Poseidon2::hash_internal",
|
|
4933
|
-
"start":
|
|
4909
|
+
"start": 1814
|
|
4934
4910
|
},
|
|
4935
4911
|
{
|
|
4936
4912
|
"name": "<impl Hasher for Poseidon2Hasher>::finish",
|
|
4937
|
-
"start":
|
|
4913
|
+
"start": 4105
|
|
4938
4914
|
},
|
|
4939
4915
|
{
|
|
4940
4916
|
"name": "<impl Hasher for Poseidon2Hasher>::write",
|
|
4941
|
-
"start":
|
|
4917
|
+
"start": 4426
|
|
4942
4918
|
},
|
|
4943
4919
|
{
|
|
4944
4920
|
"name": "<impl Default for Poseidon2Hasher>::default",
|
|
4945
|
-
"start":
|
|
4921
|
+
"start": 4549
|
|
4946
4922
|
}
|
|
4947
4923
|
],
|
|
4948
|
-
"path": "/home/aztec-dev/nargo/github.com/noir-lang/poseidon/v0.
|
|
4949
|
-
"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
|
|
4924
|
+
"path": "/home/aztec-dev/nargo/github.com/noir-lang/poseidon/v0.3.0/src/poseidon2.nr",
|
|
4925
|
+
"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"
|
|
4950
4926
|
},
|
|
4951
4927
|
"243": {
|
|
4952
4928
|
"function_locations": [
|
|
@@ -5028,331 +5004,315 @@
|
|
|
5028
5004
|
"function_locations": [
|
|
5029
5005
|
{
|
|
5030
5006
|
"name": "<impl Serialize for bool>::serialize",
|
|
5031
|
-
"start":
|
|
5007
|
+
"start": 693
|
|
5032
5008
|
},
|
|
5033
5009
|
{
|
|
5034
5010
|
"name": "<impl Serialize for bool>::stream_serialize",
|
|
5035
|
-
"start":
|
|
5011
|
+
"start": 914
|
|
5036
5012
|
},
|
|
5037
5013
|
{
|
|
5038
5014
|
"name": "<impl Deserialize for bool>::deserialize",
|
|
5039
|
-
"start":
|
|
5015
|
+
"start": 1082
|
|
5040
5016
|
},
|
|
5041
5017
|
{
|
|
5042
5018
|
"name": "<impl Deserialize for bool>::stream_deserialize",
|
|
5043
|
-
"start":
|
|
5044
|
-
},
|
|
5045
|
-
{
|
|
5046
|
-
"name": "<impl Serialize for u1>::serialize",
|
|
5047
|
-
"start": 1505
|
|
5048
|
-
},
|
|
5049
|
-
{
|
|
5050
|
-
"name": "<impl Serialize for u1>::stream_serialize",
|
|
5051
|
-
"start": 1726
|
|
5052
|
-
},
|
|
5053
|
-
{
|
|
5054
|
-
"name": "<impl Deserialize for u1>::deserialize",
|
|
5055
|
-
"start": 1890
|
|
5056
|
-
},
|
|
5057
|
-
{
|
|
5058
|
-
"name": "<impl Deserialize for u1>::stream_deserialize",
|
|
5059
|
-
"start": 2136
|
|
5019
|
+
"start": 1328
|
|
5060
5020
|
},
|
|
5061
5021
|
{
|
|
5062
5022
|
"name": "<impl Serialize for u8>::serialize",
|
|
5063
|
-
"start":
|
|
5023
|
+
"start": 1470
|
|
5064
5024
|
},
|
|
5065
5025
|
{
|
|
5066
5026
|
"name": "<impl Serialize for u8>::stream_serialize",
|
|
5067
|
-
"start":
|
|
5027
|
+
"start": 1691
|
|
5068
5028
|
},
|
|
5069
5029
|
{
|
|
5070
5030
|
"name": "<impl Deserialize for u8>::deserialize",
|
|
5071
|
-
"start":
|
|
5031
|
+
"start": 1855
|
|
5072
5032
|
},
|
|
5073
5033
|
{
|
|
5074
5034
|
"name": "<impl Deserialize for u8>::stream_deserialize",
|
|
5075
|
-
"start":
|
|
5035
|
+
"start": 2101
|
|
5076
5036
|
},
|
|
5077
5037
|
{
|
|
5078
5038
|
"name": "<impl Serialize for u16>::serialize",
|
|
5079
|
-
"start":
|
|
5039
|
+
"start": 2246
|
|
5080
5040
|
},
|
|
5081
5041
|
{
|
|
5082
5042
|
"name": "<impl Serialize for u16>::stream_serialize",
|
|
5083
|
-
"start":
|
|
5043
|
+
"start": 2467
|
|
5084
5044
|
},
|
|
5085
5045
|
{
|
|
5086
5046
|
"name": "<impl Deserialize for u16>::deserialize",
|
|
5087
|
-
"start":
|
|
5047
|
+
"start": 2633
|
|
5088
5048
|
},
|
|
5089
5049
|
{
|
|
5090
5050
|
"name": "<impl Deserialize for u16>::stream_deserialize",
|
|
5091
|
-
"start":
|
|
5051
|
+
"start": 2879
|
|
5092
5052
|
},
|
|
5093
5053
|
{
|
|
5094
5054
|
"name": "<impl Serialize for u32>::serialize",
|
|
5095
|
-
"start":
|
|
5055
|
+
"start": 3025
|
|
5096
5056
|
},
|
|
5097
5057
|
{
|
|
5098
5058
|
"name": "<impl Serialize for u32>::stream_serialize",
|
|
5099
|
-
"start":
|
|
5059
|
+
"start": 3246
|
|
5100
5060
|
},
|
|
5101
5061
|
{
|
|
5102
5062
|
"name": "<impl Deserialize for u32>::deserialize",
|
|
5103
|
-
"start":
|
|
5063
|
+
"start": 3412
|
|
5104
5064
|
},
|
|
5105
5065
|
{
|
|
5106
5066
|
"name": "<impl Deserialize for u32>::stream_deserialize",
|
|
5107
|
-
"start":
|
|
5067
|
+
"start": 3658
|
|
5108
5068
|
},
|
|
5109
5069
|
{
|
|
5110
5070
|
"name": "<impl Serialize for u64>::serialize",
|
|
5111
|
-
"start":
|
|
5071
|
+
"start": 3804
|
|
5112
5072
|
},
|
|
5113
5073
|
{
|
|
5114
5074
|
"name": "<impl Serialize for u64>::stream_serialize",
|
|
5115
|
-
"start":
|
|
5075
|
+
"start": 4025
|
|
5116
5076
|
},
|
|
5117
5077
|
{
|
|
5118
5078
|
"name": "<impl Deserialize for u64>::deserialize",
|
|
5119
|
-
"start":
|
|
5079
|
+
"start": 4191
|
|
5120
5080
|
},
|
|
5121
5081
|
{
|
|
5122
5082
|
"name": "<impl Deserialize for u64>::stream_deserialize",
|
|
5123
|
-
"start":
|
|
5083
|
+
"start": 4437
|
|
5124
5084
|
},
|
|
5125
5085
|
{
|
|
5126
5086
|
"name": "<impl Serialize for u128>::serialize",
|
|
5127
|
-
"start":
|
|
5087
|
+
"start": 4585
|
|
5128
5088
|
},
|
|
5129
5089
|
{
|
|
5130
5090
|
"name": "<impl Serialize for u128>::stream_serialize",
|
|
5131
|
-
"start":
|
|
5091
|
+
"start": 4806
|
|
5132
5092
|
},
|
|
5133
5093
|
{
|
|
5134
5094
|
"name": "<impl Deserialize for u128>::deserialize",
|
|
5135
|
-
"start":
|
|
5095
|
+
"start": 4974
|
|
5136
5096
|
},
|
|
5137
5097
|
{
|
|
5138
5098
|
"name": "<impl Deserialize for u128>::stream_deserialize",
|
|
5139
|
-
"start":
|
|
5099
|
+
"start": 5220
|
|
5140
5100
|
},
|
|
5141
5101
|
{
|
|
5142
5102
|
"name": "<impl Serialize for Field>::serialize",
|
|
5143
|
-
"start":
|
|
5103
|
+
"start": 5371
|
|
5144
5104
|
},
|
|
5145
5105
|
{
|
|
5146
5106
|
"name": "<impl Serialize for Field>::stream_serialize",
|
|
5147
|
-
"start":
|
|
5107
|
+
"start": 5592
|
|
5148
5108
|
},
|
|
5149
5109
|
{
|
|
5150
5110
|
"name": "<impl Deserialize for Field>::deserialize",
|
|
5151
|
-
"start":
|
|
5111
|
+
"start": 5753
|
|
5152
5112
|
},
|
|
5153
5113
|
{
|
|
5154
5114
|
"name": "<impl Deserialize for Field>::stream_deserialize",
|
|
5155
|
-
"start":
|
|
5115
|
+
"start": 5999
|
|
5156
5116
|
},
|
|
5157
5117
|
{
|
|
5158
5118
|
"name": "<impl Serialize for i8>::serialize",
|
|
5159
|
-
"start":
|
|
5119
|
+
"start": 6136
|
|
5160
5120
|
},
|
|
5161
5121
|
{
|
|
5162
5122
|
"name": "<impl Serialize for i8>::stream_serialize",
|
|
5163
|
-
"start":
|
|
5123
|
+
"start": 6357
|
|
5164
5124
|
},
|
|
5165
5125
|
{
|
|
5166
5126
|
"name": "<impl Deserialize for i8>::deserialize",
|
|
5167
|
-
"start":
|
|
5127
|
+
"start": 6527
|
|
5168
5128
|
},
|
|
5169
5129
|
{
|
|
5170
5130
|
"name": "<impl Deserialize for i8>::stream_deserialize",
|
|
5171
|
-
"start":
|
|
5131
|
+
"start": 6773
|
|
5172
5132
|
},
|
|
5173
5133
|
{
|
|
5174
5134
|
"name": "<impl Serialize for i16>::serialize",
|
|
5175
|
-
"start":
|
|
5135
|
+
"start": 6924
|
|
5176
5136
|
},
|
|
5177
5137
|
{
|
|
5178
5138
|
"name": "<impl Serialize for i16>::stream_serialize",
|
|
5179
|
-
"start":
|
|
5139
|
+
"start": 7145
|
|
5180
5140
|
},
|
|
5181
5141
|
{
|
|
5182
5142
|
"name": "<impl Deserialize for i16>::deserialize",
|
|
5183
|
-
"start":
|
|
5143
|
+
"start": 7318
|
|
5184
5144
|
},
|
|
5185
5145
|
{
|
|
5186
5146
|
"name": "<impl Deserialize for i16>::stream_deserialize",
|
|
5187
|
-
"start":
|
|
5147
|
+
"start": 7564
|
|
5188
5148
|
},
|
|
5189
5149
|
{
|
|
5190
5150
|
"name": "<impl Serialize for i32>::serialize",
|
|
5191
|
-
"start":
|
|
5151
|
+
"start": 7717
|
|
5192
5152
|
},
|
|
5193
5153
|
{
|
|
5194
5154
|
"name": "<impl Serialize for i32>::stream_serialize",
|
|
5195
|
-
"start":
|
|
5155
|
+
"start": 7938
|
|
5196
5156
|
},
|
|
5197
5157
|
{
|
|
5198
5158
|
"name": "<impl Deserialize for i32>::deserialize",
|
|
5199
|
-
"start":
|
|
5159
|
+
"start": 8111
|
|
5200
5160
|
},
|
|
5201
5161
|
{
|
|
5202
5162
|
"name": "<impl Deserialize for i32>::stream_deserialize",
|
|
5203
|
-
"start":
|
|
5163
|
+
"start": 8357
|
|
5204
5164
|
},
|
|
5205
5165
|
{
|
|
5206
5166
|
"name": "<impl Serialize for i64>::serialize",
|
|
5207
|
-
"start":
|
|
5167
|
+
"start": 8510
|
|
5208
5168
|
},
|
|
5209
5169
|
{
|
|
5210
5170
|
"name": "<impl Serialize for i64>::stream_serialize",
|
|
5211
|
-
"start":
|
|
5171
|
+
"start": 8731
|
|
5212
5172
|
},
|
|
5213
5173
|
{
|
|
5214
5174
|
"name": "<impl Deserialize for i64>::deserialize",
|
|
5215
|
-
"start":
|
|
5175
|
+
"start": 8904
|
|
5216
5176
|
},
|
|
5217
5177
|
{
|
|
5218
5178
|
"name": "<impl Deserialize for i64>::stream_deserialize",
|
|
5219
|
-
"start":
|
|
5179
|
+
"start": 9150
|
|
5220
5180
|
},
|
|
5221
5181
|
{
|
|
5222
5182
|
"name": "<impl Serialize for [T; M]>::serialize",
|
|
5223
|
-
"start":
|
|
5183
|
+
"start": 9350
|
|
5224
5184
|
},
|
|
5225
5185
|
{
|
|
5226
5186
|
"name": "<impl Serialize for [T; M]>::stream_serialize",
|
|
5227
|
-
"start":
|
|
5187
|
+
"start": 9571
|
|
5228
5188
|
},
|
|
5229
5189
|
{
|
|
5230
5190
|
"name": "<impl Deserialize for [T; M]>::deserialize",
|
|
5231
|
-
"start":
|
|
5191
|
+
"start": 9831
|
|
5232
5192
|
},
|
|
5233
5193
|
{
|
|
5234
5194
|
"name": "<impl Deserialize for [T; M]>::stream_deserialize",
|
|
5235
|
-
"start":
|
|
5195
|
+
"start": 10077
|
|
5236
5196
|
},
|
|
5237
5197
|
{
|
|
5238
5198
|
"name": "<impl Serialize for Option<T>>::serialize",
|
|
5239
|
-
"start":
|
|
5199
|
+
"start": 10389
|
|
5240
5200
|
},
|
|
5241
5201
|
{
|
|
5242
5202
|
"name": "<impl Serialize for Option<T>>::stream_serialize",
|
|
5243
|
-
"start":
|
|
5203
|
+
"start": 10610
|
|
5244
5204
|
},
|
|
5245
5205
|
{
|
|
5246
5206
|
"name": "<impl Deserialize for Option<T>>::deserialize",
|
|
5247
|
-
"start":
|
|
5207
|
+
"start": 10997
|
|
5248
5208
|
},
|
|
5249
5209
|
{
|
|
5250
5210
|
"name": "<impl Deserialize for Option<T>>::stream_deserialize",
|
|
5251
|
-
"start":
|
|
5211
|
+
"start": 11243
|
|
5252
5212
|
},
|
|
5253
5213
|
{
|
|
5254
5214
|
"name": "<impl Serialize for EmbeddedCurveScalar>::serialize",
|
|
5255
|
-
"start":
|
|
5215
|
+
"start": 11621
|
|
5256
5216
|
},
|
|
5257
5217
|
{
|
|
5258
5218
|
"name": "<impl Serialize for EmbeddedCurveScalar>::stream_serialize",
|
|
5259
|
-
"start":
|
|
5219
|
+
"start": 11744
|
|
5260
5220
|
},
|
|
5261
5221
|
{
|
|
5262
5222
|
"name": "<impl Deserialize for EmbeddedCurveScalar>::deserialize",
|
|
5263
|
-
"start":
|
|
5223
|
+
"start": 11944
|
|
5264
5224
|
},
|
|
5265
5225
|
{
|
|
5266
5226
|
"name": "<impl Deserialize for EmbeddedCurveScalar>::stream_deserialize",
|
|
5267
|
-
"start":
|
|
5227
|
+
"start": 12090
|
|
5268
5228
|
},
|
|
5269
5229
|
{
|
|
5270
5230
|
"name": "<impl Serialize for EmbeddedCurvePoint>::serialize",
|
|
5271
|
-
"start":
|
|
5231
|
+
"start": 12297
|
|
5272
5232
|
},
|
|
5273
5233
|
{
|
|
5274
5234
|
"name": "<impl Serialize for EmbeddedCurvePoint>::stream_serialize",
|
|
5275
|
-
"start":
|
|
5235
|
+
"start": 12397
|
|
5276
5236
|
},
|
|
5277
5237
|
{
|
|
5278
5238
|
"name": "<impl Deserialize for EmbeddedCurvePoint>::deserialize",
|
|
5279
|
-
"start":
|
|
5239
|
+
"start": 12593
|
|
5280
5240
|
},
|
|
5281
5241
|
{
|
|
5282
5242
|
"name": "<impl Deserialize for EmbeddedCurvePoint>::stream_deserialize",
|
|
5283
|
-
"start":
|
|
5243
|
+
"start": 12737
|
|
5284
5244
|
},
|
|
5285
5245
|
{
|
|
5286
5246
|
"name": "<impl Deserialize for str<M>>::deserialize",
|
|
5287
|
-
"start":
|
|
5247
|
+
"start": 12916
|
|
5288
5248
|
},
|
|
5289
5249
|
{
|
|
5290
5250
|
"name": "<impl Deserialize for str<M>>::stream_deserialize",
|
|
5291
|
-
"start":
|
|
5251
|
+
"start": 13162
|
|
5292
5252
|
},
|
|
5293
5253
|
{
|
|
5294
5254
|
"name": "<impl Serialize for str<M>>::serialize",
|
|
5295
|
-
"start":
|
|
5255
|
+
"start": 13395
|
|
5296
5256
|
},
|
|
5297
5257
|
{
|
|
5298
5258
|
"name": "<impl Serialize for str<M>>::stream_serialize",
|
|
5299
|
-
"start":
|
|
5259
|
+
"start": 13616
|
|
5300
5260
|
},
|
|
5301
5261
|
{
|
|
5302
5262
|
"name": "<impl Deserialize for BoundedVec<T, M>>::deserialize",
|
|
5303
|
-
"start":
|
|
5263
|
+
"start": 13997
|
|
5304
5264
|
},
|
|
5305
5265
|
{
|
|
5306
5266
|
"name": "<impl Deserialize for BoundedVec<T, M>>::stream_deserialize",
|
|
5307
|
-
"start":
|
|
5267
|
+
"start": 14243
|
|
5308
5268
|
},
|
|
5309
5269
|
{
|
|
5310
5270
|
"name": "<impl Deserialize for ()>::deserialize",
|
|
5311
|
-
"start":
|
|
5271
|
+
"start": 15299
|
|
5312
5272
|
},
|
|
5313
5273
|
{
|
|
5314
5274
|
"name": "<impl Deserialize for ()>::stream_deserialize",
|
|
5315
|
-
"start":
|
|
5275
|
+
"start": 15546
|
|
5316
5276
|
},
|
|
5317
5277
|
{
|
|
5318
5278
|
"name": "<impl Serialize for BoundedVec<T, M>>::serialize",
|
|
5319
|
-
"start":
|
|
5279
|
+
"start": 15911
|
|
5320
5280
|
},
|
|
5321
5281
|
{
|
|
5322
5282
|
"name": "<impl Serialize for BoundedVec<T, M>>::stream_serialize",
|
|
5323
|
-
"start":
|
|
5283
|
+
"start": 16132
|
|
5324
5284
|
},
|
|
5325
5285
|
{
|
|
5326
5286
|
"name": "make_slice",
|
|
5327
|
-
"start":
|
|
5287
|
+
"start": 16617
|
|
5328
5288
|
},
|
|
5329
5289
|
{
|
|
5330
5290
|
"name": "impl_serialize_for_tuple",
|
|
5331
|
-
"start":
|
|
5291
|
+
"start": 16867
|
|
5332
5292
|
},
|
|
5333
5293
|
{
|
|
5334
5294
|
"name": "<impl Serialize for (T1,)>::serialize",
|
|
5335
|
-
"start":
|
|
5295
|
+
"start": 20158
|
|
5336
5296
|
},
|
|
5337
5297
|
{
|
|
5338
5298
|
"name": "<impl Serialize for (T1,)>::stream_serialize",
|
|
5339
|
-
"start":
|
|
5299
|
+
"start": 20409
|
|
5340
5300
|
},
|
|
5341
5301
|
{
|
|
5342
5302
|
"name": "<impl Deserialize for (T1,)>::deserialize",
|
|
5343
|
-
"start":
|
|
5303
|
+
"start": 20616
|
|
5344
5304
|
},
|
|
5345
5305
|
{
|
|
5346
5306
|
"name": "<impl Deserialize for (T1,)>::stream_deserialize",
|
|
5347
|
-
"start":
|
|
5307
|
+
"start": 20877
|
|
5348
5308
|
},
|
|
5349
5309
|
{
|
|
5350
5310
|
"name": "bounded_vec_serialization",
|
|
5351
|
-
"start":
|
|
5311
|
+
"start": 21226
|
|
5352
5312
|
}
|
|
5353
5313
|
],
|
|
5354
5314
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-protocol-circuits/crates/serde/src/type_impls.nr",
|
|
5355
|
-
"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"
|
|
5315
|
+
"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"
|
|
5356
5316
|
},
|
|
5357
5317
|
"256": {
|
|
5358
5318
|
"function_locations": [
|
|
@@ -5436,148 +5396,6 @@
|
|
|
5436
5396
|
"path": "/home/aztec-dev/nargo/github.com/noir-lang/sha256/v0.3.0/src/sha256.nr",
|
|
5437
5397
|
"source": "use std::hash::sha256_compression;\nuse std::runtime::is_unconstrained;\n\nuse constants::{\n BLOCK_BYTE_PTR, BLOCK_SIZE, HASH, INITIAL_STATE, INT_BLOCK_SIZE, INT_SIZE, INT_SIZE_PTR,\n MSG_BLOCK, MSG_SIZE_PTR, STATE, TWO_POW_16, TWO_POW_24, TWO_POW_32, TWO_POW_8,\n};\n\npub(crate) mod constants;\nmod tests;\nmod oracle_tests;\n\n// Implementation of SHA-256 mapping a byte array of variable length to\n// 32 bytes.\n\n// Deprecated in favour of `sha256_var`\n// docs:start:sha256\npub fn sha256<let N: u32>(input: [u8; N]) -> HASH\n// docs:end:sha256\n{\n digest(input)\n}\n\n// SHA-256 hash function\n#[no_predicates]\npub fn digest<let N: u32>(msg: [u8; N]) -> HASH {\n sha256_var(msg, N)\n}\n\n// Variable size SHA-256 hash\npub fn sha256_var<let N: u32>(msg: [u8; N], message_size: u32) -> HASH {\n assert(message_size <= N);\n\n let (h, msg_block) = process_full_blocks(msg, message_size, INITIAL_STATE);\n\n finalize_sha256_blocks(message_size, h, msg_block)\n}\n\n/// Returns the first partially filled message block along with the internal state prior to its compression.\npub(crate) fn process_full_blocks<let N: u32>(\n msg: [u8; N],\n message_size: u32,\n initial_state: STATE,\n) -> (STATE, MSG_BLOCK) {\n if std::runtime::is_unconstrained() {\n let num_full_blocks = message_size / BLOCK_SIZE;\n // Intermediate hash, starting with the canonical initial value\n let mut h: STATE = initial_state;\n // Pointer into msg_block on a 64 byte scale\n for i in 0..num_full_blocks {\n let msg_block = build_msg_block(msg, message_size, BLOCK_SIZE * i);\n h = sha256_compression(msg_block, h);\n }\n\n // We now build the final un-filled block.\n let msg_byte_ptr = message_size % BLOCK_SIZE;\n let msg_block: MSG_BLOCK = if msg_byte_ptr != 0 {\n let num_full_blocks = message_size / BLOCK_SIZE;\n let msg_start = BLOCK_SIZE * num_full_blocks;\n build_msg_block(msg, message_size, msg_start)\n } else {\n // If the message size is a multiple of the block size (i.e. `msg_byte_ptr == 0`) then this block will be empty,\n // so we short-circuit in this case.\n [0; 16]\n };\n\n (h, msg_block)\n } else {\n let num_blocks = N / BLOCK_SIZE;\n\n // We store the intermediate hash states and message blocks in these two arrays which allows us to select the correct state\n // for the given message size with a lookup.\n //\n // These can be reasoned about as followed:\n // Consider a message with an unknown number of bytes, `msg_size. It can be seen that this will have `msg_size / BLOCK_SIZE` full blocks.\n // - `states[i]` should then be the state after processing the first `i` blocks.\n // - `blocks[i]` should then be the next message block after processing the first `i` blocks.\n // blocks[first_partially_filled_block_index] is the last block that is partially filled or all 0 if the message is a multiple of the block size.\n //\n // In other words:\n //\n // blocks = [block 1, block 2, ..., block N / BLOCK_SIZE, block N / BLOCK_SIZE + 1]\n // states = [INITIAL_STATE, state after block 1, state after block 2, ..., state after block N / BLOCK_SIZE]\n //\n // We place the initial state in `states[0]` as in the case where the `message_size < BLOCK_SIZE` then there are no full blocks to process and no compressions should occur.\n let mut blocks: [MSG_BLOCK; N / BLOCK_SIZE + 1] = std::mem::zeroed();\n let mut states: [STATE; N / BLOCK_SIZE + 1] = [initial_state; N / BLOCK_SIZE + 1];\n\n // Optimization for small messages. If the largest possible message is smaller than a block then we know that the first block is partially filled\n // no matter the value of `message_size`.\n //\n // Note that the condition `N >= BLOCK_SIZE` is known during monomorphization so this has no runtime cost.\n let first_partially_filled_block_index = if N >= BLOCK_SIZE {\n message_size / BLOCK_SIZE\n } else {\n 0\n };\n\n for i in 0..num_blocks {\n let msg_start = BLOCK_SIZE * i;\n let new_msg_block = build_msg_block(msg, message_size, msg_start);\n\n blocks[i] = new_msg_block;\n states[i + 1] = sha256_compression(new_msg_block, states[i]);\n }\n // If message_size/BLOCK_SIZE == N/BLOCK_SIZE, and there is a remainder, we need to process the last block.\n if N % BLOCK_SIZE != 0 {\n let new_msg_block = build_msg_block(msg, message_size, BLOCK_SIZE * num_blocks);\n\n blocks[num_blocks] = new_msg_block;\n }\n\n (states[first_partially_filled_block_index], blocks[first_partially_filled_block_index])\n }\n}\n\n// Take `BLOCK_SIZE` number of bytes from `msg` starting at `msg_start` and pack them into a `MSG_BLOCK`.\npub(crate) unconstrained fn build_msg_block_helper<let N: u32>(\n msg: [u8; N],\n message_size: u32,\n msg_start: u32,\n) -> MSG_BLOCK {\n let mut msg_block: MSG_BLOCK = [0; INT_BLOCK_SIZE];\n\n // We insert `BLOCK_SIZE` bytes (or up to the end of the message)\n let block_input = if message_size < msg_start {\n // This function is sometimes called with `msg_start` past the end of the message.\n // In this case we return an empty block and zero pointer to signal that the result should be ignored.\n 0\n } else if message_size < msg_start + BLOCK_SIZE {\n message_size - msg_start\n } else {\n BLOCK_SIZE\n };\n\n // Figure out the number of items in the int array that we have to pack.\n // e.g. if the input is [0,1,2,3,4,5] then we need to pack it as 2 items: [0123, 4500]\n let int_input = (block_input + INT_SIZE - 1) / INT_SIZE;\n\n for i in 0..int_input {\n let mut msg_item: u32 = 0;\n // Always construct the integer as 4 bytes, even if it means going beyond the input.\n for j in 0..INT_SIZE {\n let k = i * INT_SIZE + j;\n let msg_byte = if k < block_input {\n msg[msg_start + k]\n } else {\n 0\n };\n msg_item = (msg_item << 8) + msg_byte as u32;\n }\n msg_block[i] = msg_item;\n }\n\n // Returning the index as if it was a 64 byte array.\n // We have to project it down to 16 items and bit shifting to get a byte back if we need it.\n msg_block\n}\n\n// Build a message block from the input message starting at `msg_start`.\n//\n// If `message_size` is less than `msg_start` then this is called with the old non-empty block;\n// in that case we can skip verification, ie. no need to check that everything is zero.\nfn build_msg_block<let N: u32>(msg: [u8; N], message_size: u32, msg_start: u32) -> MSG_BLOCK {\n let msg_block =\n // Safety: We constrain the block below by reconstructing each `u32` word from the input bytes.\n unsafe { build_msg_block_helper(msg, message_size, msg_start) };\n\n if !is_unconstrained() {\n let mut msg_end = msg_start + BLOCK_SIZE;\n\n let max_read_index = std::cmp::min(message_size, msg_end);\n\n // Reconstructed packed item\n let mut msg_item: Field = 0;\n\n // Inclusive at the end so that we can compare the last item.\n for k in msg_start..=msg_end {\n if (k != msg_start) & (k % INT_SIZE == 0) {\n // If we consumed some input we can compare against the block.\n let msg_block_index = (k - msg_start) / INT_SIZE - 1;\n assert_eq(msg_block[msg_block_index] as Field, msg_item);\n\n msg_item = 0;\n }\n\n // If we have input to consume, add it at the rightmost position.\n let msg_byte = if k < max_read_index { msg[k] } else { 0 };\n msg_item = msg_item * (TWO_POW_8 as Field) + msg_byte as Field;\n }\n }\n msg_block\n}\n\n// Encode `8 * message_size` into two `u32` limbs.\nunconstrained fn encode_len(message_size: u32) -> (u32, u32) {\n let len = 8 * message_size as u64;\n let lo = len & 0xFFFFFFFF;\n let hi = (len >> 32) & 0xFFFFFFFF;\n (lo as u32, hi as u32)\n}\n\n// Write the length into the last 8 bytes of the block.\nfn attach_len_to_msg_block(mut msg_block: MSG_BLOCK, message_size: u32) -> MSG_BLOCK {\n // Safety: We assert the correctness of the decomposition below.\n // 2 `u32` limbs cannot overflow the field modulus so performing the check as `Field`s is safe.\n let (lo, hi) = unsafe { encode_len(message_size) };\n assert_eq(8 * (message_size as Field), lo as Field + hi as Field * TWO_POW_32);\n\n msg_block[INT_SIZE_PTR] = hi;\n msg_block[INT_SIZE_PTR + 1] = lo;\n msg_block\n}\n\n// Perform the final compression, then transform the `STATE` into `HASH`.\nfn hash_final_block(msg_block: MSG_BLOCK, mut state: STATE) -> HASH {\n // Hash final padded block\n state = sha256_compression(msg_block, state);\n\n // Return final hash as byte array\n let mut out_h: HASH = [0; 32]; // Digest as sequence of bytes\n for j in 0..8 {\n let h_bytes: [u8; 4] = (state[j] as Field).to_be_bytes();\n for k in 0..4 {\n out_h[4 * j + k] = h_bytes[k];\n }\n }\n\n out_h\n}\n\n/// Lookup table for the position of the padding bit within one of the `u32` words in the final message block.\nglobal PADDING_BIT_TABLE: [u32; 4] =\n [(1 << 7) * TWO_POW_24, (1 << 7) * TWO_POW_16, (1 << 7) * TWO_POW_8, (1 << 7)];\n\n/// Add 1 bit padding to end of message and compress the block if there's not enough room for the 8-byte length.\n/// Returns the updated hash state and message block that will be used to write the message size.\n///\n/// # Assumptions:\n///\n/// - `msg_block[i] == 0` for all `i > msg_byte_ptr / INT_SIZE`\n/// - `msg_block[msg_byte_ptr / INT_SIZE] & ((1 << 7) * (msg_byte_ptr % INT_SIZE)) == 0`\nfn add_padding_byte_and_compress_if_needed(\n mut msg_block: MSG_BLOCK,\n msg_byte_ptr: BLOCK_BYTE_PTR,\n h: STATE,\n) -> (STATE, MSG_BLOCK) {\n // Pad the rest such that we have a [u32; 2] block at the end representing the length\n // of the message, and a block of 1 0 ... 0 following the message (i.e. [1 << 7, 0, ..., 0]).\n // Here we rely on the fact that everything beyond the available input is set to 0.\n let index = msg_byte_ptr / INT_SIZE;\n\n // Lookup the position of the padding bit and insert it into the message block.\n msg_block[index] += PADDING_BIT_TABLE[msg_byte_ptr % INT_SIZE];\n\n // If we don't have room to write the size, compress the block and reset it.\n if msg_byte_ptr >= MSG_SIZE_PTR {\n let h = sha256_compression(msg_block, h);\n\n // In this case, the final block consists of all zeros with the last 8 bytes containing the length.\n // We set msg_block to all zeros and attach_len_to_msg_block will add the length to the last 8 bytes.\n let msg_block = [0; INT_BLOCK_SIZE];\n (h, msg_block)\n } else {\n (h, msg_block)\n }\n}\n\npub(crate) fn finalize_sha256_blocks(\n message_size: u32,\n mut h: STATE,\n mut msg_block: MSG_BLOCK,\n) -> HASH {\n let msg_byte_ptr = message_size % BLOCK_SIZE;\n\n let (h, mut msg_block) = add_padding_byte_and_compress_if_needed(msg_block, msg_byte_ptr, h);\n\n msg_block = attach_len_to_msg_block(msg_block, message_size);\n\n hash_final_block(msg_block, h)\n}\n\n/**\n * Given some state of a partially computed sha256 hash and part of the preimage, continue hashing\n * @notice used for complex/ recursive offloading of post-partial hashing\n *\n * @param N - the maximum length of the message to hash\n * @param h - the intermediate hash state\n * @param msg - the preimage to hash\n * @param message_size - the actual length of the preimage to hash\n * @return the intermediate hash state after compressing in msg to h\n */\npub fn partial_sha256_var_interstitial<let N: u32>(\n mut h: [u32; 8],\n msg: [u8; N],\n message_size: u32,\n) -> [u32; 8] {\n assert(message_size % BLOCK_SIZE == 0, \"Message size must be a multiple of the block size\");\n if std::runtime::is_unconstrained() {\n // Safety: running as an unconstrained function\n unsafe {\n __sha_partial_var_interstitial(h, msg, message_size)\n }\n } else {\n let (h, _) = process_full_blocks(msg, message_size, h);\n\n h\n }\n}\n\n/**\n * Given some state of a partially computed sha256 hash and remaining preimage, complete the hash\n * @notice used for traditional partial hashing\n *\n * @param N - the maximum length of the message to hash\n * @param h - the intermediate hash state\n * @param msg - the remaining preimage to hash\n * @param message_size - the size of the current chunk\n * @param real_message_size - the total size of the original preimage\n * @return finalized sha256 hash\n */\npub fn partial_sha256_var_end<let N: u32>(\n mut h: [u32; 8],\n msg: [u8; N],\n message_size: u32,\n real_message_size: u32,\n) -> [u8; 32] {\n assert(message_size % BLOCK_SIZE == 0, \"Message size must be a multiple of the block size\");\n if std::runtime::is_unconstrained() {\n // Safety: running as an unconstrained function\n unsafe {\n h = __sha_partial_var_interstitial(h, msg, message_size);\n\n // Handle setup of the final msg block.\n // This case is only hit if the msg is less than the block size,\n // or our message cannot be evenly split into blocks.\n\n finalize_last_sha256_block(h, real_message_size, msg)\n }\n } else {\n let (h, msg_block) = process_full_blocks(msg, message_size, h);\n finalize_sha256_blocks(real_message_size, h, msg_block)\n }\n}\n\nunconstrained fn __sha_partial_var_interstitial<let N: u32>(\n mut h: [u32; 8],\n msg: [u8; N],\n message_size: u32,\n) -> [u32; 8] {\n let num_full_blocks = message_size / BLOCK_SIZE;\n // Intermediate hash, starting with the canonical initial value\n // Pointer into msg_block on a 64 byte scale\n for i in 0..num_full_blocks {\n let msg_block = build_msg_block(msg, message_size, BLOCK_SIZE * i);\n h = sha256_compression(msg_block, h);\n }\n h\n}\n\n// Helper function to finalize the message block with padding and length\nunconstrained fn finalize_last_sha256_block<let N: u32>(\n mut h: STATE,\n message_size: u32,\n msg: [u8; N],\n) -> HASH {\n let msg_byte_ptr = message_size % BLOCK_SIZE;\n\n // We now build the final un-filled block.\n let msg_block: MSG_BLOCK = if msg_byte_ptr != 0 {\n let num_full_blocks = message_size / BLOCK_SIZE;\n let msg_start = BLOCK_SIZE * num_full_blocks;\n build_msg_block(msg, message_size, msg_start)\n } else {\n // If the message size is a multiple of the block size (i.e. `msg_byte_ptr == 0`) then this block will be empty,\n // so we short-circuit in this case.\n [0; 16]\n };\n\n // Once built, we need to add the necessary padding bytes and encoded length\n let (h, mut msg_block) = add_padding_byte_and_compress_if_needed(msg_block, msg_byte_ptr, h);\n msg_block = attach_len_to_msg_block(msg_block, message_size);\n\n hash_final_block(msg_block, h)\n}\n\nmod test_process_full_blocks {\n\n /// Wrapper to force an unconstrained runtime on process_full_blocks.\n unconstrained fn unconstrained_process_full_blocks<let N: u32>(\n msg: [u8; N],\n message_size: u32,\n h: super::STATE,\n ) -> (super::STATE, super::MSG_BLOCK) {\n super::process_full_blocks(msg, message_size, h)\n }\n\n #[test]\n fn test_implementations_agree(msg: [u8; 100], message_size: u32) {\n let message_size = message_size % 100;\n // Safety: test function\n let unconstrained_state =\n unsafe { unconstrained_process_full_blocks(msg, message_size, super::INITIAL_STATE) };\n let state = super::process_full_blocks(msg, message_size, super::INITIAL_STATE);\n assert_eq(state, unconstrained_state);\n }\n}\n\nmod test_sha256_var {\n\n /// Wrapper to force an unconstrained runtime on sha256.\n unconstrained fn unconstrained_sha256<let N: u32>(\n msg: [u8; N],\n message_size: u32,\n ) -> super::HASH {\n super::sha256_var(msg, message_size)\n }\n\n #[test]\n fn test_implementations_agree(msg: [u8; 100], message_size: u32) {\n let message_size = message_size % 100;\n // Safety: test function\n let unconstrained_sha = unsafe { unconstrained_sha256(msg, message_size) };\n let sha = super::sha256_var(msg, message_size);\n assert_eq(sha, unconstrained_sha);\n }\n\n}\n"
|
|
5438
5398
|
},
|
|
5439
|
-
"3": {
|
|
5440
|
-
"function_locations": [
|
|
5441
|
-
{
|
|
5442
|
-
"name": "[T; N]::len",
|
|
5443
|
-
"start": 480
|
|
5444
|
-
},
|
|
5445
|
-
{
|
|
5446
|
-
"name": "[T; N]::as_vector",
|
|
5447
|
-
"start": 735
|
|
5448
|
-
},
|
|
5449
|
-
{
|
|
5450
|
-
"name": "[T; N]::as_slice",
|
|
5451
|
-
"start": 1112
|
|
5452
|
-
},
|
|
5453
|
-
{
|
|
5454
|
-
"name": "[T; N]::map",
|
|
5455
|
-
"start": 1442
|
|
5456
|
-
},
|
|
5457
|
-
{
|
|
5458
|
-
"name": "[T; N]::mapi",
|
|
5459
|
-
"start": 2002
|
|
5460
|
-
},
|
|
5461
|
-
{
|
|
5462
|
-
"name": "[T; N]::for_each",
|
|
5463
|
-
"start": 2549
|
|
5464
|
-
},
|
|
5465
|
-
{
|
|
5466
|
-
"name": "[T; N]::for_eachi",
|
|
5467
|
-
"start": 2966
|
|
5468
|
-
},
|
|
5469
|
-
{
|
|
5470
|
-
"name": "[T; N]::fold",
|
|
5471
|
-
"start": 3832
|
|
5472
|
-
},
|
|
5473
|
-
{
|
|
5474
|
-
"name": "[T; N]::reduce",
|
|
5475
|
-
"start": 4349
|
|
5476
|
-
},
|
|
5477
|
-
{
|
|
5478
|
-
"name": "[T; N]::all",
|
|
5479
|
-
"start": 4858
|
|
5480
|
-
},
|
|
5481
|
-
{
|
|
5482
|
-
"name": "[T; N]::any",
|
|
5483
|
-
"start": 5330
|
|
5484
|
-
},
|
|
5485
|
-
{
|
|
5486
|
-
"name": "[T; N]::concat",
|
|
5487
|
-
"start": 5872
|
|
5488
|
-
},
|
|
5489
|
-
{
|
|
5490
|
-
"name": "[T; N]::sort",
|
|
5491
|
-
"start": 6768
|
|
5492
|
-
},
|
|
5493
|
-
{
|
|
5494
|
-
"name": "[T; N]::sort_via",
|
|
5495
|
-
"start": 7783
|
|
5496
|
-
},
|
|
5497
|
-
{
|
|
5498
|
-
"name": "[u8; N]::as_str_unchecked",
|
|
5499
|
-
"start": 8811
|
|
5500
|
-
},
|
|
5501
|
-
{
|
|
5502
|
-
"name": "<impl From<str<N>> for [u8; N]>::from",
|
|
5503
|
-
"start": 8938
|
|
5504
|
-
},
|
|
5505
|
-
{
|
|
5506
|
-
"name": "test::map_empty",
|
|
5507
|
-
"start": 9012
|
|
5508
|
-
},
|
|
5509
|
-
{
|
|
5510
|
-
"name": "test::sort_u32",
|
|
5511
|
-
"start": 10122
|
|
5512
|
-
},
|
|
5513
|
-
{
|
|
5514
|
-
"name": "test::test_sort",
|
|
5515
|
-
"start": 10177
|
|
5516
|
-
},
|
|
5517
|
-
{
|
|
5518
|
-
"name": "test::test_sort_100_values",
|
|
5519
|
-
"start": 10408
|
|
5520
|
-
},
|
|
5521
|
-
{
|
|
5522
|
-
"name": "test::test_sort_100_values_comptime",
|
|
5523
|
-
"start": 11576
|
|
5524
|
-
},
|
|
5525
|
-
{
|
|
5526
|
-
"name": "test::test_sort_via",
|
|
5527
|
-
"start": 11721
|
|
5528
|
-
},
|
|
5529
|
-
{
|
|
5530
|
-
"name": "test::test_sort_via_100_values",
|
|
5531
|
-
"start": 11968
|
|
5532
|
-
},
|
|
5533
|
-
{
|
|
5534
|
-
"name": "test::mapi_empty",
|
|
5535
|
-
"start": 13129
|
|
5536
|
-
},
|
|
5537
|
-
{
|
|
5538
|
-
"name": "test::for_each_empty",
|
|
5539
|
-
"start": 13224
|
|
5540
|
-
},
|
|
5541
|
-
{
|
|
5542
|
-
"name": "test::for_eachi_empty",
|
|
5543
|
-
"start": 13362
|
|
5544
|
-
},
|
|
5545
|
-
{
|
|
5546
|
-
"name": "test::map_example",
|
|
5547
|
-
"start": 13501
|
|
5548
|
-
},
|
|
5549
|
-
{
|
|
5550
|
-
"name": "test::mapi_example",
|
|
5551
|
-
"start": 13638
|
|
5552
|
-
},
|
|
5553
|
-
{
|
|
5554
|
-
"name": "test::for_each_example",
|
|
5555
|
-
"start": 13787
|
|
5556
|
-
},
|
|
5557
|
-
{
|
|
5558
|
-
"name": "test::for_eachi_example",
|
|
5559
|
-
"start": 14127
|
|
5560
|
-
},
|
|
5561
|
-
{
|
|
5562
|
-
"name": "test::concat",
|
|
5563
|
-
"start": 14338
|
|
5564
|
-
},
|
|
5565
|
-
{
|
|
5566
|
-
"name": "test::concat_zero_length_with_something",
|
|
5567
|
-
"start": 14597
|
|
5568
|
-
},
|
|
5569
|
-
{
|
|
5570
|
-
"name": "test::concat_something_with_zero_length",
|
|
5571
|
-
"start": 14800
|
|
5572
|
-
},
|
|
5573
|
-
{
|
|
5574
|
-
"name": "test::concat_zero_lengths",
|
|
5575
|
-
"start": 14989
|
|
5576
|
-
}
|
|
5577
|
-
],
|
|
5578
|
-
"path": "std/array/mod.nr",
|
|
5579
|
-
"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"
|
|
5580
|
-
},
|
|
5581
5399
|
"38": {
|
|
5582
5400
|
"function_locations": [
|
|
5583
5401
|
{
|
|
@@ -5604,453 +5422,417 @@
|
|
|
5604
5422
|
"name": "<impl Add for u8>::add",
|
|
5605
5423
|
"start": 630
|
|
5606
5424
|
},
|
|
5607
|
-
{
|
|
5608
|
-
"name": "<impl Add for u1>::add",
|
|
5609
|
-
"start": 713
|
|
5610
|
-
},
|
|
5611
5425
|
{
|
|
5612
5426
|
"name": "<impl Add for i8>::add",
|
|
5613
|
-
"start":
|
|
5427
|
+
"start": 713
|
|
5614
5428
|
},
|
|
5615
5429
|
{
|
|
5616
5430
|
"name": "<impl Add for i16>::add",
|
|
5617
|
-
"start":
|
|
5431
|
+
"start": 799
|
|
5618
5432
|
},
|
|
5619
5433
|
{
|
|
5620
5434
|
"name": "<impl Add for i32>::add",
|
|
5621
|
-
"start":
|
|
5435
|
+
"start": 885
|
|
5622
5436
|
},
|
|
5623
5437
|
{
|
|
5624
5438
|
"name": "<impl Add for i64>::add",
|
|
5625
|
-
"start":
|
|
5439
|
+
"start": 971
|
|
5626
5440
|
},
|
|
5627
5441
|
{
|
|
5628
5442
|
"name": "<impl Sub for Field>::sub",
|
|
5629
|
-
"start":
|
|
5443
|
+
"start": 1168
|
|
5630
5444
|
},
|
|
5631
5445
|
{
|
|
5632
5446
|
"name": "<impl Sub for u128>::sub",
|
|
5633
|
-
"start":
|
|
5447
|
+
"start": 1258
|
|
5634
5448
|
},
|
|
5635
5449
|
{
|
|
5636
5450
|
"name": "<impl Sub for u64>::sub",
|
|
5637
|
-
"start":
|
|
5451
|
+
"start": 1344
|
|
5638
5452
|
},
|
|
5639
5453
|
{
|
|
5640
5454
|
"name": "<impl Sub for u32>::sub",
|
|
5641
|
-
"start":
|
|
5455
|
+
"start": 1430
|
|
5642
5456
|
},
|
|
5643
5457
|
{
|
|
5644
5458
|
"name": "<impl Sub for u16>::sub",
|
|
5645
|
-
"start":
|
|
5459
|
+
"start": 1516
|
|
5646
5460
|
},
|
|
5647
5461
|
{
|
|
5648
5462
|
"name": "<impl Sub for u8>::sub",
|
|
5649
|
-
"start":
|
|
5650
|
-
},
|
|
5651
|
-
{
|
|
5652
|
-
"name": "<impl Sub for u1>::sub",
|
|
5653
|
-
"start": 1766
|
|
5463
|
+
"start": 1599
|
|
5654
5464
|
},
|
|
5655
5465
|
{
|
|
5656
5466
|
"name": "<impl Sub for i8>::sub",
|
|
5657
|
-
"start":
|
|
5467
|
+
"start": 1682
|
|
5658
5468
|
},
|
|
5659
5469
|
{
|
|
5660
5470
|
"name": "<impl Sub for i16>::sub",
|
|
5661
|
-
"start":
|
|
5471
|
+
"start": 1768
|
|
5662
5472
|
},
|
|
5663
5473
|
{
|
|
5664
5474
|
"name": "<impl Sub for i32>::sub",
|
|
5665
|
-
"start":
|
|
5475
|
+
"start": 1854
|
|
5666
5476
|
},
|
|
5667
5477
|
{
|
|
5668
5478
|
"name": "<impl Sub for i64>::sub",
|
|
5669
|
-
"start":
|
|
5479
|
+
"start": 1940
|
|
5670
5480
|
},
|
|
5671
5481
|
{
|
|
5672
5482
|
"name": "<impl Mul for Field>::mul",
|
|
5673
|
-
"start":
|
|
5483
|
+
"start": 2137
|
|
5674
5484
|
},
|
|
5675
5485
|
{
|
|
5676
5486
|
"name": "<impl Mul for u128>::mul",
|
|
5677
|
-
"start":
|
|
5487
|
+
"start": 2227
|
|
5678
5488
|
},
|
|
5679
5489
|
{
|
|
5680
5490
|
"name": "<impl Mul for u64>::mul",
|
|
5681
|
-
"start":
|
|
5491
|
+
"start": 2313
|
|
5682
5492
|
},
|
|
5683
5493
|
{
|
|
5684
5494
|
"name": "<impl Mul for u32>::mul",
|
|
5685
|
-
"start":
|
|
5495
|
+
"start": 2399
|
|
5686
5496
|
},
|
|
5687
5497
|
{
|
|
5688
5498
|
"name": "<impl Mul for u16>::mul",
|
|
5689
|
-
"start":
|
|
5499
|
+
"start": 2485
|
|
5690
5500
|
},
|
|
5691
5501
|
{
|
|
5692
5502
|
"name": "<impl Mul for u8>::mul",
|
|
5693
|
-
"start":
|
|
5694
|
-
},
|
|
5695
|
-
{
|
|
5696
|
-
"name": "<impl Mul for u1>::mul",
|
|
5697
|
-
"start": 2819
|
|
5503
|
+
"start": 2568
|
|
5698
5504
|
},
|
|
5699
5505
|
{
|
|
5700
5506
|
"name": "<impl Mul for i8>::mul",
|
|
5701
|
-
"start":
|
|
5507
|
+
"start": 2651
|
|
5702
5508
|
},
|
|
5703
5509
|
{
|
|
5704
5510
|
"name": "<impl Mul for i16>::mul",
|
|
5705
|
-
"start":
|
|
5511
|
+
"start": 2737
|
|
5706
5512
|
},
|
|
5707
5513
|
{
|
|
5708
5514
|
"name": "<impl Mul for i32>::mul",
|
|
5709
|
-
"start":
|
|
5515
|
+
"start": 2823
|
|
5710
5516
|
},
|
|
5711
5517
|
{
|
|
5712
5518
|
"name": "<impl Mul for i64>::mul",
|
|
5713
|
-
"start":
|
|
5519
|
+
"start": 2909
|
|
5714
5520
|
},
|
|
5715
5521
|
{
|
|
5716
5522
|
"name": "<impl Div for Field>::div",
|
|
5717
|
-
"start":
|
|
5523
|
+
"start": 3106
|
|
5718
5524
|
},
|
|
5719
5525
|
{
|
|
5720
5526
|
"name": "<impl Div for u128>::div",
|
|
5721
|
-
"start":
|
|
5527
|
+
"start": 3196
|
|
5722
5528
|
},
|
|
5723
5529
|
{
|
|
5724
5530
|
"name": "<impl Div for u64>::div",
|
|
5725
|
-
"start":
|
|
5531
|
+
"start": 3282
|
|
5726
5532
|
},
|
|
5727
5533
|
{
|
|
5728
5534
|
"name": "<impl Div for u32>::div",
|
|
5729
|
-
"start":
|
|
5535
|
+
"start": 3368
|
|
5730
5536
|
},
|
|
5731
5537
|
{
|
|
5732
5538
|
"name": "<impl Div for u16>::div",
|
|
5733
|
-
"start":
|
|
5539
|
+
"start": 3454
|
|
5734
5540
|
},
|
|
5735
5541
|
{
|
|
5736
5542
|
"name": "<impl Div for u8>::div",
|
|
5737
|
-
"start":
|
|
5738
|
-
},
|
|
5739
|
-
{
|
|
5740
|
-
"name": "<impl Div for u1>::div",
|
|
5741
|
-
"start": 3872
|
|
5543
|
+
"start": 3537
|
|
5742
5544
|
},
|
|
5743
5545
|
{
|
|
5744
5546
|
"name": "<impl Div for i8>::div",
|
|
5745
|
-
"start":
|
|
5547
|
+
"start": 3620
|
|
5746
5548
|
},
|
|
5747
5549
|
{
|
|
5748
5550
|
"name": "<impl Div for i16>::div",
|
|
5749
|
-
"start":
|
|
5551
|
+
"start": 3706
|
|
5750
5552
|
},
|
|
5751
5553
|
{
|
|
5752
5554
|
"name": "<impl Div for i32>::div",
|
|
5753
|
-
"start":
|
|
5555
|
+
"start": 3792
|
|
5754
5556
|
},
|
|
5755
5557
|
{
|
|
5756
5558
|
"name": "<impl Div for i64>::div",
|
|
5757
|
-
"start":
|
|
5559
|
+
"start": 3878
|
|
5758
5560
|
},
|
|
5759
5561
|
{
|
|
5760
5562
|
"name": "<impl Rem for u128>::rem",
|
|
5761
|
-
"start":
|
|
5563
|
+
"start": 4072
|
|
5762
5564
|
},
|
|
5763
5565
|
{
|
|
5764
5566
|
"name": "<impl Rem for u64>::rem",
|
|
5765
|
-
"start":
|
|
5567
|
+
"start": 4158
|
|
5766
5568
|
},
|
|
5767
5569
|
{
|
|
5768
5570
|
"name": "<impl Rem for u32>::rem",
|
|
5769
|
-
"start":
|
|
5571
|
+
"start": 4244
|
|
5770
5572
|
},
|
|
5771
5573
|
{
|
|
5772
5574
|
"name": "<impl Rem for u16>::rem",
|
|
5773
|
-
"start":
|
|
5575
|
+
"start": 4330
|
|
5774
5576
|
},
|
|
5775
5577
|
{
|
|
5776
5578
|
"name": "<impl Rem for u8>::rem",
|
|
5777
|
-
"start":
|
|
5778
|
-
},
|
|
5779
|
-
{
|
|
5780
|
-
"name": "<impl Rem for u1>::rem",
|
|
5781
|
-
"start": 4832
|
|
5579
|
+
"start": 4413
|
|
5782
5580
|
},
|
|
5783
5581
|
{
|
|
5784
5582
|
"name": "<impl Rem for i8>::rem",
|
|
5785
|
-
"start":
|
|
5583
|
+
"start": 4496
|
|
5786
5584
|
},
|
|
5787
5585
|
{
|
|
5788
5586
|
"name": "<impl Rem for i16>::rem",
|
|
5789
|
-
"start":
|
|
5587
|
+
"start": 4582
|
|
5790
5588
|
},
|
|
5791
5589
|
{
|
|
5792
5590
|
"name": "<impl Rem for i32>::rem",
|
|
5793
|
-
"start":
|
|
5591
|
+
"start": 4668
|
|
5794
5592
|
},
|
|
5795
5593
|
{
|
|
5796
5594
|
"name": "<impl Rem for i64>::rem",
|
|
5797
|
-
"start":
|
|
5595
|
+
"start": 4754
|
|
5798
5596
|
},
|
|
5799
5597
|
{
|
|
5800
5598
|
"name": "<impl Neg for Field>::neg",
|
|
5801
|
-
"start":
|
|
5599
|
+
"start": 4954
|
|
5802
5600
|
},
|
|
5803
5601
|
{
|
|
5804
5602
|
"name": "<impl Neg for i8>::neg",
|
|
5805
|
-
"start":
|
|
5603
|
+
"start": 5020
|
|
5806
5604
|
},
|
|
5807
5605
|
{
|
|
5808
5606
|
"name": "<impl Neg for i16>::neg",
|
|
5809
|
-
"start":
|
|
5607
|
+
"start": 5087
|
|
5810
5608
|
},
|
|
5811
5609
|
{
|
|
5812
5610
|
"name": "<impl Neg for i32>::neg",
|
|
5813
|
-
"start":
|
|
5611
|
+
"start": 5154
|
|
5814
5612
|
},
|
|
5815
5613
|
{
|
|
5816
5614
|
"name": "<impl Neg for i64>::neg",
|
|
5817
|
-
"start":
|
|
5818
|
-
},
|
|
5819
|
-
{
|
|
5820
|
-
"name": "<impl WrappingAdd for u1>::wrapping_add",
|
|
5821
|
-
"start": 5898
|
|
5615
|
+
"start": 5221
|
|
5822
5616
|
},
|
|
5823
5617
|
{
|
|
5824
5618
|
"name": "<impl WrappingAdd for u8>::wrapping_add",
|
|
5825
|
-
"start":
|
|
5619
|
+
"start": 5478
|
|
5826
5620
|
},
|
|
5827
5621
|
{
|
|
5828
5622
|
"name": "<impl WrappingAdd for u16>::wrapping_add",
|
|
5829
|
-
"start":
|
|
5623
|
+
"start": 5596
|
|
5830
5624
|
},
|
|
5831
5625
|
{
|
|
5832
5626
|
"name": "<impl WrappingAdd for u32>::wrapping_add",
|
|
5833
|
-
"start":
|
|
5627
|
+
"start": 5714
|
|
5834
5628
|
},
|
|
5835
5629
|
{
|
|
5836
5630
|
"name": "<impl WrappingAdd for u64>::wrapping_add",
|
|
5837
|
-
"start":
|
|
5631
|
+
"start": 5832
|
|
5838
5632
|
},
|
|
5839
5633
|
{
|
|
5840
5634
|
"name": "<impl WrappingAdd for u128>::wrapping_add",
|
|
5841
|
-
"start":
|
|
5635
|
+
"start": 5954
|
|
5842
5636
|
},
|
|
5843
5637
|
{
|
|
5844
5638
|
"name": "<impl WrappingAdd for i8>::wrapping_add",
|
|
5845
|
-
"start":
|
|
5639
|
+
"start": 6068
|
|
5846
5640
|
},
|
|
5847
5641
|
{
|
|
5848
5642
|
"name": "<impl WrappingAdd for i16>::wrapping_add",
|
|
5849
|
-
"start":
|
|
5643
|
+
"start": 6218
|
|
5850
5644
|
},
|
|
5851
5645
|
{
|
|
5852
5646
|
"name": "<impl WrappingAdd for i32>::wrapping_add",
|
|
5853
|
-
"start":
|
|
5647
|
+
"start": 6371
|
|
5854
5648
|
},
|
|
5855
5649
|
{
|
|
5856
5650
|
"name": "<impl WrappingAdd for i64>::wrapping_add",
|
|
5857
|
-
"start":
|
|
5651
|
+
"start": 6524
|
|
5858
5652
|
},
|
|
5859
5653
|
{
|
|
5860
5654
|
"name": "<impl WrappingAdd for Field>::wrapping_add",
|
|
5861
|
-
"start":
|
|
5862
|
-
},
|
|
5863
|
-
{
|
|
5864
|
-
"name": "<impl WrappingSub for u1>::wrapping_sub",
|
|
5865
|
-
"start": 7435
|
|
5655
|
+
"start": 6684
|
|
5866
5656
|
},
|
|
5867
5657
|
{
|
|
5868
5658
|
"name": "<impl WrappingSub for u8>::wrapping_sub",
|
|
5869
|
-
"start":
|
|
5659
|
+
"start": 6918
|
|
5870
5660
|
},
|
|
5871
5661
|
{
|
|
5872
5662
|
"name": "<impl WrappingSub for u16>::wrapping_sub",
|
|
5873
|
-
"start":
|
|
5663
|
+
"start": 7042
|
|
5874
5664
|
},
|
|
5875
5665
|
{
|
|
5876
5666
|
"name": "<impl WrappingSub for u32>::wrapping_sub",
|
|
5877
|
-
"start":
|
|
5667
|
+
"start": 7167
|
|
5878
5668
|
},
|
|
5879
5669
|
{
|
|
5880
5670
|
"name": "<impl WrappingSub for u64>::wrapping_sub",
|
|
5881
|
-
"start":
|
|
5671
|
+
"start": 7291
|
|
5882
5672
|
},
|
|
5883
5673
|
{
|
|
5884
5674
|
"name": "<impl WrappingSub for u128>::wrapping_sub",
|
|
5885
|
-
"start":
|
|
5675
|
+
"start": 7419
|
|
5886
5676
|
},
|
|
5887
5677
|
{
|
|
5888
5678
|
"name": "<impl WrappingSub for i8>::wrapping_sub",
|
|
5889
|
-
"start":
|
|
5679
|
+
"start": 7541
|
|
5890
5680
|
},
|
|
5891
5681
|
{
|
|
5892
5682
|
"name": "<impl WrappingSub for i16>::wrapping_sub",
|
|
5893
|
-
"start":
|
|
5683
|
+
"start": 7691
|
|
5894
5684
|
},
|
|
5895
5685
|
{
|
|
5896
5686
|
"name": "<impl WrappingSub for i32>::wrapping_sub",
|
|
5897
|
-
"start":
|
|
5687
|
+
"start": 7844
|
|
5898
5688
|
},
|
|
5899
5689
|
{
|
|
5900
5690
|
"name": "<impl WrappingSub for i64>::wrapping_sub",
|
|
5901
|
-
"start":
|
|
5691
|
+
"start": 7996
|
|
5902
5692
|
},
|
|
5903
5693
|
{
|
|
5904
5694
|
"name": "<impl WrappingSub for Field>::wrapping_sub",
|
|
5905
|
-
"start":
|
|
5906
|
-
},
|
|
5907
|
-
{
|
|
5908
|
-
"name": "<impl WrappingMul for u1>::wrapping_mul",
|
|
5909
|
-
"start": 9004
|
|
5695
|
+
"start": 8156
|
|
5910
5696
|
},
|
|
5911
5697
|
{
|
|
5912
5698
|
"name": "<impl WrappingMul for u8>::wrapping_mul",
|
|
5913
|
-
"start":
|
|
5699
|
+
"start": 8390
|
|
5914
5700
|
},
|
|
5915
5701
|
{
|
|
5916
5702
|
"name": "<impl WrappingMul for u16>::wrapping_mul",
|
|
5917
|
-
"start":
|
|
5703
|
+
"start": 8508
|
|
5918
5704
|
},
|
|
5919
5705
|
{
|
|
5920
5706
|
"name": "<impl WrappingMul for u32>::wrapping_mul",
|
|
5921
|
-
"start":
|
|
5707
|
+
"start": 8626
|
|
5922
5708
|
},
|
|
5923
5709
|
{
|
|
5924
5710
|
"name": "<impl WrappingMul for u64>::wrapping_mul",
|
|
5925
|
-
"start":
|
|
5711
|
+
"start": 8743
|
|
5926
5712
|
},
|
|
5927
5713
|
{
|
|
5928
5714
|
"name": "<impl WrappingMul for i8>::wrapping_mul",
|
|
5929
|
-
"start":
|
|
5715
|
+
"start": 8857
|
|
5930
5716
|
},
|
|
5931
5717
|
{
|
|
5932
5718
|
"name": "<impl WrappingMul for i16>::wrapping_mul",
|
|
5933
|
-
"start":
|
|
5719
|
+
"start": 9007
|
|
5934
5720
|
},
|
|
5935
5721
|
{
|
|
5936
5722
|
"name": "<impl WrappingMul for i32>::wrapping_mul",
|
|
5937
|
-
"start":
|
|
5723
|
+
"start": 9160
|
|
5938
5724
|
},
|
|
5939
5725
|
{
|
|
5940
5726
|
"name": "<impl WrappingMul for i64>::wrapping_mul",
|
|
5941
|
-
"start":
|
|
5727
|
+
"start": 9313
|
|
5942
5728
|
},
|
|
5943
5729
|
{
|
|
5944
5730
|
"name": "<impl WrappingMul for u128>::wrapping_mul",
|
|
5945
|
-
"start":
|
|
5731
|
+
"start": 9470
|
|
5946
5732
|
},
|
|
5947
5733
|
{
|
|
5948
5734
|
"name": "<impl WrappingMul for Field>::wrapping_mul",
|
|
5949
|
-
"start":
|
|
5735
|
+
"start": 9598
|
|
5950
5736
|
},
|
|
5951
5737
|
{
|
|
5952
5738
|
"name": "wrapping_add_hlp",
|
|
5953
|
-
"start":
|
|
5739
|
+
"start": 9726
|
|
5954
5740
|
},
|
|
5955
5741
|
{
|
|
5956
5742
|
"name": "wrapping_sub_hlp",
|
|
5957
|
-
"start":
|
|
5743
|
+
"start": 9848
|
|
5958
5744
|
},
|
|
5959
5745
|
{
|
|
5960
5746
|
"name": "wrapping_mul_hlp",
|
|
5961
|
-
"start":
|
|
5747
|
+
"start": 10103
|
|
5962
5748
|
},
|
|
5963
5749
|
{
|
|
5964
5750
|
"name": "split64",
|
|
5965
|
-
"start":
|
|
5751
|
+
"start": 10295
|
|
5966
5752
|
},
|
|
5967
5753
|
{
|
|
5968
5754
|
"name": "split_into_64_bit_limbs",
|
|
5969
|
-
"start":
|
|
5755
|
+
"start": 10528
|
|
5970
5756
|
},
|
|
5971
5757
|
{
|
|
5972
5758
|
"name": "wrapping_mul128_hlp",
|
|
5973
|
-
"start":
|
|
5759
|
+
"start": 10787
|
|
5974
5760
|
},
|
|
5975
5761
|
{
|
|
5976
5762
|
"name": "tests::test_static_assert_custom_message",
|
|
5977
|
-
"start":
|
|
5763
|
+
"start": 11507
|
|
5978
5764
|
},
|
|
5979
5765
|
{
|
|
5980
5766
|
"name": "tests::arithmetic::test_basic_arithmetic_traits",
|
|
5981
|
-
"start":
|
|
5767
|
+
"start": 11714
|
|
5982
5768
|
},
|
|
5983
5769
|
{
|
|
5984
5770
|
"name": "tests::arithmetic::test_division",
|
|
5985
|
-
"start":
|
|
5771
|
+
"start": 12477
|
|
5986
5772
|
},
|
|
5987
5773
|
{
|
|
5988
5774
|
"name": "tests::arithmetic::test_u8_sub_overflow_failure",
|
|
5989
|
-
"start":
|
|
5775
|
+
"start": 13029
|
|
5990
5776
|
},
|
|
5991
5777
|
{
|
|
5992
5778
|
"name": "tests::arithmetic::test_u8_add_overflow_failure",
|
|
5993
|
-
"start":
|
|
5779
|
+
"start": 13147
|
|
5994
5780
|
},
|
|
5995
5781
|
{
|
|
5996
5782
|
"name": "tests::arithmetic::test_u8_mul_overflow_failure",
|
|
5997
|
-
"start":
|
|
5783
|
+
"start": 13267
|
|
5998
5784
|
},
|
|
5999
5785
|
{
|
|
6000
5786
|
"name": "tests::arithmetic::test_u16_sub_overflow_failure",
|
|
6001
|
-
"start":
|
|
5787
|
+
"start": 13388
|
|
6002
5788
|
},
|
|
6003
5789
|
{
|
|
6004
5790
|
"name": "tests::arithmetic::test_u16_add_overflow_failure",
|
|
6005
|
-
"start":
|
|
5791
|
+
"start": 13509
|
|
6006
5792
|
},
|
|
6007
5793
|
{
|
|
6008
5794
|
"name": "tests::arithmetic::test_u16_mul_overflow_failure",
|
|
6009
|
-
"start":
|
|
5795
|
+
"start": 13634
|
|
6010
5796
|
},
|
|
6011
5797
|
{
|
|
6012
5798
|
"name": "tests::arithmetic::test_signed_sub_overflow_failure",
|
|
6013
|
-
"start":
|
|
5799
|
+
"start": 13762
|
|
6014
5800
|
},
|
|
6015
5801
|
{
|
|
6016
5802
|
"name": "tests::arithmetic::test_signed_overflow_failure",
|
|
6017
|
-
"start":
|
|
5803
|
+
"start": 13912
|
|
6018
5804
|
},
|
|
6019
5805
|
{
|
|
6020
5806
|
"name": "tests::arithmetic::test_field",
|
|
6021
|
-
"start":
|
|
5807
|
+
"start": 14001
|
|
6022
5808
|
},
|
|
6023
5809
|
{
|
|
6024
5810
|
"name": "tests::wrapping_arithmetic::test_wrapping_add",
|
|
6025
|
-
"start":
|
|
5811
|
+
"start": 14598
|
|
6026
5812
|
},
|
|
6027
5813
|
{
|
|
6028
5814
|
"name": "tests::wrapping_arithmetic::test_wrapping_sub",
|
|
6029
|
-
"start":
|
|
5815
|
+
"start": 16348
|
|
6030
5816
|
},
|
|
6031
5817
|
{
|
|
6032
5818
|
"name": "tests::wrapping_arithmetic::test_wrapping_mul",
|
|
6033
|
-
"start":
|
|
6034
|
-
},
|
|
6035
|
-
{
|
|
6036
|
-
"name": "tests::wrapping_arithmetic::test_u1_behavior",
|
|
6037
|
-
"start": 20534
|
|
5819
|
+
"start": 17688
|
|
6038
5820
|
},
|
|
6039
5821
|
{
|
|
6040
5822
|
"name": "tests::wrapping_arithmetic::test_wrapping_vs_regular",
|
|
6041
|
-
"start":
|
|
5823
|
+
"start": 19905
|
|
6042
5824
|
},
|
|
6043
5825
|
{
|
|
6044
5826
|
"name": "tests::wrapping_arithmetic::test_field_wrapping_operations",
|
|
6045
|
-
"start":
|
|
5827
|
+
"start": 20538
|
|
6046
5828
|
},
|
|
6047
5829
|
{
|
|
6048
5830
|
"name": "tests::split_functions::test_split_functions",
|
|
6049
|
-
"start":
|
|
5831
|
+
"start": 21622
|
|
6050
5832
|
}
|
|
6051
5833
|
],
|
|
6052
5834
|
"path": "std/ops/arith.nr",
|
|
6053
|
-
"source": "use crate::convert::AsPrimitive;\n\n// docs:start:add-trait\npub trait Add {\n fn add(self, other: Self) -> Self;\n}\n// docs:end:add-trait\n\nimpl Add for Field {\n fn add(self, other: Field) -> Field {\n self + other\n }\n}\n\nimpl Add for u128 {\n fn add(self, other: u128) -> u128 {\n self + other\n }\n}\nimpl Add for u64 {\n fn add(self, other: u64) -> u64 {\n self + other\n }\n}\nimpl Add for u32 {\n fn add(self, other: u32) -> u32 {\n self + other\n }\n}\nimpl Add for u16 {\n fn add(self, other: u16) -> u16 {\n self + other\n }\n}\nimpl Add for u8 {\n fn add(self, other: u8) -> u8 {\n self + other\n }\n}\nimpl Add for u1 {\n fn add(self, other: u1) -> u1 {\n self + other\n }\n}\n\nimpl Add for i8 {\n fn add(self, other: i8) -> i8 {\n self + other\n }\n}\nimpl Add for i16 {\n fn add(self, other: i16) -> i16 {\n self + other\n }\n}\nimpl Add for i32 {\n fn add(self, other: i32) -> i32 {\n self + other\n }\n}\nimpl Add for i64 {\n fn add(self, other: i64) -> i64 {\n self + other\n }\n}\n\n// docs:start:sub-trait\npub trait Sub {\n fn sub(self, other: Self) -> Self;\n}\n// docs:end:sub-trait\n\nimpl Sub for Field {\n fn sub(self, other: Field) -> Field {\n self - other\n }\n}\n\nimpl Sub for u128 {\n fn sub(self, other: u128) -> u128 {\n self - other\n }\n}\nimpl Sub for u64 {\n fn sub(self, other: u64) -> u64 {\n self - other\n }\n}\nimpl Sub for u32 {\n fn sub(self, other: u32) -> u32 {\n self - other\n }\n}\nimpl Sub for u16 {\n fn sub(self, other: u16) -> u16 {\n self - other\n }\n}\nimpl Sub for u8 {\n fn sub(self, other: u8) -> u8 {\n self - other\n }\n}\nimpl Sub for u1 {\n fn sub(self, other: u1) -> u1 {\n self - other\n }\n}\n\nimpl Sub for i8 {\n fn sub(self, other: i8) -> i8 {\n self - other\n }\n}\nimpl Sub for i16 {\n fn sub(self, other: i16) -> i16 {\n self - other\n }\n}\nimpl Sub for i32 {\n fn sub(self, other: i32) -> i32 {\n self - other\n }\n}\nimpl Sub for i64 {\n fn sub(self, other: i64) -> i64 {\n self - other\n }\n}\n\n// docs:start:mul-trait\npub trait Mul {\n fn mul(self, other: Self) -> Self;\n}\n// docs:end:mul-trait\n\nimpl Mul for Field {\n fn mul(self, other: Field) -> Field {\n self * other\n }\n}\n\nimpl Mul for u128 {\n fn mul(self, other: u128) -> u128 {\n self * other\n }\n}\nimpl Mul for u64 {\n fn mul(self, other: u64) -> u64 {\n self * other\n }\n}\nimpl Mul for u32 {\n fn mul(self, other: u32) -> u32 {\n self * other\n }\n}\nimpl Mul for u16 {\n fn mul(self, other: u16) -> u16 {\n self * other\n }\n}\nimpl Mul for u8 {\n fn mul(self, other: u8) -> u8 {\n self * other\n }\n}\nimpl Mul for u1 {\n fn mul(self, other: u1) -> u1 {\n self * other\n }\n}\n\nimpl Mul for i8 {\n fn mul(self, other: i8) -> i8 {\n self * other\n }\n}\nimpl Mul for i16 {\n fn mul(self, other: i16) -> i16 {\n self * other\n }\n}\nimpl Mul for i32 {\n fn mul(self, other: i32) -> i32 {\n self * other\n }\n}\nimpl Mul for i64 {\n fn mul(self, other: i64) -> i64 {\n self * other\n }\n}\n\n// docs:start:div-trait\npub trait Div {\n fn div(self, other: Self) -> Self;\n}\n// docs:end:div-trait\n\nimpl Div for Field {\n fn div(self, other: Field) -> Field {\n self / other\n }\n}\n\nimpl Div for u128 {\n fn div(self, other: u128) -> u128 {\n self / other\n }\n}\nimpl Div for u64 {\n fn div(self, other: u64) -> u64 {\n self / other\n }\n}\nimpl Div for u32 {\n fn div(self, other: u32) -> u32 {\n self / other\n }\n}\nimpl Div for u16 {\n fn div(self, other: u16) -> u16 {\n self / other\n }\n}\nimpl Div for u8 {\n fn div(self, other: u8) -> u8 {\n self / other\n }\n}\nimpl Div for u1 {\n fn div(self, other: u1) -> u1 {\n self / other\n }\n}\n\nimpl Div for i8 {\n fn div(self, other: i8) -> i8 {\n self / other\n }\n}\nimpl Div for i16 {\n fn div(self, other: i16) -> i16 {\n self / other\n }\n}\nimpl Div for i32 {\n fn div(self, other: i32) -> i32 {\n self / other\n }\n}\nimpl Div for i64 {\n fn div(self, other: i64) -> i64 {\n self / other\n }\n}\n\n// docs:start:rem-trait\npub trait Rem {\n fn rem(self, other: Self) -> Self;\n}\n// docs:end:rem-trait\n\nimpl Rem for u128 {\n fn rem(self, other: u128) -> u128 {\n self % other\n }\n}\nimpl Rem for u64 {\n fn rem(self, other: u64) -> u64 {\n self % other\n }\n}\nimpl Rem for u32 {\n fn rem(self, other: u32) -> u32 {\n self % other\n }\n}\nimpl Rem for u16 {\n fn rem(self, other: u16) -> u16 {\n self % other\n }\n}\nimpl Rem for u8 {\n fn rem(self, other: u8) -> u8 {\n self % other\n }\n}\nimpl Rem for u1 {\n fn rem(self, other: u1) -> u1 {\n self % other\n }\n}\n\nimpl Rem for i8 {\n fn rem(self, other: i8) -> i8 {\n self % other\n }\n}\nimpl Rem for i16 {\n fn rem(self, other: i16) -> i16 {\n self % other\n }\n}\nimpl Rem for i32 {\n fn rem(self, other: i32) -> i32 {\n self % other\n }\n}\nimpl Rem for i64 {\n fn rem(self, other: i64) -> i64 {\n self % other\n }\n}\n\n// docs:start:neg-trait\npub trait Neg {\n fn neg(self) -> Self;\n}\n// docs:end:neg-trait\n\n// docs:start:neg-trait-impls\nimpl Neg for Field {\n fn neg(self) -> Field {\n -self\n }\n}\n\nimpl Neg for i8 {\n fn neg(self) -> i8 {\n -self\n }\n}\nimpl Neg for i16 {\n fn neg(self) -> i16 {\n -self\n }\n}\nimpl Neg for i32 {\n fn neg(self) -> i32 {\n -self\n }\n}\nimpl Neg for i64 {\n fn neg(self) -> i64 {\n -self\n }\n}\n// docs:end:neg-trait-impls\n\n// docs:start:wrapping-add-trait\npub trait WrappingAdd {\n fn wrapping_add(self, y: Self) -> Self;\n}\n// docs:end:wrapping-add-trait\n\nimpl WrappingAdd for u1 {\n fn wrapping_add(self: u1, y: u1) -> u1 {\n self ^ y\n }\n}\n\nimpl WrappingAdd for u8 {\n fn wrapping_add(self: u8, y: u8) -> u8 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u16 {\n fn wrapping_add(self: u16, y: u16) -> u16 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u32 {\n fn wrapping_add(self: u32, y: u32) -> u32 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u64 {\n fn wrapping_add(self: u64, y: u64) -> u64 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u128 {\n fn wrapping_add(self: u128, y: u128) -> u128 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for i8 {\n fn wrapping_add(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_add(y as u8) as i8\n }\n}\n\nimpl WrappingAdd for i16 {\n fn wrapping_add(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_add(y as u16) as i16\n }\n}\n\nimpl WrappingAdd for i32 {\n fn wrapping_add(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_add(y as u32) as i32\n }\n}\n\nimpl WrappingAdd for i64 {\n fn wrapping_add(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_add(y as u64) as i64\n }\n}\nimpl WrappingAdd for Field {\n fn wrapping_add(self: Field, y: Field) -> Field {\n self + y\n }\n}\n\n// docs:start:wrapping-sub-trait\npub trait WrappingSub {\n fn wrapping_sub(self, y: Self) -> Self;\n}\n// docs:start:wrapping-sub-trait\n\nimpl WrappingSub for u1 {\n fn wrapping_sub(self: u1, y: u1) -> u1 {\n self ^ y\n }\n}\n\nimpl WrappingSub for u8 {\n fn wrapping_sub(self: u8, y: u8) -> u8 {\n wrapping_sub_hlp(self, y) as u8\n }\n}\n\nimpl WrappingSub for u16 {\n fn wrapping_sub(self: u16, y: u16) -> u16 {\n wrapping_sub_hlp(self, y) as u16\n }\n}\n\nimpl WrappingSub for u32 {\n fn wrapping_sub(self: u32, y: u32) -> u32 {\n wrapping_sub_hlp(self, y) as u32\n }\n}\nimpl WrappingSub for u64 {\n fn wrapping_sub(self: u64, y: u64) -> u64 {\n wrapping_sub_hlp(self, y) as u64\n }\n}\nimpl WrappingSub for u128 {\n fn wrapping_sub(self: u128, y: u128) -> u128 {\n wrapping_sub_hlp(self, y) as u128\n }\n}\n\nimpl WrappingSub for i8 {\n fn wrapping_sub(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_sub(y as u8) as i8\n }\n}\n\nimpl WrappingSub for i16 {\n fn wrapping_sub(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_sub(y as u16) as i16\n }\n}\n\nimpl WrappingSub for i32 {\n fn wrapping_sub(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_sub(y as u32) as i32\n }\n}\nimpl WrappingSub for i64 {\n fn wrapping_sub(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_sub(y as u64) as i64\n }\n}\nimpl WrappingSub for Field {\n fn wrapping_sub(self: Field, y: Field) -> Field {\n self - y\n }\n}\n\n// docs:start:wrapping-mul-trait\npub trait WrappingMul {\n fn wrapping_mul(self, y: Self) -> Self;\n}\n// docs:start:wrapping-mul-trait\n\nimpl WrappingMul for u1 {\n fn wrapping_mul(self: u1, y: u1) -> u1 {\n self & y\n }\n}\n\nimpl WrappingMul for u8 {\n fn wrapping_mul(self: u8, y: u8) -> u8 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for u16 {\n fn wrapping_mul(self: u16, y: u16) -> u16 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for u32 {\n fn wrapping_mul(self: u32, y: u32) -> u32 {\n wrapping_mul_hlp(self, y)\n }\n}\nimpl WrappingMul for u64 {\n fn wrapping_mul(self: u64, y: u64) -> u64 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for i8 {\n fn wrapping_mul(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_mul(y as u8) as i8\n }\n}\n\nimpl WrappingMul for i16 {\n fn wrapping_mul(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_mul(y as u16) as i16\n }\n}\n\nimpl WrappingMul for i32 {\n fn wrapping_mul(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_mul(y as u32) as i32\n }\n}\n\nimpl WrappingMul for i64 {\n fn wrapping_mul(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_mul(y as u64) as i64\n }\n}\n\nimpl WrappingMul for u128 {\n fn wrapping_mul(self: u128, y: u128) -> u128 {\n wrapping_mul128_hlp(self, y)\n }\n}\nimpl WrappingMul for Field {\n fn wrapping_mul(self: Field, y: Field) -> Field {\n self * y\n }\n}\n\nfn wrapping_add_hlp<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n AsPrimitive::as_(x.as_() + y.as_())\n}\n\nfn wrapping_sub_hlp<T>(x: T, y: T) -> Field\nwhere\n T: AsPrimitive<Field>,\n{\n //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow\n x.as_() + 340282366920938463463374607431768211456 - y.as_()\n}\n\nfn wrapping_mul_hlp<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n AsPrimitive::as_(x.as_() * y.as_())\n}\n\nglobal two_pow_64: u128 = 0x10000000000000000;\n/// Splits a 128 bits number into two 64 bits limbs\nunconstrained fn split64(x: u128) -> (u64, u64) {\n let lo = x as u64;\n let hi = (x / two_pow_64) as u64;\n (lo, hi)\n}\n\n/// Split a 128 bits number into two 64 bits limbs\n/// It will fail if the number is more than 128 bits\nfn split_into_64_bit_limbs(x: u128) -> (u64, u64) {\n // Safety: the limbs are constrained below\n let (x_lo, x_hi) = unsafe { split64(x) };\n assert(x as Field == x_lo as Field + x_hi as Field * two_pow_64 as Field);\n (x_lo, x_hi)\n}\n\n#[field(bn254)]\nfn wrapping_mul128_hlp(x: u128, y: u128) -> u128 {\n let (x_lo, x_hi) = split_into_64_bit_limbs(x);\n let (y_lo, y_hi) = split_into_64_bit_limbs(y);\n // Multiplication using the limbs:(x_lo + 2**64*x_hi)*(y_lo + 2**64*y_hi)=x_lo*y_lo+...\n // and skipping the terms over 2**128\n // Working with u64 limbs ensures that we cannot overflow the field modulus.\n let low = x_lo as Field * y_lo as Field;\n let lo = low as u64 as Field;\n let carry = (low - lo) / two_pow_64 as Field;\n let high = x_lo as Field * y_hi as Field + x_hi as Field * y_lo as Field + carry;\n let hi = high as u64 as Field;\n (lo + two_pow_64 as Field * hi) as u128\n}\n\nmod tests {\n #[test(should_fail_with = \"custom message\")]\n fn test_static_assert_custom_message() {\n crate::static_assert(1 == 2, \"custom message\");\n }\n\n mod arithmetic {\n use crate::ops::arith::{Add, Div, Mul, Neg, Rem, Sub};\n #[test]\n fn test_basic_arithmetic_traits() {\n // add\n assert_eq(5.add(3), 8);\n assert_eq(0u8.add(255u8), 255u8);\n assert_eq(42.add(58), 100);\n\n // sub\n assert_eq(10.sub(3), 7);\n assert_eq(100.sub(42), 58);\n\n // mul\n assert_eq(6.mul(7), 42);\n\n // div\n assert_eq(15.div(3), 5);\n assert_eq(10u8.div(3u8), 3u8);\n assert_eq(15.div(3), 5);\n\n // rem (Field doesn't implement Rem)\n assert_eq(17u64.rem(5u64), 2u64);\n assert_eq(10u8.rem(3u8), 1u8);\n\n // neg\n assert_eq(42.neg(), -42);\n assert_eq((-10).neg(), 10);\n assert_eq(42.neg(), -42);\n }\n\n #[test]\n fn test_division() {\n // test division by one\n assert_eq(42.div(1), 42);\n assert_eq(0.div(1), 0);\n assert_eq(255u8.div(1u8), 255u8);\n\n // test division by self\n assert_eq(42.div(42), 1);\n assert_eq(1.div(1), 1);\n\n // test remainder (Field doesn't implement Rem)\n assert_eq(42u32.rem(42u32), 0u32);\n assert_eq(0u16.rem(42u16), 0u16);\n assert_eq(1u64.rem(42u64), 1u64);\n }\n\n #[test(should_fail)]\n fn test_u8_sub_overflow_failure() {\n let _ = 0u8.sub(1u8);\n }\n\n #[test(should_fail)]\n fn test_u8_add_overflow_failure() {\n let _ = 255u8.add(1u8);\n }\n\n #[test(should_fail)]\n fn test_u8_mul_overflow_failure() {\n let _ = 255u8.mul(2u8);\n }\n\n #[test(should_fail)]\n fn test_u16_sub_overflow_failure() {\n let _ = 0u16.sub(1u16);\n }\n\n #[test(should_fail)]\n fn test_u16_add_overflow_failure() {\n let _ = 65535u16.add(1u16);\n }\n\n #[test(should_fail)]\n fn test_u16_mul_overflow_failure() {\n let _ = 65535u16.mul(2u16);\n }\n\n #[test(should_fail)]\n fn test_signed_sub_overflow_failure() {\n let val: i8 = -128;\n let _ = val.sub(1i8);\n }\n\n #[test(should_fail)]\n fn test_signed_overflow_failure() {\n let _ = 127i8.add(1i8);\n }\n\n #[test]\n fn test_field() {\n let zero: Field = 0;\n let one: Field = 1;\n\n // test Field basic operations\n assert_eq(zero.add(one), one);\n assert_eq(one.add(zero), one);\n assert_eq(one.sub(one), zero);\n assert_eq(one.mul(one), one);\n assert_eq(one.div(one), one);\n assert_eq(zero.neg(), zero);\n assert_eq(one.neg(), -one);\n }\n\n }\n\n mod wrapping_arithmetic {\n use crate::ops::arith::{Add, Div, Mul, Neg, Sub, WrappingAdd, WrappingMul, WrappingSub};\n #[test]\n fn test_wrapping_add() {\n assert_eq(255u8.wrapping_add(1u8), 0u8);\n assert_eq(255u8.wrapping_add(255u8), 254u8);\n assert_eq(0u8.wrapping_add(0u8), 0u8);\n assert_eq(128u8.wrapping_add(128u8), 0u8);\n\n // test u16 wrapping add\n assert_eq(65535u16.wrapping_add(1u16), 0u16);\n assert_eq(65535u16.wrapping_add(65535u16), 65534u16);\n\n // test u32 wrapping add\n assert_eq(0xffffffffu32.wrapping_add(1u32), 0u32);\n assert_eq(0xffffffffu32.wrapping_add(0xffffffffu32), 0xfffffffeu32);\n\n // test u64 wrapping add\n assert_eq(0xffffffffffffffffu64.wrapping_add(1u64), 0u64);\n assert_eq(\n 0xffffffffffffffffu64.wrapping_add(0xffffffffffffffffu64),\n 0xfffffffffffffffeu64,\n );\n\n // test u128 wrapping add\n assert_eq(0xffffffffffffffffffffffffffffffffu128.wrapping_add(1u128), 0u128);\n\n // test signed types\n assert_eq(127i8.wrapping_add(1i8), -128i8);\n let val: i8 = -128;\n assert_eq(val.wrapping_add(-1i8), 127i8);\n\n // test Field wrapping add\n let forty_two: Field = 42;\n let fifty_eight: Field = 58;\n let hundred: Field = 100;\n let neg_two: Field = -2;\n let two: Field = 2;\n let zero: Field = 0;\n let neg_two_hundred: Field = -200;\n let neg_one_ninety_eight: Field = -198;\n assert_eq(forty_two.wrapping_add(fifty_eight), hundred);\n assert_eq(neg_two.wrapping_add(two), zero);\n assert_eq(neg_two_hundred.wrapping_add(two), neg_one_ninety_eight);\n }\n\n #[test]\n fn test_wrapping_sub() {\n assert_eq(0u8.wrapping_sub(1u8), 255u8);\n assert_eq(255u8.wrapping_sub(255u8), 0u8);\n assert_eq(0u8.wrapping_sub(0u8), 0u8);\n assert_eq(1u8.wrapping_sub(2u8), 255u8);\n\n // test u16 wrapping sub\n assert_eq(0u16.wrapping_sub(1u16), 65535u16);\n assert_eq(65535u16.wrapping_sub(65535u16), 0u16);\n\n // test u32 wrapping sub\n assert_eq(0u32.wrapping_sub(1u32), 0xffffffffu32);\n assert_eq(0xffffffffu32.wrapping_sub(0xffffffffu32), 0u32);\n\n // test u64 wrapping sub\n assert_eq(0u64.wrapping_sub(1u64), 0xffffffffffffffffu64);\n assert_eq(0xffffffffffffffffu64.wrapping_sub(0xffffffffffffffffu64), 0u64);\n\n // test u128 wrapping sub\n assert_eq(0u128.wrapping_sub(1u128), 0xffffffffffffffffffffffffffffffffu128);\n\n // test signed types\n let val: i8 = -128;\n assert_eq(val.wrapping_sub(1i8), 127i8);\n assert_eq(127i8.wrapping_sub(-1i8), -128i8);\n\n // test Field wrapping sub\n let forty_two: Field = 42;\n let fifty_eight: Field = 58;\n let neg_sixteen: Field = -16;\n assert_eq(forty_two.wrapping_sub(fifty_eight), neg_sixteen);\n }\n\n #[test]\n fn test_wrapping_mul() {\n let zero: u128 = 0;\n let one: u128 = 1;\n let two_pow_64: u128 = 0x10000000000000000;\n let u128_max: u128 = 0xffffffffffffffffffffffffffffffff;\n\n assert_eq(zero, zero.wrapping_mul(one));\n assert_eq(zero, one.wrapping_mul(zero));\n assert_eq(one, one.wrapping_mul(one));\n assert_eq(zero, zero.wrapping_mul(two_pow_64));\n assert_eq(zero, two_pow_64.wrapping_mul(zero));\n assert_eq(two_pow_64, two_pow_64.wrapping_mul(one));\n assert_eq(two_pow_64, one.wrapping_mul(two_pow_64));\n assert_eq(zero, two_pow_64.wrapping_mul(two_pow_64));\n assert_eq(one, u128_max.wrapping_mul(u128_max));\n\n // test u8 wrapping mul\n assert_eq(255u8.wrapping_mul(2u8), 254u8);\n assert_eq(255u8.wrapping_mul(255u8), 1u8);\n assert_eq(128u8.wrapping_mul(2u8), 0u8);\n\n // test u16 wrapping mul\n assert_eq(65535u16.wrapping_mul(2u16), 65534u16);\n assert_eq(65535u16.wrapping_mul(65535u16), 1u16);\n\n // test u32 wrapping mul\n assert_eq(0xffffffffu32.wrapping_mul(2u32), 0xfffffffeu32);\n assert_eq(0xffffffffu32.wrapping_mul(0xffffffffu32), 1u32);\n\n // test u64 wrapping mul\n // 0xffffffffffffffffu64 is 2^64 - 1\n assert_eq(0xffffffffffffffffu64.wrapping_mul(2u64), 0xfffffffffffffffeu64);\n assert_eq(0xffffffffffffffffu64.wrapping_mul(0xffffffffffffffffu64), 1u64);\n\n // test signed types\n assert_eq(127i8.wrapping_mul(2i8), -2i8);\n let val: i8 = -128;\n assert_eq(val.wrapping_mul(-1i8), -128i8);\n\n // test Field wrapping mul\n let six: Field = 6;\n let seven: Field = 7;\n let forty_two: Field = 42;\n let neg_two: Field = -2;\n let two: Field = 2;\n let neg_four: Field = -4;\n assert_eq(six.wrapping_mul(seven), forty_two);\n assert_eq(neg_two.wrapping_mul(two), neg_four);\n }\n\n #[test]\n fn test_u1_behavior() {\n // u1 wrapping add is XOR\n assert_eq(0u1.wrapping_add(0u1), 0u1);\n assert_eq(0u1.wrapping_add(1u1), 1u1);\n assert_eq(1u1.wrapping_add(0u1), 1u1);\n assert_eq(1u1.wrapping_add(1u1), 0u1);\n\n // u1 wrapping sub is XOR\n assert_eq(0u1.wrapping_sub(0u1), 0u1);\n assert_eq(0u1.wrapping_sub(1u1), 1u1);\n assert_eq(1u1.wrapping_sub(0u1), 1u1);\n assert_eq(1u1.wrapping_sub(1u1), 0u1);\n\n // u1 wrapping mul is AND\n assert_eq(0u1.wrapping_mul(0u1), 0u1);\n assert_eq(0u1.wrapping_mul(1u1), 0u1);\n assert_eq(1u1.wrapping_mul(0u1), 0u1);\n assert_eq(1u1.wrapping_mul(1u1), 1u1);\n }\n\n // test wrapping operations is the same as the regular operations\n #[test]\n fn test_wrapping_vs_regular() {\n let u64_large = 0x123456789abcdef0u64;\n let u128_large = 0x123456789abcdef0123456789abcdef0u128;\n\n assert_eq(u64_large.wrapping_add(1u64), u64_large + 1u64);\n assert_eq(u64_large.wrapping_sub(1u64), u64_large - 1u64);\n assert_eq(u64_large.wrapping_mul(2u64), u64_large * 2u64);\n\n assert_eq(u128_large.wrapping_add(1u128), u128_large + 1u128);\n assert_eq(u128_large.wrapping_sub(1u128), u128_large - 1u128);\n assert_eq(u128_large.wrapping_mul(2u128), u128_large * 2u128);\n }\n\n #[test]\n fn test_field_wrapping_operations() {\n let zero: Field = 0;\n let one: Field = 1;\n let large_val = 0xffffffffffffffff;\n\n // test Field wrapping operations\n assert_eq(zero.wrapping_add(one), one);\n assert_eq(one.wrapping_add(large_val), one + large_val);\n assert_eq(zero.wrapping_sub(one), -one);\n assert_eq(one.wrapping_sub(large_val), one - large_val);\n assert_eq(zero.wrapping_mul(one), zero);\n assert_eq(one.wrapping_mul(large_val), large_val);\n\n // test Field basic operations\n assert_eq(zero.add(one), one);\n assert_eq(one.add(zero), one);\n assert_eq(one.sub(one), zero);\n assert_eq(one.mul(one), one);\n assert_eq(one.div(one), one);\n assert_eq(zero.neg(), zero);\n assert_eq(one.neg(), -one);\n }\n\n }\n\n mod split_functions {\n\n use crate::ops::arith::{split64, split_into_64_bit_limbs};\n\n // test split64 and split_into_64_bit_limbs functions\n #[test]\n fn test_split_functions() {\n let small_val = 0x123456789abcdefu128;\n let large_val = 0x123456789abcdef0123456789abcdef0u128;\n let max_val = 0xffffffffffffffffffffffffffffffffu128;\n\n // test split64 (unconstrained)\n // Safety: testing\n unsafe {\n let (lo, hi) = split64(small_val);\n assert_eq(lo, 0x123456789abcdefu64);\n assert_eq(hi, 0u64);\n\n let (lo2, hi2) = split64(large_val);\n assert_eq(lo2, 0x123456789abcdef0u64);\n assert_eq(hi2, 0x123456789abcdef0u64);\n }\n\n // test split_into_64_bit_limbs (constrained)\n let (lo3, hi3) = split_into_64_bit_limbs(small_val);\n assert_eq(lo3, 0x123456789abcdefu64);\n assert_eq(hi3, 0u64);\n\n let (lo4, hi4) = split_into_64_bit_limbs(large_val);\n assert_eq(lo4, 0x123456789abcdef0u64);\n assert_eq(hi4, 0x123456789abcdef0u64);\n\n let (lo5, hi5) = split_into_64_bit_limbs(max_val);\n assert_eq(lo5, 0xffffffffffffffffu64);\n assert_eq(hi5, 0xffffffffffffffffu64);\n }\n }\n}\n"
|
|
5835
|
+
"source": "use crate::convert::AsPrimitive;\n\n// docs:start:add-trait\npub trait Add {\n fn add(self, other: Self) -> Self;\n}\n// docs:end:add-trait\n\nimpl Add for Field {\n fn add(self, other: Field) -> Field {\n self + other\n }\n}\n\nimpl Add for u128 {\n fn add(self, other: u128) -> u128 {\n self + other\n }\n}\nimpl Add for u64 {\n fn add(self, other: u64) -> u64 {\n self + other\n }\n}\nimpl Add for u32 {\n fn add(self, other: u32) -> u32 {\n self + other\n }\n}\nimpl Add for u16 {\n fn add(self, other: u16) -> u16 {\n self + other\n }\n}\nimpl Add for u8 {\n fn add(self, other: u8) -> u8 {\n self + other\n }\n}\nimpl Add for i8 {\n fn add(self, other: i8) -> i8 {\n self + other\n }\n}\nimpl Add for i16 {\n fn add(self, other: i16) -> i16 {\n self + other\n }\n}\nimpl Add for i32 {\n fn add(self, other: i32) -> i32 {\n self + other\n }\n}\nimpl Add for i64 {\n fn add(self, other: i64) -> i64 {\n self + other\n }\n}\n\n// docs:start:sub-trait\npub trait Sub {\n fn sub(self, other: Self) -> Self;\n}\n// docs:end:sub-trait\n\nimpl Sub for Field {\n fn sub(self, other: Field) -> Field {\n self - other\n }\n}\n\nimpl Sub for u128 {\n fn sub(self, other: u128) -> u128 {\n self - other\n }\n}\nimpl Sub for u64 {\n fn sub(self, other: u64) -> u64 {\n self - other\n }\n}\nimpl Sub for u32 {\n fn sub(self, other: u32) -> u32 {\n self - other\n }\n}\nimpl Sub for u16 {\n fn sub(self, other: u16) -> u16 {\n self - other\n }\n}\nimpl Sub for u8 {\n fn sub(self, other: u8) -> u8 {\n self - other\n }\n}\nimpl Sub for i8 {\n fn sub(self, other: i8) -> i8 {\n self - other\n }\n}\nimpl Sub for i16 {\n fn sub(self, other: i16) -> i16 {\n self - other\n }\n}\nimpl Sub for i32 {\n fn sub(self, other: i32) -> i32 {\n self - other\n }\n}\nimpl Sub for i64 {\n fn sub(self, other: i64) -> i64 {\n self - other\n }\n}\n\n// docs:start:mul-trait\npub trait Mul {\n fn mul(self, other: Self) -> Self;\n}\n// docs:end:mul-trait\n\nimpl Mul for Field {\n fn mul(self, other: Field) -> Field {\n self * other\n }\n}\n\nimpl Mul for u128 {\n fn mul(self, other: u128) -> u128 {\n self * other\n }\n}\nimpl Mul for u64 {\n fn mul(self, other: u64) -> u64 {\n self * other\n }\n}\nimpl Mul for u32 {\n fn mul(self, other: u32) -> u32 {\n self * other\n }\n}\nimpl Mul for u16 {\n fn mul(self, other: u16) -> u16 {\n self * other\n }\n}\nimpl Mul for u8 {\n fn mul(self, other: u8) -> u8 {\n self * other\n }\n}\nimpl Mul for i8 {\n fn mul(self, other: i8) -> i8 {\n self * other\n }\n}\nimpl Mul for i16 {\n fn mul(self, other: i16) -> i16 {\n self * other\n }\n}\nimpl Mul for i32 {\n fn mul(self, other: i32) -> i32 {\n self * other\n }\n}\nimpl Mul for i64 {\n fn mul(self, other: i64) -> i64 {\n self * other\n }\n}\n\n// docs:start:div-trait\npub trait Div {\n fn div(self, other: Self) -> Self;\n}\n// docs:end:div-trait\n\nimpl Div for Field {\n fn div(self, other: Field) -> Field {\n self / other\n }\n}\n\nimpl Div for u128 {\n fn div(self, other: u128) -> u128 {\n self / other\n }\n}\nimpl Div for u64 {\n fn div(self, other: u64) -> u64 {\n self / other\n }\n}\nimpl Div for u32 {\n fn div(self, other: u32) -> u32 {\n self / other\n }\n}\nimpl Div for u16 {\n fn div(self, other: u16) -> u16 {\n self / other\n }\n}\nimpl Div for u8 {\n fn div(self, other: u8) -> u8 {\n self / other\n }\n}\nimpl Div for i8 {\n fn div(self, other: i8) -> i8 {\n self / other\n }\n}\nimpl Div for i16 {\n fn div(self, other: i16) -> i16 {\n self / other\n }\n}\nimpl Div for i32 {\n fn div(self, other: i32) -> i32 {\n self / other\n }\n}\nimpl Div for i64 {\n fn div(self, other: i64) -> i64 {\n self / other\n }\n}\n\n// docs:start:rem-trait\npub trait Rem {\n fn rem(self, other: Self) -> Self;\n}\n// docs:end:rem-trait\n\nimpl Rem for u128 {\n fn rem(self, other: u128) -> u128 {\n self % other\n }\n}\nimpl Rem for u64 {\n fn rem(self, other: u64) -> u64 {\n self % other\n }\n}\nimpl Rem for u32 {\n fn rem(self, other: u32) -> u32 {\n self % other\n }\n}\nimpl Rem for u16 {\n fn rem(self, other: u16) -> u16 {\n self % other\n }\n}\nimpl Rem for u8 {\n fn rem(self, other: u8) -> u8 {\n self % other\n }\n}\nimpl Rem for i8 {\n fn rem(self, other: i8) -> i8 {\n self % other\n }\n}\nimpl Rem for i16 {\n fn rem(self, other: i16) -> i16 {\n self % other\n }\n}\nimpl Rem for i32 {\n fn rem(self, other: i32) -> i32 {\n self % other\n }\n}\nimpl Rem for i64 {\n fn rem(self, other: i64) -> i64 {\n self % other\n }\n}\n\n// docs:start:neg-trait\npub trait Neg {\n fn neg(self) -> Self;\n}\n// docs:end:neg-trait\n\n// docs:start:neg-trait-impls\nimpl Neg for Field {\n fn neg(self) -> Field {\n -self\n }\n}\n\nimpl Neg for i8 {\n fn neg(self) -> i8 {\n -self\n }\n}\nimpl Neg for i16 {\n fn neg(self) -> i16 {\n -self\n }\n}\nimpl Neg for i32 {\n fn neg(self) -> i32 {\n -self\n }\n}\nimpl Neg for i64 {\n fn neg(self) -> i64 {\n -self\n }\n}\n// docs:end:neg-trait-impls\n\n// docs:start:wrapping-add-trait\npub trait WrappingAdd {\n fn wrapping_add(self, y: Self) -> Self;\n}\n// docs:end:wrapping-add-trait\n\nimpl WrappingAdd for u8 {\n fn wrapping_add(self: u8, y: u8) -> u8 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u16 {\n fn wrapping_add(self: u16, y: u16) -> u16 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u32 {\n fn wrapping_add(self: u32, y: u32) -> u32 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u64 {\n fn wrapping_add(self: u64, y: u64) -> u64 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for u128 {\n fn wrapping_add(self: u128, y: u128) -> u128 {\n wrapping_add_hlp(self, y)\n }\n}\n\nimpl WrappingAdd for i8 {\n fn wrapping_add(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_add(y as u8) as i8\n }\n}\n\nimpl WrappingAdd for i16 {\n fn wrapping_add(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_add(y as u16) as i16\n }\n}\n\nimpl WrappingAdd for i32 {\n fn wrapping_add(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_add(y as u32) as i32\n }\n}\n\nimpl WrappingAdd for i64 {\n fn wrapping_add(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_add(y as u64) as i64\n }\n}\nimpl WrappingAdd for Field {\n fn wrapping_add(self: Field, y: Field) -> Field {\n self + y\n }\n}\n\n// docs:start:wrapping-sub-trait\npub trait WrappingSub {\n fn wrapping_sub(self, y: Self) -> Self;\n}\n// docs:start:wrapping-sub-trait\n\nimpl WrappingSub for u8 {\n fn wrapping_sub(self: u8, y: u8) -> u8 {\n wrapping_sub_hlp(self, y) as u8\n }\n}\n\nimpl WrappingSub for u16 {\n fn wrapping_sub(self: u16, y: u16) -> u16 {\n wrapping_sub_hlp(self, y) as u16\n }\n}\n\nimpl WrappingSub for u32 {\n fn wrapping_sub(self: u32, y: u32) -> u32 {\n wrapping_sub_hlp(self, y) as u32\n }\n}\nimpl WrappingSub for u64 {\n fn wrapping_sub(self: u64, y: u64) -> u64 {\n wrapping_sub_hlp(self, y) as u64\n }\n}\nimpl WrappingSub for u128 {\n fn wrapping_sub(self: u128, y: u128) -> u128 {\n wrapping_sub_hlp(self, y) as u128\n }\n}\n\nimpl WrappingSub for i8 {\n fn wrapping_sub(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_sub(y as u8) as i8\n }\n}\n\nimpl WrappingSub for i16 {\n fn wrapping_sub(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_sub(y as u16) as i16\n }\n}\n\nimpl WrappingSub for i32 {\n fn wrapping_sub(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_sub(y as u32) as i32\n }\n}\nimpl WrappingSub for i64 {\n fn wrapping_sub(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_sub(y as u64) as i64\n }\n}\nimpl WrappingSub for Field {\n fn wrapping_sub(self: Field, y: Field) -> Field {\n self - y\n }\n}\n\n// docs:start:wrapping-mul-trait\npub trait WrappingMul {\n fn wrapping_mul(self, y: Self) -> Self;\n}\n// docs:start:wrapping-mul-trait\n\nimpl WrappingMul for u8 {\n fn wrapping_mul(self: u8, y: u8) -> u8 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for u16 {\n fn wrapping_mul(self: u16, y: u16) -> u16 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for u32 {\n fn wrapping_mul(self: u32, y: u32) -> u32 {\n wrapping_mul_hlp(self, y)\n }\n}\nimpl WrappingMul for u64 {\n fn wrapping_mul(self: u64, y: u64) -> u64 {\n wrapping_mul_hlp(self, y)\n }\n}\n\nimpl WrappingMul for i8 {\n fn wrapping_mul(self: i8, y: i8) -> i8 {\n let x = self as u8;\n x.wrapping_mul(y as u8) as i8\n }\n}\n\nimpl WrappingMul for i16 {\n fn wrapping_mul(self: i16, y: i16) -> i16 {\n let x = self as u16;\n x.wrapping_mul(y as u16) as i16\n }\n}\n\nimpl WrappingMul for i32 {\n fn wrapping_mul(self: i32, y: i32) -> i32 {\n let x = self as u32;\n x.wrapping_mul(y as u32) as i32\n }\n}\n\nimpl WrappingMul for i64 {\n fn wrapping_mul(self: i64, y: i64) -> i64 {\n let x = self as u64;\n x.wrapping_mul(y as u64) as i64\n }\n}\n\nimpl WrappingMul for u128 {\n fn wrapping_mul(self: u128, y: u128) -> u128 {\n wrapping_mul128_hlp(self, y)\n }\n}\nimpl WrappingMul for Field {\n fn wrapping_mul(self: Field, y: Field) -> Field {\n self * y\n }\n}\n\nfn wrapping_add_hlp<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n AsPrimitive::as_(x.as_() + y.as_())\n}\n\nfn wrapping_sub_hlp<T>(x: T, y: T) -> Field\nwhere\n T: AsPrimitive<Field>,\n{\n //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow\n x.as_() + 340282366920938463463374607431768211456 - y.as_()\n}\n\nfn wrapping_mul_hlp<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n AsPrimitive::as_(x.as_() * y.as_())\n}\n\nglobal two_pow_64: u128 = 0x10000000000000000;\n/// Splits a 128 bits number into two 64 bits limbs\nunconstrained fn split64(x: u128) -> (u64, u64) {\n let lo = x as u64;\n let hi = (x / two_pow_64) as u64;\n (lo, hi)\n}\n\n/// Split a 128 bits number into two 64 bits limbs\n/// It will fail if the number is more than 128 bits\nfn split_into_64_bit_limbs(x: u128) -> (u64, u64) {\n // Safety: the limbs are constrained below\n let (x_lo, x_hi) = unsafe { split64(x) };\n assert(x as Field == x_lo as Field + x_hi as Field * two_pow_64 as Field);\n (x_lo, x_hi)\n}\n\n#[field(bn254)]\nfn wrapping_mul128_hlp(x: u128, y: u128) -> u128 {\n let (x_lo, x_hi) = split_into_64_bit_limbs(x);\n let (y_lo, y_hi) = split_into_64_bit_limbs(y);\n // Multiplication using the limbs:(x_lo + 2**64*x_hi)*(y_lo + 2**64*y_hi)=x_lo*y_lo+...\n // and skipping the terms over 2**128\n // Working with u64 limbs ensures that we cannot overflow the field modulus.\n let low = x_lo as Field * y_lo as Field;\n let lo = low as u64 as Field;\n let carry = (low - lo) / two_pow_64 as Field;\n let high = x_lo as Field * y_hi as Field + x_hi as Field * y_lo as Field + carry;\n let hi = high as u64 as Field;\n (lo + two_pow_64 as Field * hi) as u128\n}\n\nmod tests {\n #[test(should_fail_with = \"custom message\")]\n fn test_static_assert_custom_message() {\n crate::static_assert(1 == 2, \"custom message\");\n }\n\n mod arithmetic {\n use crate::ops::arith::{Add, Div, Mul, Neg, Rem, Sub};\n #[test]\n fn test_basic_arithmetic_traits() {\n // add\n assert_eq(5.add(3), 8);\n assert_eq(0u8.add(255u8), 255u8);\n assert_eq(42.add(58), 100);\n\n // sub\n assert_eq(10.sub(3), 7);\n assert_eq(100.sub(42), 58);\n\n // mul\n assert_eq(6.mul(7), 42);\n\n // div\n assert_eq(15.div(3), 5);\n assert_eq(10u8.div(3u8), 3u8);\n assert_eq(15.div(3), 5);\n\n // rem (Field doesn't implement Rem)\n assert_eq(17u64.rem(5u64), 2u64);\n assert_eq(10u8.rem(3u8), 1u8);\n\n // neg\n assert_eq(42.neg(), -42);\n assert_eq((-10).neg(), 10);\n assert_eq(42.neg(), -42);\n }\n\n #[test]\n fn test_division() {\n // test division by one\n assert_eq(42.div(1), 42);\n assert_eq(0.div(1), 0);\n assert_eq(255u8.div(1u8), 255u8);\n\n // test division by self\n assert_eq(42.div(42), 1);\n assert_eq(1.div(1), 1);\n\n // test remainder (Field doesn't implement Rem)\n assert_eq(42u32.rem(42u32), 0u32);\n assert_eq(0u16.rem(42u16), 0u16);\n assert_eq(1u64.rem(42u64), 1u64);\n }\n\n #[test(should_fail)]\n fn test_u8_sub_overflow_failure() {\n let _ = 0u8.sub(1u8);\n }\n\n #[test(should_fail)]\n fn test_u8_add_overflow_failure() {\n let _ = 255u8.add(1u8);\n }\n\n #[test(should_fail)]\n fn test_u8_mul_overflow_failure() {\n let _ = 255u8.mul(2u8);\n }\n\n #[test(should_fail)]\n fn test_u16_sub_overflow_failure() {\n let _ = 0u16.sub(1u16);\n }\n\n #[test(should_fail)]\n fn test_u16_add_overflow_failure() {\n let _ = 65535u16.add(1u16);\n }\n\n #[test(should_fail)]\n fn test_u16_mul_overflow_failure() {\n let _ = 65535u16.mul(2u16);\n }\n\n #[test(should_fail)]\n fn test_signed_sub_overflow_failure() {\n let val: i8 = -128;\n let _ = val.sub(1i8);\n }\n\n #[test(should_fail)]\n fn test_signed_overflow_failure() {\n let _ = 127i8.add(1i8);\n }\n\n #[test]\n fn test_field() {\n let zero: Field = 0;\n let one: Field = 1;\n\n // test Field basic operations\n assert_eq(zero.add(one), one);\n assert_eq(one.add(zero), one);\n assert_eq(one.sub(one), zero);\n assert_eq(one.mul(one), one);\n assert_eq(one.div(one), one);\n assert_eq(zero.neg(), zero);\n assert_eq(one.neg(), -one);\n }\n\n }\n\n mod wrapping_arithmetic {\n use crate::ops::arith::{Add, Div, Mul, Neg, Sub, WrappingAdd, WrappingMul, WrappingSub};\n #[test]\n fn test_wrapping_add() {\n assert_eq(255u8.wrapping_add(1u8), 0u8);\n assert_eq(255u8.wrapping_add(255u8), 254u8);\n assert_eq(0u8.wrapping_add(0u8), 0u8);\n assert_eq(128u8.wrapping_add(128u8), 0u8);\n\n // test u16 wrapping add\n assert_eq(65535u16.wrapping_add(1u16), 0u16);\n assert_eq(65535u16.wrapping_add(65535u16), 65534u16);\n\n // test u32 wrapping add\n assert_eq(0xffffffffu32.wrapping_add(1u32), 0u32);\n assert_eq(0xffffffffu32.wrapping_add(0xffffffffu32), 0xfffffffeu32);\n\n // test u64 wrapping add\n assert_eq(0xffffffffffffffffu64.wrapping_add(1u64), 0u64);\n assert_eq(\n 0xffffffffffffffffu64.wrapping_add(0xffffffffffffffffu64),\n 0xfffffffffffffffeu64,\n );\n\n // test u128 wrapping add\n assert_eq(0xffffffffffffffffffffffffffffffffu128.wrapping_add(1u128), 0u128);\n\n // test signed types\n assert_eq(127i8.wrapping_add(1i8), -128i8);\n let val: i8 = -128;\n assert_eq(val.wrapping_add(-1i8), 127i8);\n\n // test Field wrapping add\n let forty_two: Field = 42;\n let fifty_eight: Field = 58;\n let hundred: Field = 100;\n let neg_two: Field = -2;\n let two: Field = 2;\n let zero: Field = 0;\n let neg_two_hundred: Field = -200;\n let neg_one_ninety_eight: Field = -198;\n assert_eq(forty_two.wrapping_add(fifty_eight), hundred);\n assert_eq(neg_two.wrapping_add(two), zero);\n assert_eq(neg_two_hundred.wrapping_add(two), neg_one_ninety_eight);\n }\n\n #[test]\n fn test_wrapping_sub() {\n assert_eq(0u8.wrapping_sub(1u8), 255u8);\n assert_eq(255u8.wrapping_sub(255u8), 0u8);\n assert_eq(0u8.wrapping_sub(0u8), 0u8);\n assert_eq(1u8.wrapping_sub(2u8), 255u8);\n\n // test u16 wrapping sub\n assert_eq(0u16.wrapping_sub(1u16), 65535u16);\n assert_eq(65535u16.wrapping_sub(65535u16), 0u16);\n\n // test u32 wrapping sub\n assert_eq(0u32.wrapping_sub(1u32), 0xffffffffu32);\n assert_eq(0xffffffffu32.wrapping_sub(0xffffffffu32), 0u32);\n\n // test u64 wrapping sub\n assert_eq(0u64.wrapping_sub(1u64), 0xffffffffffffffffu64);\n assert_eq(0xffffffffffffffffu64.wrapping_sub(0xffffffffffffffffu64), 0u64);\n\n // test u128 wrapping sub\n assert_eq(0u128.wrapping_sub(1u128), 0xffffffffffffffffffffffffffffffffu128);\n\n // test signed types\n let val: i8 = -128;\n assert_eq(val.wrapping_sub(1i8), 127i8);\n assert_eq(127i8.wrapping_sub(-1i8), -128i8);\n\n // test Field wrapping sub\n let forty_two: Field = 42;\n let fifty_eight: Field = 58;\n let neg_sixteen: Field = -16;\n assert_eq(forty_two.wrapping_sub(fifty_eight), neg_sixteen);\n }\n\n #[test]\n fn test_wrapping_mul() {\n let zero: u128 = 0;\n let one: u128 = 1;\n let two_pow_64: u128 = 0x10000000000000000;\n let u128_max: u128 = 0xffffffffffffffffffffffffffffffff;\n\n assert_eq(zero, zero.wrapping_mul(one));\n assert_eq(zero, one.wrapping_mul(zero));\n assert_eq(one, one.wrapping_mul(one));\n assert_eq(zero, zero.wrapping_mul(two_pow_64));\n assert_eq(zero, two_pow_64.wrapping_mul(zero));\n assert_eq(two_pow_64, two_pow_64.wrapping_mul(one));\n assert_eq(two_pow_64, one.wrapping_mul(two_pow_64));\n assert_eq(zero, two_pow_64.wrapping_mul(two_pow_64));\n assert_eq(one, u128_max.wrapping_mul(u128_max));\n\n // test u8 wrapping mul\n assert_eq(255u8.wrapping_mul(2u8), 254u8);\n assert_eq(255u8.wrapping_mul(255u8), 1u8);\n assert_eq(128u8.wrapping_mul(2u8), 0u8);\n\n // test u16 wrapping mul\n assert_eq(65535u16.wrapping_mul(2u16), 65534u16);\n assert_eq(65535u16.wrapping_mul(65535u16), 1u16);\n\n // test u32 wrapping mul\n assert_eq(0xffffffffu32.wrapping_mul(2u32), 0xfffffffeu32);\n assert_eq(0xffffffffu32.wrapping_mul(0xffffffffu32), 1u32);\n\n // test u64 wrapping mul\n // 0xffffffffffffffffu64 is 2^64 - 1\n assert_eq(0xffffffffffffffffu64.wrapping_mul(2u64), 0xfffffffffffffffeu64);\n assert_eq(0xffffffffffffffffu64.wrapping_mul(0xffffffffffffffffu64), 1u64);\n\n // test signed types\n assert_eq(127i8.wrapping_mul(2i8), -2i8);\n let val: i8 = -128;\n assert_eq(val.wrapping_mul(-1i8), -128i8);\n\n // test Field wrapping mul\n let six: Field = 6;\n let seven: Field = 7;\n let forty_two: Field = 42;\n let neg_two: Field = -2;\n let two: Field = 2;\n let neg_four: Field = -4;\n assert_eq(six.wrapping_mul(seven), forty_two);\n assert_eq(neg_two.wrapping_mul(two), neg_four);\n }\n\n // test wrapping operations is the same as the regular operations\n #[test]\n fn test_wrapping_vs_regular() {\n let u64_large = 0x123456789abcdef0u64;\n let u128_large = 0x123456789abcdef0123456789abcdef0u128;\n\n assert_eq(u64_large.wrapping_add(1u64), u64_large + 1u64);\n assert_eq(u64_large.wrapping_sub(1u64), u64_large - 1u64);\n assert_eq(u64_large.wrapping_mul(2u64), u64_large * 2u64);\n\n assert_eq(u128_large.wrapping_add(1u128), u128_large + 1u128);\n assert_eq(u128_large.wrapping_sub(1u128), u128_large - 1u128);\n assert_eq(u128_large.wrapping_mul(2u128), u128_large * 2u128);\n }\n\n #[test]\n fn test_field_wrapping_operations() {\n let zero: Field = 0;\n let one: Field = 1;\n let large_val = 0xffffffffffffffff;\n\n // test Field wrapping operations\n assert_eq(zero.wrapping_add(one), one);\n assert_eq(one.wrapping_add(large_val), one + large_val);\n assert_eq(zero.wrapping_sub(one), -one);\n assert_eq(one.wrapping_sub(large_val), one - large_val);\n assert_eq(zero.wrapping_mul(one), zero);\n assert_eq(one.wrapping_mul(large_val), large_val);\n\n // test Field basic operations\n assert_eq(zero.add(one), one);\n assert_eq(one.add(zero), one);\n assert_eq(one.sub(one), zero);\n assert_eq(one.mul(one), one);\n assert_eq(one.div(one), one);\n assert_eq(zero.neg(), zero);\n assert_eq(one.neg(), -one);\n }\n\n }\n\n mod split_functions {\n\n use crate::ops::arith::{split64, split_into_64_bit_limbs};\n\n // test split64 and split_into_64_bit_limbs functions\n #[test]\n fn test_split_functions() {\n let small_val = 0x123456789abcdefu128;\n let large_val = 0x123456789abcdef0123456789abcdef0u128;\n let max_val = 0xffffffffffffffffffffffffffffffffu128;\n\n // test split64 (unconstrained)\n // Safety: testing\n unsafe {\n let (lo, hi) = split64(small_val);\n assert_eq(lo, 0x123456789abcdefu64);\n assert_eq(hi, 0u64);\n\n let (lo2, hi2) = split64(large_val);\n assert_eq(lo2, 0x123456789abcdef0u64);\n assert_eq(hi2, 0x123456789abcdef0u64);\n }\n\n // test split_into_64_bit_limbs (constrained)\n let (lo3, hi3) = split_into_64_bit_limbs(small_val);\n assert_eq(lo3, 0x123456789abcdefu64);\n assert_eq(hi3, 0u64);\n\n let (lo4, hi4) = split_into_64_bit_limbs(large_val);\n assert_eq(lo4, 0x123456789abcdef0u64);\n assert_eq(hi4, 0x123456789abcdef0u64);\n\n let (lo5, hi5) = split_into_64_bit_limbs(max_val);\n assert_eq(lo5, 0xffffffffffffffffu64);\n assert_eq(hi5, 0xffffffffffffffffu64);\n }\n }\n}\n"
|
|
6054
5836
|
},
|
|
6055
5837
|
"41": {
|
|
6056
5838
|
"function_locations": [
|
|
@@ -6064,91 +5846,91 @@
|
|
|
6064
5846
|
},
|
|
6065
5847
|
{
|
|
6066
5848
|
"name": "Option<T>::is_none",
|
|
6067
|
-
"start":
|
|
5849
|
+
"start": 672
|
|
6068
5850
|
},
|
|
6069
5851
|
{
|
|
6070
5852
|
"name": "Option<T>::is_some",
|
|
6071
|
-
"start":
|
|
5853
|
+
"start": 774
|
|
6072
5854
|
},
|
|
6073
5855
|
{
|
|
6074
5856
|
"name": "Option<T>::unwrap",
|
|
6075
|
-
"start":
|
|
5857
|
+
"start": 898
|
|
6076
5858
|
},
|
|
6077
5859
|
{
|
|
6078
5860
|
"name": "Option<T>::unwrap_unchecked",
|
|
6079
|
-
"start":
|
|
5861
|
+
"start": 1196
|
|
6080
5862
|
},
|
|
6081
5863
|
{
|
|
6082
5864
|
"name": "Option<T>::unwrap_or",
|
|
6083
|
-
"start":
|
|
5865
|
+
"start": 1368
|
|
6084
5866
|
},
|
|
6085
5867
|
{
|
|
6086
5868
|
"name": "Option<T>::unwrap_or_else",
|
|
6087
|
-
"start":
|
|
5869
|
+
"start": 1668
|
|
6088
5870
|
},
|
|
6089
5871
|
{
|
|
6090
5872
|
"name": "Option<T>::expect",
|
|
6091
|
-
"start":
|
|
5873
|
+
"start": 1969
|
|
6092
5874
|
},
|
|
6093
5875
|
{
|
|
6094
5876
|
"name": "Option<T>::map",
|
|
6095
|
-
"start":
|
|
5877
|
+
"start": 2190
|
|
6096
5878
|
},
|
|
6097
5879
|
{
|
|
6098
5880
|
"name": "Option<T>::map_or",
|
|
6099
|
-
"start":
|
|
5881
|
+
"start": 2490
|
|
6100
5882
|
},
|
|
6101
5883
|
{
|
|
6102
5884
|
"name": "Option<T>::map_or_else",
|
|
6103
|
-
"start":
|
|
5885
|
+
"start": 2784
|
|
6104
5886
|
},
|
|
6105
5887
|
{
|
|
6106
5888
|
"name": "Option<T>::and",
|
|
6107
|
-
"start":
|
|
5889
|
+
"start": 3009
|
|
6108
5890
|
},
|
|
6109
5891
|
{
|
|
6110
5892
|
"name": "Option<T>::and_then",
|
|
6111
|
-
"start":
|
|
5893
|
+
"start": 3446
|
|
6112
5894
|
},
|
|
6113
5895
|
{
|
|
6114
5896
|
"name": "Option<T>::or",
|
|
6115
|
-
"start":
|
|
5897
|
+
"start": 3669
|
|
6116
5898
|
},
|
|
6117
5899
|
{
|
|
6118
5900
|
"name": "Option<T>::or_else",
|
|
6119
|
-
"start":
|
|
5901
|
+
"start": 3902
|
|
6120
5902
|
},
|
|
6121
5903
|
{
|
|
6122
5904
|
"name": "Option<T>::xor",
|
|
6123
|
-
"start":
|
|
5905
|
+
"start": 4192
|
|
6124
5906
|
},
|
|
6125
5907
|
{
|
|
6126
5908
|
"name": "Option<T>::filter",
|
|
6127
|
-
"start":
|
|
5909
|
+
"start": 4636
|
|
6128
5910
|
},
|
|
6129
5911
|
{
|
|
6130
5912
|
"name": "Option<T>::flatten",
|
|
6131
|
-
"start":
|
|
5913
|
+
"start": 5065
|
|
6132
5914
|
},
|
|
6133
5915
|
{
|
|
6134
5916
|
"name": "<impl Default for Option<T>>::default",
|
|
6135
|
-
"start":
|
|
5917
|
+
"start": 5242
|
|
6136
5918
|
},
|
|
6137
5919
|
{
|
|
6138
5920
|
"name": "<impl Eq for Option<T>>::eq",
|
|
6139
|
-
"start":
|
|
5921
|
+
"start": 5357
|
|
6140
5922
|
},
|
|
6141
5923
|
{
|
|
6142
5924
|
"name": "<impl Hash for Option<T>>::hash",
|
|
6143
|
-
"start":
|
|
5925
|
+
"start": 5706
|
|
6144
5926
|
},
|
|
6145
5927
|
{
|
|
6146
5928
|
"name": "<impl Ord for Option<T>>::cmp",
|
|
6147
|
-
"start":
|
|
5929
|
+
"start": 5975
|
|
6148
5930
|
}
|
|
6149
5931
|
],
|
|
6150
5932
|
"path": "std/option.nr",
|
|
6151
|
-
"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"
|
|
5933
|
+
"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"
|
|
6152
5934
|
},
|
|
6153
5935
|
"42": {
|
|
6154
5936
|
"function_locations": [
|
|
@@ -6190,241 +5972,237 @@
|
|
|
6190
5972
|
"name": "<impl Eq for u8>::eq",
|
|
6191
5973
|
"start": 1282
|
|
6192
5974
|
},
|
|
6193
|
-
{
|
|
6194
|
-
"name": "<impl Eq for u1>::eq",
|
|
6195
|
-
"start": 1366
|
|
6196
|
-
},
|
|
6197
5975
|
{
|
|
6198
5976
|
"name": "<impl Eq for i8>::eq",
|
|
6199
|
-
"start":
|
|
5977
|
+
"start": 1366
|
|
6200
5978
|
},
|
|
6201
5979
|
{
|
|
6202
5980
|
"name": "<impl Eq for i16>::eq",
|
|
6203
|
-
"start":
|
|
5981
|
+
"start": 1452
|
|
6204
5982
|
},
|
|
6205
5983
|
{
|
|
6206
5984
|
"name": "<impl Eq for i32>::eq",
|
|
6207
|
-
"start":
|
|
5985
|
+
"start": 1538
|
|
6208
5986
|
},
|
|
6209
5987
|
{
|
|
6210
5988
|
"name": "<impl Eq for i64>::eq",
|
|
6211
|
-
"start":
|
|
5989
|
+
"start": 1624
|
|
6212
5990
|
},
|
|
6213
5991
|
{
|
|
6214
5992
|
"name": "<impl Eq for ()>::eq",
|
|
6215
|
-
"start":
|
|
5993
|
+
"start": 1717
|
|
6216
5994
|
},
|
|
6217
5995
|
{
|
|
6218
5996
|
"name": "<impl Eq for bool>::eq",
|
|
6219
|
-
"start":
|
|
5997
|
+
"start": 1796
|
|
6220
5998
|
},
|
|
6221
5999
|
{
|
|
6222
6000
|
"name": "<impl Eq for [T; N]>::eq",
|
|
6223
|
-
"start":
|
|
6001
|
+
"start": 1921
|
|
6224
6002
|
},
|
|
6225
6003
|
{
|
|
6226
6004
|
"name": "<impl Eq for [T]>::eq",
|
|
6227
|
-
"start":
|
|
6005
|
+
"start": 2139
|
|
6228
6006
|
},
|
|
6229
6007
|
{
|
|
6230
6008
|
"name": "<impl Eq for str<N>>::eq",
|
|
6231
|
-
"start":
|
|
6009
|
+
"start": 2418
|
|
6232
6010
|
},
|
|
6233
6011
|
{
|
|
6234
6012
|
"name": "make_tuple_eq_body",
|
|
6235
|
-
"start":
|
|
6013
|
+
"start": 2598
|
|
6236
6014
|
},
|
|
6237
6015
|
{
|
|
6238
6016
|
"name": "<impl Eq for (A, B)>::eq",
|
|
6239
|
-
"start":
|
|
6017
|
+
"start": 2859
|
|
6240
6018
|
},
|
|
6241
6019
|
{
|
|
6242
6020
|
"name": "<impl Eq for (A, B, C)>::eq",
|
|
6243
|
-
"start":
|
|
6021
|
+
"start": 2991
|
|
6244
6022
|
},
|
|
6245
6023
|
{
|
|
6246
6024
|
"name": "<impl Eq for (A, B, C, D)>::eq",
|
|
6247
|
-
"start":
|
|
6025
|
+
"start": 3136
|
|
6248
6026
|
},
|
|
6249
6027
|
{
|
|
6250
6028
|
"name": "<impl Eq for (A, B, C, D, E)>::eq",
|
|
6251
|
-
"start":
|
|
6029
|
+
"start": 3294
|
|
6252
6030
|
},
|
|
6253
6031
|
{
|
|
6254
6032
|
"name": "<impl Eq for (A, B, C, D, E, F)>::eq",
|
|
6255
|
-
"start":
|
|
6033
|
+
"start": 3465
|
|
6256
6034
|
},
|
|
6257
6035
|
{
|
|
6258
6036
|
"name": "<impl Eq for (A, B, C, D, E, F, G)>::eq",
|
|
6259
|
-
"start":
|
|
6037
|
+
"start": 3649
|
|
6260
6038
|
},
|
|
6261
6039
|
{
|
|
6262
6040
|
"name": "<impl Eq for (A, B, C, D, E, F, G, H)>::eq",
|
|
6263
|
-
"start":
|
|
6041
|
+
"start": 3846
|
|
6264
6042
|
},
|
|
6265
6043
|
{
|
|
6266
6044
|
"name": "<impl Eq for (A, B, C, D, E, F, G, H, I)>::eq",
|
|
6267
|
-
"start":
|
|
6045
|
+
"start": 4056
|
|
6268
6046
|
},
|
|
6269
6047
|
{
|
|
6270
6048
|
"name": "<impl Eq for (A, B, C, D, E, F, G, H, I, J)>::eq",
|
|
6271
|
-
"start":
|
|
6049
|
+
"start": 4279
|
|
6272
6050
|
},
|
|
6273
6051
|
{
|
|
6274
6052
|
"name": "<impl Eq for (A, B, C, D, E, F, G, H, I, J, K)>::eq",
|
|
6275
|
-
"start":
|
|
6053
|
+
"start": 4516
|
|
6276
6054
|
},
|
|
6277
6055
|
{
|
|
6278
6056
|
"name": "<impl Eq for (A, B, C, D, E, F, G, H, I, J, K, L)>::eq",
|
|
6279
|
-
"start":
|
|
6057
|
+
"start": 4766
|
|
6280
6058
|
},
|
|
6281
6059
|
{
|
|
6282
6060
|
"name": "<impl Eq for Ordering>::eq",
|
|
6283
|
-
"start":
|
|
6061
|
+
"start": 4876
|
|
6284
6062
|
},
|
|
6285
6063
|
{
|
|
6286
6064
|
"name": "Ordering::less",
|
|
6287
|
-
"start":
|
|
6065
|
+
"start": 5477
|
|
6288
6066
|
},
|
|
6289
6067
|
{
|
|
6290
6068
|
"name": "Ordering::equal",
|
|
6291
|
-
"start":
|
|
6069
|
+
"start": 5548
|
|
6292
6070
|
},
|
|
6293
6071
|
{
|
|
6294
6072
|
"name": "Ordering::greater",
|
|
6295
|
-
"start":
|
|
6073
|
+
"start": 5621
|
|
6296
6074
|
},
|
|
6297
6075
|
{
|
|
6298
6076
|
"name": "derive_ord",
|
|
6299
|
-
"start":
|
|
6077
|
+
"start": 5992
|
|
6300
6078
|
},
|
|
6301
6079
|
{
|
|
6302
6080
|
"name": "<impl Ord for u128>::cmp",
|
|
6303
|
-
"start":
|
|
6081
|
+
"start": 6642
|
|
6304
6082
|
},
|
|
6305
6083
|
{
|
|
6306
6084
|
"name": "<impl Ord for u64>::cmp",
|
|
6307
|
-
"start":
|
|
6085
|
+
"start": 6889
|
|
6308
6086
|
},
|
|
6309
6087
|
{
|
|
6310
6088
|
"name": "<impl Ord for u32>::cmp",
|
|
6311
|
-
"start":
|
|
6089
|
+
"start": 7137
|
|
6312
6090
|
},
|
|
6313
6091
|
{
|
|
6314
6092
|
"name": "<impl Ord for u16>::cmp",
|
|
6315
|
-
"start":
|
|
6093
|
+
"start": 7385
|
|
6316
6094
|
},
|
|
6317
6095
|
{
|
|
6318
6096
|
"name": "<impl Ord for u8>::cmp",
|
|
6319
|
-
"start":
|
|
6097
|
+
"start": 7631
|
|
6320
6098
|
},
|
|
6321
6099
|
{
|
|
6322
6100
|
"name": "<impl Ord for i8>::cmp",
|
|
6323
|
-
"start":
|
|
6101
|
+
"start": 7877
|
|
6324
6102
|
},
|
|
6325
6103
|
{
|
|
6326
6104
|
"name": "<impl Ord for i16>::cmp",
|
|
6327
|
-
"start":
|
|
6105
|
+
"start": 8125
|
|
6328
6106
|
},
|
|
6329
6107
|
{
|
|
6330
6108
|
"name": "<impl Ord for i32>::cmp",
|
|
6331
|
-
"start":
|
|
6109
|
+
"start": 8373
|
|
6332
6110
|
},
|
|
6333
6111
|
{
|
|
6334
6112
|
"name": "<impl Ord for i64>::cmp",
|
|
6335
|
-
"start":
|
|
6113
|
+
"start": 8621
|
|
6336
6114
|
},
|
|
6337
6115
|
{
|
|
6338
6116
|
"name": "<impl Ord for ()>::cmp",
|
|
6339
|
-
"start":
|
|
6117
|
+
"start": 8875
|
|
6340
6118
|
},
|
|
6341
6119
|
{
|
|
6342
6120
|
"name": "<impl Ord for bool>::cmp",
|
|
6343
|
-
"start":
|
|
6121
|
+
"start": 8974
|
|
6344
6122
|
},
|
|
6345
6123
|
{
|
|
6346
6124
|
"name": "<impl Ord for [T; N]>::cmp",
|
|
6347
|
-
"start":
|
|
6125
|
+
"start": 9444
|
|
6348
6126
|
},
|
|
6349
6127
|
{
|
|
6350
6128
|
"name": "<impl Ord for [T]>::cmp",
|
|
6351
|
-
"start":
|
|
6129
|
+
"start": 9847
|
|
6352
6130
|
},
|
|
6353
6131
|
{
|
|
6354
6132
|
"name": "make_tuple_ord_body",
|
|
6355
|
-
"start":
|
|
6133
|
+
"start": 10415
|
|
6356
6134
|
},
|
|
6357
6135
|
{
|
|
6358
6136
|
"name": "<impl Ord for (A, B)>::cmp",
|
|
6359
|
-
"start":
|
|
6137
|
+
"start": 11037
|
|
6360
6138
|
},
|
|
6361
6139
|
{
|
|
6362
6140
|
"name": "<impl Ord for (A, B, C)>::cmp",
|
|
6363
|
-
"start":
|
|
6141
|
+
"start": 11179
|
|
6364
6142
|
},
|
|
6365
6143
|
{
|
|
6366
6144
|
"name": "<impl Ord for (A, B, C, D)>::cmp",
|
|
6367
|
-
"start":
|
|
6145
|
+
"start": 11335
|
|
6368
6146
|
},
|
|
6369
6147
|
{
|
|
6370
6148
|
"name": "<impl Ord for (A, B, C, D, E)>::cmp",
|
|
6371
|
-
"start":
|
|
6149
|
+
"start": 11505
|
|
6372
6150
|
},
|
|
6373
6151
|
{
|
|
6374
6152
|
"name": "<impl Ord for (A, B, C, D, E, F)>::cmp",
|
|
6375
|
-
"start":
|
|
6153
|
+
"start": 11689
|
|
6376
6154
|
},
|
|
6377
6155
|
{
|
|
6378
6156
|
"name": "<impl Ord for (A, B, C, D, E, F, G)>::cmp",
|
|
6379
|
-
"start":
|
|
6157
|
+
"start": 11887
|
|
6380
6158
|
},
|
|
6381
6159
|
{
|
|
6382
6160
|
"name": "<impl Ord for (A, B, C, D, E, F, G, H)>::cmp",
|
|
6383
|
-
"start":
|
|
6161
|
+
"start": 12099
|
|
6384
6162
|
},
|
|
6385
6163
|
{
|
|
6386
6164
|
"name": "<impl Ord for (A, B, C, D, E, F, G, H, I)>::cmp",
|
|
6387
|
-
"start":
|
|
6165
|
+
"start": 12325
|
|
6388
6166
|
},
|
|
6389
6167
|
{
|
|
6390
6168
|
"name": "<impl Ord for (A, B, C, D, E, F, G, H, I, J)>::cmp",
|
|
6391
|
-
"start":
|
|
6169
|
+
"start": 12565
|
|
6392
6170
|
},
|
|
6393
6171
|
{
|
|
6394
6172
|
"name": "<impl Ord for (A, B, C, D, E, F, G, H, I, J, K)>::cmp",
|
|
6395
|
-
"start":
|
|
6173
|
+
"start": 12820
|
|
6396
6174
|
},
|
|
6397
6175
|
{
|
|
6398
6176
|
"name": "<impl Ord for (A, B, C, D, E, F, G, H, I, J, K, L)>::cmp",
|
|
6399
|
-
"start":
|
|
6177
|
+
"start": 13089
|
|
6400
6178
|
},
|
|
6401
6179
|
{
|
|
6402
6180
|
"name": "max",
|
|
6403
|
-
"start":
|
|
6181
|
+
"start": 13451
|
|
6404
6182
|
},
|
|
6405
6183
|
{
|
|
6406
6184
|
"name": "min",
|
|
6407
|
-
"start":
|
|
6185
|
+
"start": 13828
|
|
6408
6186
|
},
|
|
6409
6187
|
{
|
|
6410
6188
|
"name": "cmp_tests::sanity_check_min",
|
|
6411
|
-
"start":
|
|
6189
|
+
"start": 13982
|
|
6412
6190
|
},
|
|
6413
6191
|
{
|
|
6414
6192
|
"name": "cmp_tests::sanity_check_max",
|
|
6415
|
-
"start":
|
|
6193
|
+
"start": 14178
|
|
6416
6194
|
},
|
|
6417
6195
|
{
|
|
6418
6196
|
"name": "cmp_tests::correctly_handles_unequal_length_vectors",
|
|
6419
|
-
"start":
|
|
6197
|
+
"start": 14400
|
|
6420
6198
|
},
|
|
6421
6199
|
{
|
|
6422
6200
|
"name": "cmp_tests::lexicographic_ordering_for_vectors",
|
|
6423
|
-
"start":
|
|
6201
|
+
"start": 14600
|
|
6424
6202
|
}
|
|
6425
6203
|
],
|
|
6426
6204
|
"path": "std/cmp.nr",
|
|
6427
|
-
"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"
|
|
6205
|
+
"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"
|
|
6428
6206
|
},
|
|
6429
6207
|
"50": {
|
|
6430
6208
|
"function_locations": [
|
|
@@ -6600,115 +6378,115 @@
|
|
|
6600
6378
|
},
|
|
6601
6379
|
{
|
|
6602
6380
|
"name": "PublicContext::l1_to_l2_msg_exists",
|
|
6603
|
-
"start":
|
|
6381
|
+
"start": 1786
|
|
6604
6382
|
},
|
|
6605
6383
|
{
|
|
6606
6384
|
"name": "PublicContext::nullifier_exists_unsafe",
|
|
6607
|
-
"start":
|
|
6385
|
+
"start": 2226
|
|
6608
6386
|
},
|
|
6609
6387
|
{
|
|
6610
6388
|
"name": "PublicContext::consume_l1_to_l2_message",
|
|
6611
|
-
"start":
|
|
6389
|
+
"start": 2685
|
|
6612
6390
|
},
|
|
6613
6391
|
{
|
|
6614
6392
|
"name": "PublicContext::message_portal",
|
|
6615
|
-
"start":
|
|
6393
|
+
"start": 3571
|
|
6616
6394
|
},
|
|
6617
6395
|
{
|
|
6618
6396
|
"name": "PublicContext::call_public_function",
|
|
6619
|
-
"start":
|
|
6397
|
+
"start": 3996
|
|
6620
6398
|
},
|
|
6621
6399
|
{
|
|
6622
6400
|
"name": "PublicContext::static_call_public_function",
|
|
6623
|
-
"start":
|
|
6401
|
+
"start": 4896
|
|
6624
6402
|
},
|
|
6625
6403
|
{
|
|
6626
6404
|
"name": "PublicContext::push_note_hash",
|
|
6627
|
-
"start":
|
|
6405
|
+
"start": 5597
|
|
6628
6406
|
},
|
|
6629
6407
|
{
|
|
6630
6408
|
"name": "PublicContext::push_nullifier",
|
|
6631
|
-
"start":
|
|
6409
|
+
"start": 5831
|
|
6632
6410
|
},
|
|
6633
6411
|
{
|
|
6634
6412
|
"name": "PublicContext::this_address",
|
|
6635
|
-
"start":
|
|
6413
|
+
"start": 6077
|
|
6636
6414
|
},
|
|
6637
6415
|
{
|
|
6638
6416
|
"name": "PublicContext::maybe_msg_sender",
|
|
6639
|
-
"start":
|
|
6417
|
+
"start": 6342
|
|
6640
6418
|
},
|
|
6641
6419
|
{
|
|
6642
6420
|
"name": "PublicContext::selector",
|
|
6643
|
-
"start":
|
|
6421
|
+
"start": 6764
|
|
6644
6422
|
},
|
|
6645
6423
|
{
|
|
6646
6424
|
"name": "PublicContext::get_args_hash",
|
|
6647
|
-
"start":
|
|
6425
|
+
"start": 7197
|
|
6648
6426
|
},
|
|
6649
6427
|
{
|
|
6650
6428
|
"name": "PublicContext::transaction_fee",
|
|
6651
|
-
"start":
|
|
6429
|
+
"start": 7485
|
|
6652
6430
|
},
|
|
6653
6431
|
{
|
|
6654
6432
|
"name": "PublicContext::chain_id",
|
|
6655
|
-
"start":
|
|
6433
|
+
"start": 7716
|
|
6656
6434
|
},
|
|
6657
6435
|
{
|
|
6658
6436
|
"name": "PublicContext::version",
|
|
6659
|
-
"start":
|
|
6437
|
+
"start": 7924
|
|
6660
6438
|
},
|
|
6661
6439
|
{
|
|
6662
6440
|
"name": "PublicContext::block_number",
|
|
6663
|
-
"start":
|
|
6441
|
+
"start": 8138
|
|
6664
6442
|
},
|
|
6665
6443
|
{
|
|
6666
6444
|
"name": "PublicContext::timestamp",
|
|
6667
|
-
"start":
|
|
6445
|
+
"start": 8364
|
|
6668
6446
|
},
|
|
6669
6447
|
{
|
|
6670
6448
|
"name": "PublicContext::min_fee_per_l2_gas",
|
|
6671
|
-
"start":
|
|
6449
|
+
"start": 8589
|
|
6672
6450
|
},
|
|
6673
6451
|
{
|
|
6674
6452
|
"name": "PublicContext::min_fee_per_da_gas",
|
|
6675
|
-
"start":
|
|
6453
|
+
"start": 8823
|
|
6676
6454
|
},
|
|
6677
6455
|
{
|
|
6678
6456
|
"name": "PublicContext::l2_gas_left",
|
|
6679
|
-
"start":
|
|
6457
|
+
"start": 9053
|
|
6680
6458
|
},
|
|
6681
6459
|
{
|
|
6682
6460
|
"name": "PublicContext::da_gas_left",
|
|
6683
|
-
"start":
|
|
6461
|
+
"start": 9276
|
|
6684
6462
|
},
|
|
6685
6463
|
{
|
|
6686
6464
|
"name": "PublicContext::is_static_call",
|
|
6687
|
-
"start":
|
|
6465
|
+
"start": 9527
|
|
6688
6466
|
},
|
|
6689
6467
|
{
|
|
6690
6468
|
"name": "PublicContext::raw_storage_read",
|
|
6691
|
-
"start":
|
|
6469
|
+
"start": 9781
|
|
6692
6470
|
},
|
|
6693
6471
|
{
|
|
6694
6472
|
"name": "PublicContext::storage_read",
|
|
6695
|
-
"start":
|
|
6473
|
+
"start": 10216
|
|
6696
6474
|
},
|
|
6697
6475
|
{
|
|
6698
6476
|
"name": "PublicContext::raw_storage_write",
|
|
6699
|
-
"start":
|
|
6477
|
+
"start": 10426
|
|
6700
6478
|
},
|
|
6701
6479
|
{
|
|
6702
6480
|
"name": "PublicContext::storage_write",
|
|
6703
|
-
"start":
|
|
6481
|
+
"start": 10767
|
|
6704
6482
|
},
|
|
6705
6483
|
{
|
|
6706
6484
|
"name": "<impl Empty for PublicContext>::empty",
|
|
6707
|
-
"start":
|
|
6485
|
+
"start": 10892
|
|
6708
6486
|
}
|
|
6709
6487
|
],
|
|
6710
6488
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/aztec_sublib/src/context/public_context.nr",
|
|
6711
|
-
"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"
|
|
6489
|
+
"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"
|
|
6712
6490
|
},
|
|
6713
6491
|
"62": {
|
|
6714
6492
|
"function_locations": [
|
|
@@ -6798,195 +6576,195 @@
|
|
|
6798
6576
|
},
|
|
6799
6577
|
{
|
|
6800
6578
|
"name": "is_static_call",
|
|
6801
|
-
"start":
|
|
6579
|
+
"start": 1080
|
|
6802
6580
|
},
|
|
6803
6581
|
{
|
|
6804
6582
|
"name": "note_hash_exists",
|
|
6805
|
-
"start":
|
|
6583
|
+
"start": 1193
|
|
6806
6584
|
},
|
|
6807
6585
|
{
|
|
6808
6586
|
"name": "emit_note_hash",
|
|
6809
|
-
"start":
|
|
6587
|
+
"start": 1302
|
|
6810
6588
|
},
|
|
6811
6589
|
{
|
|
6812
6590
|
"name": "nullifier_exists",
|
|
6813
|
-
"start":
|
|
6591
|
+
"start": 1414
|
|
6814
6592
|
},
|
|
6815
6593
|
{
|
|
6816
6594
|
"name": "emit_nullifier",
|
|
6817
|
-
"start":
|
|
6595
|
+
"start": 1518
|
|
6818
6596
|
},
|
|
6819
6597
|
{
|
|
6820
6598
|
"name": "emit_public_log",
|
|
6821
|
-
"start":
|
|
6599
|
+
"start": 1614
|
|
6822
6600
|
},
|
|
6823
6601
|
{
|
|
6824
6602
|
"name": "l1_to_l2_msg_exists",
|
|
6825
|
-
"start":
|
|
6603
|
+
"start": 1741
|
|
6826
6604
|
},
|
|
6827
6605
|
{
|
|
6828
6606
|
"name": "send_l2_to_l1_msg",
|
|
6829
|
-
"start":
|
|
6607
|
+
"start": 1880
|
|
6830
6608
|
},
|
|
6831
6609
|
{
|
|
6832
6610
|
"name": "call",
|
|
6833
|
-
"start":
|
|
6611
|
+
"start": 2080
|
|
6834
6612
|
},
|
|
6835
6613
|
{
|
|
6836
6614
|
"name": "call_static",
|
|
6837
|
-
"start":
|
|
6615
|
+
"start": 2310
|
|
6838
6616
|
},
|
|
6839
6617
|
{
|
|
6840
6618
|
"name": "calldata_copy",
|
|
6841
|
-
"start":
|
|
6619
|
+
"start": 2486
|
|
6842
6620
|
},
|
|
6843
6621
|
{
|
|
6844
6622
|
"name": "success_copy",
|
|
6845
|
-
"start":
|
|
6623
|
+
"start": 2669
|
|
6846
6624
|
},
|
|
6847
6625
|
{
|
|
6848
6626
|
"name": "returndata_size",
|
|
6849
|
-
"start":
|
|
6627
|
+
"start": 2746
|
|
6850
6628
|
},
|
|
6851
6629
|
{
|
|
6852
6630
|
"name": "returndata_copy",
|
|
6853
|
-
"start":
|
|
6631
|
+
"start": 2859
|
|
6854
6632
|
},
|
|
6855
6633
|
{
|
|
6856
6634
|
"name": "avm_return",
|
|
6857
|
-
"start":
|
|
6635
|
+
"start": 3044
|
|
6858
6636
|
},
|
|
6859
6637
|
{
|
|
6860
6638
|
"name": "revert",
|
|
6861
|
-
"start":
|
|
6639
|
+
"start": 3421
|
|
6862
6640
|
},
|
|
6863
6641
|
{
|
|
6864
6642
|
"name": "storage_read",
|
|
6865
|
-
"start":
|
|
6643
|
+
"start": 3545
|
|
6866
6644
|
},
|
|
6867
6645
|
{
|
|
6868
6646
|
"name": "storage_write",
|
|
6869
|
-
"start":
|
|
6647
|
+
"start": 3676
|
|
6870
6648
|
},
|
|
6871
6649
|
{
|
|
6872
6650
|
"name": "address_opcode",
|
|
6873
|
-
"start":
|
|
6651
|
+
"start": 3807
|
|
6874
6652
|
},
|
|
6875
6653
|
{
|
|
6876
6654
|
"name": "sender_opcode",
|
|
6877
|
-
"start":
|
|
6655
|
+
"start": 3888
|
|
6878
6656
|
},
|
|
6879
6657
|
{
|
|
6880
6658
|
"name": "transaction_fee_opcode",
|
|
6881
|
-
"start":
|
|
6659
|
+
"start": 3979
|
|
6882
6660
|
},
|
|
6883
6661
|
{
|
|
6884
6662
|
"name": "chain_id_opcode",
|
|
6885
|
-
"start":
|
|
6663
|
+
"start": 4056
|
|
6886
6664
|
},
|
|
6887
6665
|
{
|
|
6888
6666
|
"name": "version_opcode",
|
|
6889
|
-
"start":
|
|
6667
|
+
"start": 4132
|
|
6890
6668
|
},
|
|
6891
6669
|
{
|
|
6892
6670
|
"name": "block_number_opcode",
|
|
6893
|
-
"start":
|
|
6671
|
+
"start": 4215
|
|
6894
6672
|
},
|
|
6895
6673
|
{
|
|
6896
6674
|
"name": "timestamp_opcode",
|
|
6897
|
-
"start":
|
|
6675
|
+
"start": 4293
|
|
6898
6676
|
},
|
|
6899
6677
|
{
|
|
6900
6678
|
"name": "min_fee_per_l2_gas_opcode",
|
|
6901
|
-
"start":
|
|
6679
|
+
"start": 4386
|
|
6902
6680
|
},
|
|
6903
6681
|
{
|
|
6904
6682
|
"name": "min_fee_per_da_gas_opcode",
|
|
6905
|
-
"start":
|
|
6683
|
+
"start": 4479
|
|
6906
6684
|
},
|
|
6907
6685
|
{
|
|
6908
6686
|
"name": "l2_gas_left_opcode",
|
|
6909
|
-
"start":
|
|
6687
|
+
"start": 4559
|
|
6910
6688
|
},
|
|
6911
6689
|
{
|
|
6912
6690
|
"name": "da_gas_left_opcode",
|
|
6913
|
-
"start":
|
|
6691
|
+
"start": 4639
|
|
6914
6692
|
},
|
|
6915
6693
|
{
|
|
6916
6694
|
"name": "is_static_call_opcode",
|
|
6917
|
-
"start":
|
|
6695
|
+
"start": 4726
|
|
6918
6696
|
},
|
|
6919
6697
|
{
|
|
6920
6698
|
"name": "note_hash_exists_opcode",
|
|
6921
|
-
"start":
|
|
6699
|
+
"start": 4850
|
|
6922
6700
|
},
|
|
6923
6701
|
{
|
|
6924
6702
|
"name": "emit_note_hash_opcode",
|
|
6925
|
-
"start":
|
|
6703
|
+
"start": 4945
|
|
6926
6704
|
},
|
|
6927
6705
|
{
|
|
6928
6706
|
"name": "nullifier_exists_opcode",
|
|
6929
|
-
"start":
|
|
6707
|
+
"start": 5060
|
|
6930
6708
|
},
|
|
6931
6709
|
{
|
|
6932
6710
|
"name": "emit_nullifier_opcode",
|
|
6933
|
-
"start":
|
|
6711
|
+
"start": 5156
|
|
6934
6712
|
},
|
|
6935
6713
|
{
|
|
6936
6714
|
"name": "emit_public_log_opcode",
|
|
6937
|
-
"start":
|
|
6715
|
+
"start": 5253
|
|
6938
6716
|
},
|
|
6939
6717
|
{
|
|
6940
6718
|
"name": "l1_to_l2_msg_exists_opcode",
|
|
6941
|
-
"start":
|
|
6719
|
+
"start": 5384
|
|
6942
6720
|
},
|
|
6943
6721
|
{
|
|
6944
6722
|
"name": "send_l2_to_l1_msg_opcode",
|
|
6945
|
-
"start":
|
|
6723
|
+
"start": 5504
|
|
6946
6724
|
},
|
|
6947
6725
|
{
|
|
6948
6726
|
"name": "calldata_copy_opcode",
|
|
6949
|
-
"start":
|
|
6727
|
+
"start": 5637
|
|
6950
6728
|
},
|
|
6951
6729
|
{
|
|
6952
6730
|
"name": "returndata_size_opcode",
|
|
6953
|
-
"start":
|
|
6731
|
+
"start": 5726
|
|
6954
6732
|
},
|
|
6955
6733
|
{
|
|
6956
6734
|
"name": "returndata_copy_opcode",
|
|
6957
|
-
"start":
|
|
6735
|
+
"start": 5848
|
|
6958
6736
|
},
|
|
6959
6737
|
{
|
|
6960
6738
|
"name": "return_opcode",
|
|
6961
|
-
"start":
|
|
6739
|
+
"start": 5932
|
|
6962
6740
|
},
|
|
6963
6741
|
{
|
|
6964
6742
|
"name": "revert_opcode",
|
|
6965
|
-
"start":
|
|
6743
|
+
"start": 6016
|
|
6966
6744
|
},
|
|
6967
6745
|
{
|
|
6968
6746
|
"name": "call_opcode",
|
|
6969
|
-
"start":
|
|
6747
|
+
"start": 6463
|
|
6970
6748
|
},
|
|
6971
6749
|
{
|
|
6972
6750
|
"name": "call_static_opcode",
|
|
6973
|
-
"start":
|
|
6751
|
+
"start": 6923
|
|
6974
6752
|
},
|
|
6975
6753
|
{
|
|
6976
6754
|
"name": "success_copy_opcode",
|
|
6977
|
-
"start":
|
|
6755
|
+
"start": 7007
|
|
6978
6756
|
},
|
|
6979
6757
|
{
|
|
6980
6758
|
"name": "storage_read_opcode",
|
|
6981
|
-
"start":
|
|
6759
|
+
"start": 7136
|
|
6982
6760
|
},
|
|
6983
6761
|
{
|
|
6984
6762
|
"name": "storage_write_opcode",
|
|
6985
|
-
"start":
|
|
6763
|
+
"start": 7247
|
|
6986
6764
|
}
|
|
6987
6765
|
],
|
|
6988
6766
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/aztec_sublib/src/oracle/avm.nr",
|
|
6989
|
-
"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() ->
|
|
6767
|
+
"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"
|
|
6990
6768
|
},
|
|
6991
6769
|
"76": {
|
|
6992
6770
|
"function_locations": [
|
|
@@ -7106,27 +6884,27 @@
|
|
|
7106
6884
|
"function_locations": [
|
|
7107
6885
|
{
|
|
7108
6886
|
"name": "assert_compatible_oracle_version",
|
|
7109
|
-
"start":
|
|
6887
|
+
"start": 1191
|
|
7110
6888
|
},
|
|
7111
6889
|
{
|
|
7112
6890
|
"name": "assert_compatible_oracle_version_wrapper",
|
|
7113
|
-
"start":
|
|
6891
|
+
"start": 1500
|
|
7114
6892
|
},
|
|
7115
6893
|
{
|
|
7116
6894
|
"name": "assert_compatible_oracle_version_oracle",
|
|
7117
|
-
"start":
|
|
6895
|
+
"start": 1732
|
|
7118
6896
|
},
|
|
7119
6897
|
{
|
|
7120
6898
|
"name": "test::compatible_oracle_version",
|
|
7121
|
-
"start":
|
|
6899
|
+
"start": 1926
|
|
7122
6900
|
},
|
|
7123
6901
|
{
|
|
7124
|
-
"name": "test::
|
|
7125
|
-
"start":
|
|
6902
|
+
"name": "test::incompatible_oracle_version_major",
|
|
6903
|
+
"start": 2151
|
|
7126
6904
|
}
|
|
7127
6905
|
],
|
|
7128
6906
|
"path": "/home/aztec-dev/aztec-packages/noir-projects/noir-contracts/contracts/protocol/aztec_sublib/src/oracle/version.nr",
|
|
7129
|
-
"source": "/// The
|
|
6907
|
+
"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"
|
|
7130
6908
|
},
|
|
7131
6909
|
"86": {
|
|
7132
6910
|
"function_locations": [
|