@aztec/ivc-integration 0.86.0 → 0.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/artifacts/app_creator.json +1 -1
- package/artifacts/app_reader.json +1 -1
- package/artifacts/keys/mock_private_kernel_init.vk.data.json +83 -83
- package/artifacts/keys/mock_private_kernel_inner.vk.data.json +83 -83
- package/artifacts/keys/mock_private_kernel_reset.vk.data.json +87 -87
- package/artifacts/keys/mock_private_kernel_tail.vk.data.json +83 -83
- package/artifacts/keys/mock_rollup_base_private.vk.data.json +85 -85
- package/artifacts/keys/mock_rollup_base_public.vk.data.json +85 -85
- package/artifacts/keys/mock_rollup_merge.vk.data.json +85 -85
- package/artifacts/keys/mock_rollup_root.vk.data.json +85 -85
- package/artifacts/keys/mock_rollup_root_verifier.sol +52 -52
- package/artifacts/mock_private_kernel_init.json +1 -1
- package/artifacts/mock_private_kernel_inner.json +1 -1
- package/artifacts/mock_private_kernel_reset.json +1 -1
- package/artifacts/mock_private_kernel_tail.json +1 -1
- package/artifacts/mock_rollup_base_private.json +1 -1
- package/artifacts/mock_rollup_base_public.json +1 -1
- package/artifacts/mock_rollup_merge.json +1 -1
- package/artifacts/mock_rollup_root.json +1 -1
- package/dest/prove_native.d.ts +1 -1
- package/dest/prove_native.d.ts.map +1 -1
- package/dest/prove_native.js +7 -3
- package/dest/types/index.d.ts +106 -2
- package/dest/types/index.d.ts.map +1 -1
- package/dest/types/index.js +2 -2
- package/dest/witgen.d.ts +14 -4
- package/dest/witgen.d.ts.map +1 -1
- package/dest/witgen.js +58 -36
- package/package.json +19 -18
- package/src/prove_native.ts +15 -1
- package/src/types/index.ts +125 -3
- package/src/witgen.ts +68 -40
|
@@ -12,72 +12,72 @@ library HonkVerificationKey {
|
|
|
12
12
|
logCircuitSize: uint256(25),
|
|
13
13
|
publicInputsSize: uint256(17),
|
|
14
14
|
ql: Honk.G1Point({
|
|
15
|
-
x: uint256(
|
|
16
|
-
y: uint256(
|
|
15
|
+
x: uint256(0x293f4deeba2c9f02890fb003ff26f222290616e7f78b2c466d845bbfea6557a0),
|
|
16
|
+
y: uint256(0x2268247f6dd4176b4de919525083b9d7ff594315673d0a9bb1f5d72b504902dd)
|
|
17
17
|
}),
|
|
18
18
|
qr: Honk.G1Point({
|
|
19
|
-
x: uint256(
|
|
20
|
-
y: uint256(
|
|
19
|
+
x: uint256(0x1a3fba463e9ae5db2d9d523a61970b609b75d2a362f32687d5e4c8687cca751a),
|
|
20
|
+
y: uint256(0x1715c81cde81a44d0ff94a8667511f0d5a89f3bad51eb166fe82d035ed7600d7)
|
|
21
21
|
}),
|
|
22
22
|
qo: Honk.G1Point({
|
|
23
|
-
x: uint256(
|
|
24
|
-
y: uint256(
|
|
23
|
+
x: uint256(0x1c9f6d804b5067eef213bdf32ec6beb634bd7109436b925300520bda4bc9f174),
|
|
24
|
+
y: uint256(0x1b325eac948f59ab7f0382506db26f4ea5e90ac0245eab061774596b7b6b2de6)
|
|
25
25
|
}),
|
|
26
26
|
q4: Honk.G1Point({
|
|
27
|
-
x: uint256(
|
|
28
|
-
y: uint256(
|
|
27
|
+
x: uint256(0x140a2d5f09c4629701305ba25f64f77b7799e2d4856aec915d59715f26d2ea92),
|
|
28
|
+
y: uint256(0x1aab3ed84ebfe7f39c58532413602c9c0a35d837fccfcef4742195ff730d1582)
|
|
29
29
|
}),
|
|
30
30
|
qm: Honk.G1Point({
|
|
31
|
-
x: uint256(
|
|
32
|
-
y: uint256(
|
|
31
|
+
x: uint256(0x04253787ee38e4502d7176bc3ddeca3f939df3d1a9081b927b03b508e0d0dc67),
|
|
32
|
+
y: uint256(0x10356aa45aa528d7aa8664964386ecd661ea3af4dc50e34962fc63aa31596da0)
|
|
33
33
|
}),
|
|
34
34
|
qc: Honk.G1Point({
|
|
35
|
-
x: uint256(
|
|
36
|
-
y: uint256(
|
|
35
|
+
x: uint256(0x15dd774b089af14d0b103945a67f03f5f372b66ea1ab630b80d43d3074704912),
|
|
36
|
+
y: uint256(0x2358bae2ea6993f53f253d9923d4a02c89fb90bb9c8d2762c164bd329708127b)
|
|
37
37
|
}),
|
|
38
38
|
qArith: Honk.G1Point({
|
|
39
|
-
x: uint256(
|
|
40
|
-
y: uint256(
|
|
39
|
+
x: uint256(0x253ad7ea09d5cd7e1ad1467202fcb0956eb6a7d9939f1a9a9330055f138ac15b),
|
|
40
|
+
y: uint256(0x05c0e03f9c49259b3121aae7779427aac56f3d47d68b238a25fb55581898865c)
|
|
41
41
|
}),
|
|
42
42
|
qDeltaRange: Honk.G1Point({
|
|
43
|
-
x: uint256(
|
|
44
|
-
y: uint256(
|
|
43
|
+
x: uint256(0x282e3e3af9953d1fa25d72862046f0db269613d06b44e51af63f3a9ab2b353ba),
|
|
44
|
+
y: uint256(0x2ffea3c90c6f7d72bdda13415c266fc1995dfeb7936c356e69c8667fda56b416)
|
|
45
45
|
}),
|
|
46
46
|
qElliptic: Honk.G1Point({
|
|
47
|
-
x: uint256(
|
|
48
|
-
y: uint256(
|
|
47
|
+
x: uint256(0x24f2da467bae9dcdb5b7f7ec77fbe770f45653c6f043a5d2d210392f5113ae66),
|
|
48
|
+
y: uint256(0x26486183b4fcbbb589ff1a2ea360ffc28b4716a4d7e5772bab3c59207b2f924d)
|
|
49
49
|
}),
|
|
50
50
|
qAux: Honk.G1Point({
|
|
51
|
-
x: uint256(
|
|
52
|
-
y: uint256(
|
|
51
|
+
x: uint256(0x0c4945a0bcdb1921655f4770e195c301d7fc6361ec3a462b444a8fec7e735860),
|
|
52
|
+
y: uint256(0x132ddc8ae5b5ee520d57f13e3c0e8a9f3cd8c4754c00e779109d0b424da8fe29)
|
|
53
53
|
}),
|
|
54
54
|
qLookup: Honk.G1Point({
|
|
55
55
|
x: uint256(0x0c4032c3079594eb75a8449d3d5ce8bc3661650d53f9b24d923d8f404cb0bbc9),
|
|
56
56
|
y: uint256(0x1084d709650356d40f0158fd6da81f54eb5fe796a0ca89441369b7c24301f851)
|
|
57
57
|
}),
|
|
58
58
|
qPoseidon2External: Honk.G1Point({
|
|
59
|
-
x: uint256(
|
|
60
|
-
y: uint256(
|
|
59
|
+
x: uint256(0x175c1d1f25ea2c1f8d01b7323165cce3e61496a9ffb2a6ff9731dcc656d12337),
|
|
60
|
+
y: uint256(0x1ab3e834ac5714c7e186497c9a3201ff80a35b8d49a5a64a3d8674fe30bac66b)
|
|
61
61
|
}),
|
|
62
62
|
qPoseidon2Internal: Honk.G1Point({
|
|
63
|
-
x: uint256(
|
|
64
|
-
y: uint256(
|
|
63
|
+
x: uint256(0x04f1c2c456a8142b6619704e9de03cd7eb0af580ab2399b6e77d21f039dd2987),
|
|
64
|
+
y: uint256(0x0074130a3da29a1f8b145dc22cff3ccfbc5ecd24725d167b9ebd57d2683c221c)
|
|
65
65
|
}),
|
|
66
66
|
s1: Honk.G1Point({
|
|
67
|
-
x: uint256(
|
|
68
|
-
y: uint256(
|
|
67
|
+
x: uint256(0x2ddff2910f3b472ec5606dac6cf4b30c4e5d8fe24a1dfa1221501ca6e2428931),
|
|
68
|
+
y: uint256(0x229f62cbfe90506f58bd0e5a9eabce0486c42f0278db1c7a668291509a5401d6)
|
|
69
69
|
}),
|
|
70
70
|
s2: Honk.G1Point({
|
|
71
|
-
x: uint256(
|
|
72
|
-
y: uint256(
|
|
71
|
+
x: uint256(0x063ca7758b6fa95a56b0a38156bce9d09ccf87b85f1fe5e1356f5b686faf243e),
|
|
72
|
+
y: uint256(0x275af09fc648a2544815af14ca5524863f2a673ade77ba7ce0e83d727eb2bfaf)
|
|
73
73
|
}),
|
|
74
74
|
s3: Honk.G1Point({
|
|
75
|
-
x: uint256(
|
|
76
|
-
y: uint256(
|
|
75
|
+
x: uint256(0x2b1a8a217e1ee14411b2d0e90a1d6959819dc3c291d4f32688a96b60df9e81d1),
|
|
76
|
+
y: uint256(0x06bf0334b3b9f01ae005ae5a3bd7bfa23dd91f88485d70ebf24951170e6d5094)
|
|
77
77
|
}),
|
|
78
78
|
s4: Honk.G1Point({
|
|
79
|
-
x: uint256(
|
|
80
|
-
y: uint256(
|
|
79
|
+
x: uint256(0x06ccb6716446714c981ce66f933ead99b809f8e4a1e2734730a4668552467a30),
|
|
80
|
+
y: uint256(0x0c3db525766d4cf453c81c0c8d941cc35707e683b6fd7ce11b8535fd4496232f)
|
|
81
81
|
}),
|
|
82
82
|
t1: Honk.G1Point({
|
|
83
83
|
x: uint256(0x0450f8716810dff987300c3bc10a892b1c1c2637db3f8fecd9d8bb38442cc468),
|
|
@@ -96,28 +96,28 @@ library HonkVerificationKey {
|
|
|
96
96
|
y: uint256(0x2c6b2a0de0a3fefdfc4fb4f3b8381d2c37ccc495848c2887f98bfbaca776ca39)
|
|
97
97
|
}),
|
|
98
98
|
id1: Honk.G1Point({
|
|
99
|
-
x: uint256(
|
|
100
|
-
y: uint256(
|
|
99
|
+
x: uint256(0x29403cad1be6a56debc50698ffadbb8645bedd78306abe2e7d5602c6ca42667c),
|
|
100
|
+
y: uint256(0x2c33eecf4762af9d53afdf4bbb346d91442eec97b45846360b527c596d4248fe)
|
|
101
101
|
}),
|
|
102
102
|
id2: Honk.G1Point({
|
|
103
|
-
x: uint256(
|
|
104
|
-
y: uint256(
|
|
103
|
+
x: uint256(0x12f9d576650886ce389b16835c6f65f869222c2437fd5fdc7f1ee31f2b7f8544),
|
|
104
|
+
y: uint256(0x0463736a102af992a8edb1d90127daca1b7d6e6250cc0421e3104ee5ffad4fd7)
|
|
105
105
|
}),
|
|
106
106
|
id3: Honk.G1Point({
|
|
107
|
-
x: uint256(
|
|
108
|
-
y: uint256(
|
|
107
|
+
x: uint256(0x2244193f3d5ac6080b74eb7f840303331663be8388facb407c27cc5c901529e6),
|
|
108
|
+
y: uint256(0x2177feecfa6a37e85fc55e7345454d45a4990191863afceb09e190041ca3eeb0)
|
|
109
109
|
}),
|
|
110
110
|
id4: Honk.G1Point({
|
|
111
|
-
x: uint256(
|
|
112
|
-
y: uint256(
|
|
111
|
+
x: uint256(0x1dadf22ba11b25eff33603bd60eaf3b53c0a42164f82e24c347072b0e1be9ddd),
|
|
112
|
+
y: uint256(0x0717d71d5417edcadd0a2f2fef1f1ebe132ed923614a4f99f54aa704a1e74609)
|
|
113
113
|
}),
|
|
114
114
|
lagrangeFirst: Honk.G1Point({
|
|
115
115
|
x: uint256(0x0000000000000000000000000000000000000000000000000000000000000001),
|
|
116
116
|
y: uint256(0x0000000000000000000000000000000000000000000000000000000000000002)
|
|
117
117
|
}),
|
|
118
118
|
lagrangeLast: Honk.G1Point({
|
|
119
|
-
x: uint256(
|
|
120
|
-
y: uint256(
|
|
119
|
+
x: uint256(0x08154ce1c8301a5268e8fccf8c5ee7d9d867e7bcdd5133ea5b4090c75e0771da),
|
|
120
|
+
y: uint256(0x02f971dfe23fa7a8a909caee031932e140b1caab714941e4200d5c3e9659e190)
|
|
121
121
|
})
|
|
122
122
|
});
|
|
123
123
|
return vk;
|
|
@@ -269,7 +269,7 @@ uint256 constant BATCHED_RELATION_PARTIAL_LENGTH = 8;
|
|
|
269
269
|
uint256 constant NUMBER_OF_ENTITIES = 40;
|
|
270
270
|
uint256 constant NUMBER_UNSHIFTED = 35;
|
|
271
271
|
uint256 constant NUMBER_TO_BE_SHIFTED = 5;
|
|
272
|
-
uint256 constant
|
|
272
|
+
uint256 constant PAIRING_POINTS_SIZE = 16;
|
|
273
273
|
|
|
274
274
|
// Alphas are used as relation separators so there should be NUMBER_OF_SUBRELATIONS - 1
|
|
275
275
|
uint256 constant NUMBER_OF_ALPHAS = 25;
|
|
@@ -388,7 +388,7 @@ library Honk {
|
|
|
388
388
|
|
|
389
389
|
struct Proof {
|
|
390
390
|
// Pairing point object
|
|
391
|
-
Fr[
|
|
391
|
+
Fr[PAIRING_POINTS_SIZE] pairingPointObject;
|
|
392
392
|
// Free wires
|
|
393
393
|
Honk.G1ProofPoint w1;
|
|
394
394
|
Honk.G1ProofPoint w2;
|
|
@@ -487,11 +487,11 @@ library TranscriptLib {
|
|
|
487
487
|
round0[1] = bytes32(publicInputsSize);
|
|
488
488
|
round0[2] = bytes32(pubInputsOffset);
|
|
489
489
|
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1331): Consider making publicInputsSize not include pairing point object.
|
|
490
|
-
for (uint256 i = 0; i < publicInputsSize -
|
|
490
|
+
for (uint256 i = 0; i < publicInputsSize - PAIRING_POINTS_SIZE; i++) {
|
|
491
491
|
round0[3 + i] = bytes32(publicInputs[i]);
|
|
492
492
|
}
|
|
493
|
-
for (uint256 i = 0; i <
|
|
494
|
-
round0[3 + publicInputsSize -
|
|
493
|
+
for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {
|
|
494
|
+
round0[3 + publicInputsSize - PAIRING_POINTS_SIZE + i] = FrLib.toBytes32(proof.pairingPointObject[i]);
|
|
495
495
|
}
|
|
496
496
|
|
|
497
497
|
// Create the first challenge
|
|
@@ -681,7 +681,7 @@ library TranscriptLib {
|
|
|
681
681
|
uint256 boundary = 0x0;
|
|
682
682
|
|
|
683
683
|
// Pairing point object
|
|
684
|
-
for (uint256 i = 0; i <
|
|
684
|
+
for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {
|
|
685
685
|
p.pairingPointObject[i] = bytesToFr(proof[boundary:boundary + 0x20]);
|
|
686
686
|
boundary += 0x20;
|
|
687
687
|
}
|
|
@@ -1573,7 +1573,7 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1573
1573
|
Honk.VerificationKey memory vk = loadVerificationKey();
|
|
1574
1574
|
Honk.Proof memory p = TranscriptLib.loadProof(proof);
|
|
1575
1575
|
|
|
1576
|
-
if (publicInputs.length != vk.publicInputsSize -
|
|
1576
|
+
if (publicInputs.length != vk.publicInputsSize - PAIRING_POINTS_SIZE) {
|
|
1577
1577
|
revert PublicInputsLengthWrong();
|
|
1578
1578
|
}
|
|
1579
1579
|
|
|
@@ -1597,7 +1597,7 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1597
1597
|
return sumcheckVerified && shpleminiVerified; // Boolean condition not required - nice for vanity :)
|
|
1598
1598
|
}
|
|
1599
1599
|
|
|
1600
|
-
function computePublicInputDelta(bytes32[] memory publicInputs, Fr[
|
|
1600
|
+
function computePublicInputDelta(bytes32[] memory publicInputs, Fr[PAIRING_POINTS_SIZE] memory pairingPointObject, Fr beta, Fr gamma, uint256 offset)
|
|
1601
1601
|
internal
|
|
1602
1602
|
view
|
|
1603
1603
|
returns (Fr publicInputDelta)
|
|
@@ -1609,7 +1609,7 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1609
1609
|
Fr denominatorAcc = gamma - (beta * FrLib.from(offset + 1));
|
|
1610
1610
|
|
|
1611
1611
|
{
|
|
1612
|
-
for (uint256 i = 0; i < numPublicInputs -
|
|
1612
|
+
for (uint256 i = 0; i < numPublicInputs - PAIRING_POINTS_SIZE; i++) {
|
|
1613
1613
|
Fr pubInput = FrLib.fromBytes32(publicInputs[i]);
|
|
1614
1614
|
|
|
1615
1615
|
numerator = numerator * (numeratorAcc + pubInput);
|
|
@@ -1619,7 +1619,7 @@ abstract contract BaseHonkVerifier is IVerifier {
|
|
|
1619
1619
|
denominatorAcc = denominatorAcc - beta;
|
|
1620
1620
|
}
|
|
1621
1621
|
|
|
1622
|
-
for (uint256 i = 0; i <
|
|
1622
|
+
for (uint256 i = 0; i < PAIRING_POINTS_SIZE; i++) {
|
|
1623
1623
|
Fr pubInput = pairingPointObject[i];
|
|
1624
1624
|
|
|
1625
1625
|
numerator = numerator * (numeratorAcc + pubInput);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"noir_version":"1.0.0-beta.4+0000000000000000000000000000000000000000","hash":"5418847362079696209","abi":{"parameters":[{"name":"tx","type":{"kind":"struct","path":"mock_types::TxRequest","fields":[{"name":"number_of_calls","type":{"kind":"integer","sign":"unsigned","width":32}}]},"visibility":"private"},{"name":"app_inputs","type":{"kind":"struct","path":"mock_types::AppPublicInputs","fields":[{"name":"commitments","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"read_requests","type":{"kind":"array","length":2,"type":{"kind":"field"}}}]},"visibility":"databus"},{"name":"app_vk","type":{"kind":"array","length":127,"type":{"kind":"field"}},"visibility":"private"}],"return_type":{"abi_type":{"kind":"struct","path":"mock_types::PrivateKernelPublicInputs","fields":[{"name":"remaining_calls","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"commitments","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"read_requests","type":{"kind":"array","length":4,"type":{"kind":"field"}}}]},"visibility":"databus"},"error_types":{"2920182694213909827":{"error_kind":"string","string":"attempt to subtract with overflow"},"5727012404371710682":{"error_kind":"string","string":"push out of bounds"},"14225679739041873922":{"error_kind":"string","string":"Index out of bounds"}}},"bytecode":"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","debug_symbols":"zZnNioMwFIXfJesuknvz66sMQ7GtLYJosXZgKH330aK2Y4sbiZydNzn5+DZer+QmDtnuetrm5bG6iOTrJopqnzZ5VbbVTajH0uWcll11adK6EQk7txFZeRCJ1vK+Ece8yERi2se3qLJs+qxyyo9hovv3RlBUOn+iG5b9CWPDPJ0Cqz5LwapnWHV0HZVuotJtVLqLSvdR6WEx3Q9ZlvIf/T1svdF92Hr3DNvOREkcFYWjQjgqjKOicVTMqipBDh8AG8hNVCyOisNR8TgqAUaFJI7Kut026PFlDmaqQjgqjKOicVQMjorFUXE4Kku7Lasxy8rSZFylEBXPMi5excVTXDzHxevFeD/86DBJvWCmY4OjYnFUHI6Kx1EJMCparqoyN9NphaNCOCqMo6JxVAyOyrrddm6Q0g5HxeOoBBgVs7jbkvWjSuDJOGRURHxb7Oq8KPLT9vX2o13+Ses83RVZXx6v5f5lt/k9DzvD+XNd7bPDtc460mOvxf8B","file_map":{"6":{"source":"use crate::{cmp::Eq, convert::From, runtime::is_unconstrained, static_assert};\n\n/// A `BoundedVec<T, MaxLen>` is a growable storage similar to a `Vec<T>` except that it\n/// is bounded with a maximum possible length. Unlike `Vec`, `BoundedVec` is not implemented\n/// via slices and thus is not subject to the same restrictions slices are (notably, nested\n/// slices - and thus nested vectors as well - are disallowed).\n///\n/// Since a BoundedVec is backed by a normal array under the hood, growing the BoundedVec by\n/// pushing an additional element is also more efficient - the length only needs to be increased\n/// by one.\n///\n/// For these reasons `BoundedVec<T, N>` should generally be preferred over `Vec<T>` when there\n/// is a reasonable maximum bound that can be placed on the vector.\n///\n/// Example:\n///\n/// ```noir\n/// let mut vector: BoundedVec<Field, 10> = BoundedVec::new();\n/// for i in 0..5 {\n/// vector.push(i);\n/// }\n/// assert(vector.len() == 5);\n/// assert(vector.max_len() == 10);\n/// ```\npub struct BoundedVec<T, let MaxLen: u32> {\n storage: [T; MaxLen],\n len: u32,\n}\n\nimpl<T, let MaxLen: u32> BoundedVec<T, MaxLen> {\n /// Creates a new, empty vector of length zero.\n ///\n /// Since this container is backed by an array internally, it still needs an initial value\n /// to give each element. To resolve this, each element is zeroed internally. This value\n /// is guaranteed to be inaccessible unless `get_unchecked` is used.\n ///\n /// Example:\n ///\n /// ```noir\n /// let empty_vector: BoundedVec<Field, 10> = BoundedVec::new();\n /// assert(empty_vector.len() == 0);\n /// ```\n ///\n /// Note that whenever calling `new` the maximum length of the vector should always be specified\n /// via a type signature:\n ///\n /// ```noir\n /// fn good() -> BoundedVec<Field, 10> {\n /// // Ok! MaxLen is specified with a type annotation\n /// let v1: BoundedVec<Field, 3> = BoundedVec::new();\n /// let v2 = BoundedVec::new();\n ///\n /// // Ok! MaxLen is known from the type of `good`'s return value\n /// v2\n /// }\n ///\n /// fn bad() {\n /// // Error: Type annotation needed\n /// // The compiler can't infer `MaxLen` from the following code:\n /// let mut v3 = BoundedVec::new();\n /// v3.push(5);\n /// }\n /// ```\n ///\n /// This defaulting of `MaxLen` (and numeric generics in general) to zero may change in future noir versions\n /// but for now make sure to use type annotations when using bounded vectors. Otherwise, you will receive a\n /// constraint failure at runtime when the vec is pushed to.\n pub fn new() -> Self {\n let zeroed = crate::mem::zeroed();\n BoundedVec { storage: [zeroed; MaxLen], len: 0 }\n }\n\n /// Retrieves an element from the vector at the given index, starting from zero.\n ///\n /// If the given index is equal to or greater than the length of the vector, this\n /// will issue a constraint failure.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn foo<let N: u32>(v: BoundedVec<u32, N>) {\n /// let first = v.get(0);\n /// let last = v.get(v.len() - 1);\n /// assert(first != last);\n /// }\n /// ```\n pub fn get(self, index: u32) -> T {\n assert(index < self.len, \"Attempted to read past end of BoundedVec\");\n self.get_unchecked(index)\n }\n\n /// Retrieves an element from the vector at the given index, starting from zero, without\n /// performing a bounds check.\n ///\n /// Since this function does not perform a bounds check on length before accessing the element,\n /// it is unsafe! Use at your own risk!\n ///\n /// Example:\n ///\n /// ```noir\n /// fn sum_of_first_three<let N: u32>(v: BoundedVec<u32, N>) -> u32 {\n /// // Always ensure the length is larger than the largest\n /// // index passed to get_unchecked\n /// assert(v.len() > 2);\n /// let first = v.get_unchecked(0);\n /// let second = v.get_unchecked(1);\n /// let third = v.get_unchecked(2);\n /// first + second + third\n /// }\n /// ```\n pub fn get_unchecked(self, index: u32) -> T {\n self.storage[index]\n }\n\n /// Writes an element to the vector at the given index, starting from zero.\n ///\n /// If the given index is equal to or greater than the length of the vector, this will issue a constraint failure.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn foo<let N: u32>(v: BoundedVec<u32, N>) {\n /// let first = v.get(0);\n /// assert(first != 42);\n /// v.set(0, 42);\n /// let new_first = v.get(0);\n /// assert(new_first == 42);\n /// }\n /// ```\n pub fn set(&mut self, index: u32, value: T) {\n assert(index < self.len, \"Attempted to write past end of BoundedVec\");\n self.set_unchecked(index, value)\n }\n\n /// Writes an element to the vector at the given index, starting from zero, without performing a bounds check.\n ///\n /// Since this function does not perform a bounds check on length before accessing the element, it is unsafe! Use at your own risk!\n ///\n /// Example:\n ///\n /// ```noir\n /// fn set_unchecked_example() {\n /// let mut vec: BoundedVec<u32, 5> = BoundedVec::new();\n /// vec.extend_from_array([1, 2]);\n ///\n /// // Here we're safely writing within the valid range of `vec`\n /// // `vec` now has the value [42, 2]\n /// vec.set_unchecked(0, 42);\n ///\n /// // We can then safely read this value back out of `vec`.\n /// // Notice that we use the checked version of `get` which would prevent reading unsafe values.\n /// assert_eq(vec.get(0), 42);\n ///\n /// // We've now written past the end of `vec`.\n /// // As this index is still within the maximum potential length of `v`,\n /// // it won't cause a constraint failure.\n /// vec.set_unchecked(2, 42);\n /// println(vec);\n ///\n /// // This will write past the end of the maximum potential length of `vec`,\n /// // it will then trigger a constraint failure.\n /// vec.set_unchecked(5, 42);\n /// println(vec);\n /// }\n /// ```\n pub fn set_unchecked(&mut self, index: u32, value: T) {\n self.storage[index] = value;\n }\n\n /// Pushes an element to the end of the vector. This increases the length\n /// of the vector by one.\n ///\n /// Panics if the new length of the vector will be greater than the max length.\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut v: BoundedVec<Field, 2> = BoundedVec::new();\n ///\n /// v.push(1);\n /// v.push(2);\n ///\n /// // Panics with failed assertion \"push out of bounds\"\n /// v.push(3);\n /// ```\n pub fn push(&mut self, elem: T) {\n assert(self.len < MaxLen, \"push out of bounds\");\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n /// Returns the current length of this vector\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut v: BoundedVec<Field, 4> = BoundedVec::new();\n /// assert(v.len() == 0);\n ///\n /// v.push(100);\n /// assert(v.len() == 1);\n ///\n /// v.push(200);\n /// v.push(300);\n /// v.push(400);\n /// assert(v.len() == 4);\n ///\n /// let _ = v.pop();\n /// let _ = v.pop();\n /// assert(v.len() == 2);\n /// ```\n pub fn len(self) -> u32 {\n self.len\n }\n\n /// Returns the maximum length of this vector. This is always\n /// equal to the `MaxLen` parameter this vector was initialized with.\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut v: BoundedVec<Field, 5> = BoundedVec::new();\n ///\n /// assert(v.max_len() == 5);\n /// v.push(10);\n /// assert(v.max_len() == 5);\n /// ```\n pub fn max_len(_self: BoundedVec<T, MaxLen>) -> u32 {\n MaxLen\n }\n\n /// Returns the internal array within this vector.\n ///\n /// Since arrays in Noir are immutable, mutating the returned storage array will not mutate\n /// the storage held internally by this vector.\n ///\n /// Note that uninitialized elements may be zeroed out!\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut v: BoundedVec<Field, 5> = BoundedVec::new();\n ///\n /// assert(v.storage() == [0, 0, 0, 0, 0]);\n ///\n /// v.push(57);\n /// assert(v.storage() == [57, 0, 0, 0, 0]);\n /// ```\n pub fn storage(self) -> [T; MaxLen] {\n self.storage\n }\n\n /// Pushes each element from the given array to this vector.\n ///\n /// Panics if pushing each element would cause the length of this vector\n /// to exceed the maximum length.\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut vec: BoundedVec<Field, 3> = BoundedVec::new();\n /// vec.extend_from_array([2, 4]);\n ///\n /// assert(vec.len == 2);\n /// assert(vec.get(0) == 2);\n /// assert(vec.get(1) == 4);\n /// ```\n pub fn extend_from_array<let Len: u32>(&mut self, array: [T; Len]) {\n let new_len = self.len + array.len();\n assert(new_len <= MaxLen, \"extend_from_array out of bounds\");\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = new_len;\n }\n\n /// Pushes each element from the given slice to this vector.\n ///\n /// Panics if pushing each element would cause the length of this vector\n /// to exceed the maximum length.\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut vec: BoundedVec<Field, 3> = BoundedVec::new();\n /// vec.extend_from_slice(&[2, 4]);\n ///\n /// assert(vec.len == 2);\n /// assert(vec.get(0) == 2);\n /// assert(vec.get(1) == 4);\n /// ```\n pub fn extend_from_slice(&mut self, slice: [T]) {\n let new_len = self.len + slice.len();\n assert(new_len <= MaxLen, \"extend_from_slice out of bounds\");\n for i in 0..slice.len() {\n self.storage[self.len + i] = slice[i];\n }\n self.len = new_len;\n }\n\n /// Pushes each element from the other vector to this vector. The length of\n /// the other vector is left unchanged.\n ///\n /// Panics if pushing each element would cause the length of this vector\n /// to exceed the maximum length.\n ///\n /// ```noir\n /// let mut v1: BoundedVec<Field, 5> = BoundedVec::new();\n /// let mut v2: BoundedVec<Field, 7> = BoundedVec::new();\n ///\n /// v2.extend_from_array([1, 2, 3]);\n /// v1.extend_from_bounded_vec(v2);\n ///\n /// assert(v1.storage() == [1, 2, 3, 0, 0]);\n /// assert(v2.storage() == [1, 2, 3, 0, 0, 0, 0]);\n /// ```\n pub fn extend_from_bounded_vec<let Len: u32>(&mut self, vec: BoundedVec<T, Len>) {\n let append_len = vec.len();\n let new_len = self.len + append_len;\n assert(new_len <= MaxLen, \"extend_from_bounded_vec out of bounds\");\n\n if is_unconstrained() {\n for i in 0..append_len {\n self.storage[self.len + i] = vec.get_unchecked(i);\n }\n } else {\n let mut exceeded_len = false;\n for i in 0..Len {\n exceeded_len |= i == append_len;\n if !exceeded_len {\n self.storage[self.len + i] = vec.get_unchecked(i);\n }\n }\n }\n self.len = new_len;\n }\n\n /// Creates a new vector, populating it with values derived from an array input.\n /// The maximum length of the vector is determined based on the type signature.\n ///\n /// Example:\n ///\n /// ```noir\n /// let bounded_vec: BoundedVec<Field, 10> = BoundedVec::from_array([1, 2, 3])\n /// ```\n pub fn from_array<let Len: u32>(array: [T; Len]) -> Self {\n static_assert(Len <= MaxLen, \"from array out of bounds\");\n let mut vec: BoundedVec<T, MaxLen> = BoundedVec::new();\n vec.extend_from_array(array);\n vec\n }\n\n /// Pops the element at the end of the vector. This will decrease the length\n /// of the vector by one.\n ///\n /// Panics if the vector is empty.\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut v: BoundedVec<Field, 2> = BoundedVec::new();\n /// v.push(1);\n /// v.push(2);\n ///\n /// let two = v.pop();\n /// let one = v.pop();\n ///\n /// assert(two == 2);\n /// assert(one == 1);\n ///\n /// // error: cannot pop from an empty vector\n /// let _ = v.pop();\n /// ```\n pub fn pop(&mut self) -> T {\n assert(self.len > 0);\n self.len -= 1;\n\n let elem = self.storage[self.len];\n self.storage[self.len] = crate::mem::zeroed();\n elem\n }\n\n /// Returns true if the given predicate returns true for any element\n /// in this vector.\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut v: BoundedVec<u32, 3> = BoundedVec::new();\n /// v.extend_from_array([2, 4, 6]);\n ///\n /// let all_even = !v.any(|elem: u32| elem % 2 != 0);\n /// assert(all_even);\n /// ```\n pub fn any<Env>(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n if is_unconstrained() {\n for i in 0..self.len {\n ret |= predicate(self.storage[i]);\n }\n } else {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if !exceeded_len {\n ret |= predicate(self.storage[i]);\n }\n }\n }\n ret\n }\n\n /// Creates a new vector of equal size by calling a closure on each element in this vector.\n ///\n /// Example:\n ///\n /// ```noir\n /// let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n /// let result = vec.map(|value| value * 2);\n ///\n /// let expected = BoundedVec::from_array([2, 4, 6, 8]);\n /// assert_eq(result, expected);\n /// ```\n pub fn map<U, Env>(self, f: fn[Env](T) -> U) -> BoundedVec<U, MaxLen> {\n let mut ret = BoundedVec::new();\n ret.len = self.len();\n\n if is_unconstrained() {\n for i in 0..self.len() {\n ret.storage[i] = f(self.get_unchecked(i));\n }\n } else {\n for i in 0..MaxLen {\n if i < self.len() {\n ret.storage[i] = f(self.get_unchecked(i));\n }\n }\n }\n\n ret\n }\n\n /// Creates a new vector of equal size by calling a closure on each element\n /// in this vector, along with its index.\n ///\n /// Example:\n ///\n /// ```noir\n /// let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n /// let result = vec.mapi(|i, value| i + value * 2);\n ///\n /// let expected = BoundedVec::from_array([2, 5, 8, 11]);\n /// assert_eq(result, expected);\n /// ```\n pub fn mapi<U, Env>(self, f: fn[Env](u32, T) -> U) -> BoundedVec<U, MaxLen> {\n let mut ret = BoundedVec::new();\n ret.len = self.len();\n\n if is_unconstrained() {\n for i in 0..self.len() {\n ret.storage[i] = f(i, self.get_unchecked(i));\n }\n } else {\n for i in 0..MaxLen {\n if i < self.len() {\n ret.storage[i] = f(i, self.get_unchecked(i));\n }\n }\n }\n\n ret\n }\n\n /// Calls a closure on each element in this vector.\n ///\n /// Example:\n ///\n /// ```noir\n /// let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n /// let mut result = BoundedVec::<u32, 4>::new();\n /// vec.for_each(|value| result.push(value * 2));\n ///\n /// let expected = BoundedVec::from_array([2, 4, 6, 8]);\n /// assert_eq(result, expected);\n /// ```\n pub fn for_each<Env>(self, f: fn[Env](T) -> ()) {\n if is_unconstrained() {\n for i in 0..self.len() {\n f(self.get_unchecked(i));\n }\n } else {\n for i in 0..MaxLen {\n if i < self.len() {\n f(self.get_unchecked(i));\n }\n }\n }\n }\n\n /// Calls a closure on each element in this vector, along with its index.\n ///\n /// Example:\n ///\n /// ```noir\n /// let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n /// let mut result = BoundedVec::<u32, 4>::new();\n /// vec.for_eachi(|i, value| result.push(i + value * 2));\n ///\n /// let expected = BoundedVec::from_array([2, 5, 8, 11]);\n /// assert_eq(result, expected);\n /// ```\n pub fn for_eachi<Env>(self, f: fn[Env](u32, T) -> ()) {\n if is_unconstrained() {\n for i in 0..self.len() {\n f(i, self.get_unchecked(i));\n }\n } else {\n for i in 0..MaxLen {\n if i < self.len() {\n f(i, self.get_unchecked(i));\n }\n }\n }\n }\n\n /// Creates a new BoundedVec from the given array and length.\n /// The given length must be less than or equal to the length of the array.\n ///\n /// This function will zero out any elements at or past index `len` of `array`.\n /// This incurs an extra runtime cost of O(MaxLen). If you are sure your array is\n /// zeroed after that index, you can use `from_parts_unchecked` to remove the extra loop.\n ///\n /// Example:\n ///\n /// ```noir\n /// let vec: BoundedVec<u32, 4> = BoundedVec::from_parts([1, 2, 3, 0], 3);\n /// assert_eq(vec.len(), 3);\n /// ```\n pub fn from_parts(mut array: [T; MaxLen], len: u32) -> Self {\n assert(len <= MaxLen);\n let zeroed = crate::mem::zeroed();\n\n if is_unconstrained() {\n for i in len..MaxLen {\n array[i] = zeroed;\n }\n } else {\n for i in 0..MaxLen {\n if i >= len {\n array[i] = zeroed;\n }\n }\n }\n\n BoundedVec { storage: array, len }\n }\n\n /// Creates a new BoundedVec from the given array and length.\n /// The given length must be less than or equal to the length of the array.\n ///\n /// This function is unsafe because it expects all elements past the `len` index\n /// of `array` to be zeroed, but does not check for this internally. Use `from_parts`\n /// for a safe version of this function which does zero out any indices past the\n /// given length. Invalidating this assumption can notably cause `BoundedVec::eq`\n /// to give incorrect results since it will check even elements past `len`.\n ///\n /// Example:\n ///\n /// ```noir\n /// let vec: BoundedVec<u32, 4> = BoundedVec::from_parts_unchecked([1, 2, 3, 0], 3);\n /// assert_eq(vec.len(), 3);\n ///\n /// // invalid use!\n /// let vec1: BoundedVec<u32, 4> = BoundedVec::from_parts_unchecked([1, 2, 3, 1], 3);\n /// let vec2: BoundedVec<u32, 4> = BoundedVec::from_parts_unchecked([1, 2, 3, 2], 3);\n ///\n /// // both vecs have length 3 so we'd expect them to be equal, but this\n /// // fails because elements past the length are still checked in eq\n /// assert_eq(vec1, vec2); // fails\n /// ```\n pub fn from_parts_unchecked(array: [T; MaxLen], len: u32) -> Self {\n assert(len <= MaxLen);\n BoundedVec { storage: array, len }\n }\n}\n\nimpl<T, let MaxLen: u32> Eq for BoundedVec<T, MaxLen>\nwhere\n T: Eq,\n{\n fn eq(self, other: BoundedVec<T, MaxLen>) -> bool {\n // TODO: https://github.com/noir-lang/noir/issues/4837\n //\n // We make the assumption that the user has used the proper interface for working with `BoundedVec`s\n // rather than directly manipulating the internal fields as this can result in an inconsistent internal state.\n if self.len == other.len {\n self.storage == other.storage\n } else {\n false\n }\n }\n}\n\nimpl<T, let MaxLen: u32, let Len: u32> From<[T; Len]> for BoundedVec<T, MaxLen> {\n fn from(array: [T; Len]) -> BoundedVec<T, MaxLen> {\n BoundedVec::from_array(array)\n }\n}\n\nmod bounded_vec_tests {\n\n mod get {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test(should_fail_with = \"Attempted to read past end of BoundedVec\")]\n fn panics_when_reading_elements_past_end_of_vec() {\n let vec: BoundedVec<Field, 5> = BoundedVec::new();\n\n crate::println(vec.get(0));\n }\n }\n\n mod set {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test]\n fn set_updates_values_properly() {\n let mut vec = BoundedVec::from_array([0, 0, 0, 0, 0]);\n\n vec.set(0, 42);\n assert_eq(vec.storage, [42, 0, 0, 0, 0]);\n\n vec.set(1, 43);\n assert_eq(vec.storage, [42, 43, 0, 0, 0]);\n\n vec.set(2, 44);\n assert_eq(vec.storage, [42, 43, 44, 0, 0]);\n\n vec.set(1, 10);\n assert_eq(vec.storage, [42, 10, 44, 0, 0]);\n\n vec.set(0, 0);\n assert_eq(vec.storage, [0, 10, 44, 0, 0]);\n }\n\n #[test(should_fail_with = \"Attempted to write past end of BoundedVec\")]\n fn panics_when_writing_elements_past_end_of_vec() {\n let mut vec: BoundedVec<Field, 5> = BoundedVec::new();\n vec.set(0, 42);\n\n // Need to use println to avoid DIE removing the write operation.\n crate::println(vec.get(0));\n }\n }\n\n mod map {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test]\n fn applies_function_correctly() {\n // docs:start:bounded-vec-map-example\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = vec.map(|value| value * 2);\n // docs:end:bounded-vec-map-example\n let expected = BoundedVec::from_array([2, 4, 6, 8]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn applies_function_that_changes_return_type() {\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = vec.map(|value| (value * 2) as Field);\n let expected: BoundedVec<Field, 4> = BoundedVec::from_array([2, 4, 6, 8]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn does_not_apply_function_past_len() {\n let vec: BoundedVec<u32, 3> = BoundedVec::from_array([0, 1]);\n let result = vec.map(|value| if value == 0 { 5 } else { value });\n let expected = BoundedVec::from_array([5, 1]);\n\n assert_eq(result, expected);\n assert_eq(result.get_unchecked(2), 0);\n }\n }\n\n mod mapi {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test]\n fn applies_function_correctly() {\n // docs:start:bounded-vec-mapi-example\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = vec.mapi(|i, value| i + value * 2);\n // docs:end:bounded-vec-mapi-example\n let expected = BoundedVec::from_array([2, 5, 8, 11]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn applies_function_that_changes_return_type() {\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = vec.mapi(|i, value| (i + value * 2) as Field);\n let expected: BoundedVec<Field, 4> = BoundedVec::from_array([2, 5, 8, 11]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn does_not_apply_function_past_len() {\n let vec: BoundedVec<u32, 3> = BoundedVec::from_array([0, 1]);\n let result = vec.mapi(|_, value| if value == 0 { 5 } else { value });\n let expected = BoundedVec::from_array([5, 1]);\n\n assert_eq(result, expected);\n assert_eq(result.get_unchecked(2), 0);\n }\n }\n\n mod for_each {\n use crate::collections::bounded_vec::BoundedVec;\n\n // map in terms of for_each\n fn for_each_map<T, U, Env, let MaxLen: u32>(\n input: BoundedVec<T, MaxLen>,\n f: fn[Env](T) -> U,\n ) -> BoundedVec<U, MaxLen> {\n let mut output = BoundedVec::<U, MaxLen>::new();\n let output_ref = &mut output;\n input.for_each(|x| output_ref.push(f(x)));\n output\n }\n\n #[test]\n fn smoke_test() {\n let mut acc = 0;\n let acc_ref = &mut acc;\n // docs:start:bounded-vec-for-each-example\n let vec: BoundedVec<u32, 3> = BoundedVec::from_array([1, 2, 3]);\n vec.for_each(|value| { *acc_ref += value; });\n // docs:end:bounded-vec-for-each-example\n assert_eq(acc, 6);\n }\n\n #[test]\n fn applies_function_correctly() {\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = for_each_map(vec, |value| value * 2);\n let expected = BoundedVec::from_array([2, 4, 6, 8]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn applies_function_that_changes_return_type() {\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = for_each_map(vec, |value| (value * 2) as Field);\n let expected: BoundedVec<Field, 4> = BoundedVec::from_array([2, 4, 6, 8]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn does_not_apply_function_past_len() {\n let vec: BoundedVec<u32, 3> = BoundedVec::from_array([0, 1]);\n let result = for_each_map(vec, |value| if value == 0 { 5 } else { value });\n let expected = BoundedVec::from_array([5, 1]);\n\n assert_eq(result, expected);\n assert_eq(result.get_unchecked(2), 0);\n }\n }\n\n mod for_eachi {\n use crate::collections::bounded_vec::BoundedVec;\n\n // mapi in terms of for_eachi\n fn for_eachi_mapi<T, U, Env, let MaxLen: u32>(\n input: BoundedVec<T, MaxLen>,\n f: fn[Env](u32, T) -> U,\n ) -> BoundedVec<U, MaxLen> {\n let mut output = BoundedVec::<U, MaxLen>::new();\n let output_ref = &mut output;\n input.for_eachi(|i, x| output_ref.push(f(i, x)));\n output\n }\n\n #[test]\n fn smoke_test() {\n let mut acc = 0;\n let acc_ref = &mut acc;\n // docs:start:bounded-vec-for-eachi-example\n let vec: BoundedVec<u32, 3> = BoundedVec::from_array([1, 2, 3]);\n vec.for_eachi(|i, value| { *acc_ref += i * value; });\n // docs:end:bounded-vec-for-eachi-example\n\n // 0 * 1 + 1 * 2 + 2 * 3\n assert_eq(acc, 8);\n }\n\n #[test]\n fn applies_function_correctly() {\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = for_eachi_mapi(vec, |i, value| i + value * 2);\n let expected = BoundedVec::from_array([2, 5, 8, 11]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn applies_function_that_changes_return_type() {\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = for_eachi_mapi(vec, |i, value| (i + value * 2) as Field);\n let expected: BoundedVec<Field, 4> = BoundedVec::from_array([2, 5, 8, 11]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn does_not_apply_function_past_len() {\n let vec: BoundedVec<u32, 3> = BoundedVec::from_array([0, 1]);\n let result = for_eachi_mapi(vec, |_, value| if value == 0 { 5 } else { value });\n let expected = BoundedVec::from_array([5, 1]);\n\n assert_eq(result, expected);\n assert_eq(result.get_unchecked(2), 0);\n }\n }\n\n mod from_array {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test]\n fn empty() {\n let empty_array: [Field; 0] = [];\n let bounded_vec = BoundedVec::from_array([]);\n\n assert_eq(bounded_vec.max_len(), 0);\n assert_eq(bounded_vec.len(), 0);\n assert_eq(bounded_vec.storage(), empty_array);\n }\n\n #[test]\n fn equal_len() {\n let array = [1, 2, 3];\n let bounded_vec = BoundedVec::from_array(array);\n\n assert_eq(bounded_vec.max_len(), 3);\n assert_eq(bounded_vec.len(), 3);\n assert_eq(bounded_vec.storage(), array);\n }\n\n #[test]\n fn max_len_greater_then_array_len() {\n let array = [1, 2, 3];\n let bounded_vec: BoundedVec<Field, 10> = BoundedVec::from_array(array);\n\n assert_eq(bounded_vec.max_len(), 10);\n assert_eq(bounded_vec.len(), 3);\n assert_eq(bounded_vec.get(0), 1);\n assert_eq(bounded_vec.get(1), 2);\n assert_eq(bounded_vec.get(2), 3);\n }\n\n #[test(should_fail_with = \"from array out of bounds\")]\n fn max_len_lower_then_array_len() {\n let _: BoundedVec<Field, 2> = BoundedVec::from_array([0; 3]);\n }\n }\n\n mod trait_from {\n use crate::collections::bounded_vec::BoundedVec;\n use crate::convert::From;\n\n #[test]\n fn simple() {\n let array = [1, 2];\n let bounded_vec: BoundedVec<Field, 10> = BoundedVec::from(array);\n\n assert_eq(bounded_vec.max_len(), 10);\n assert_eq(bounded_vec.len(), 2);\n assert_eq(bounded_vec.get(0), 1);\n assert_eq(bounded_vec.get(1), 2);\n }\n }\n\n mod trait_eq {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test]\n fn empty_equality() {\n let mut bounded_vec1: BoundedVec<Field, 3> = BoundedVec::new();\n let mut bounded_vec2: BoundedVec<Field, 3> = BoundedVec::new();\n\n assert_eq(bounded_vec1, bounded_vec2);\n }\n\n #[test]\n fn inequality() {\n let mut bounded_vec1: BoundedVec<Field, 3> = BoundedVec::new();\n let mut bounded_vec2: BoundedVec<Field, 3> = BoundedVec::new();\n bounded_vec1.push(1);\n bounded_vec2.push(2);\n\n assert(bounded_vec1 != bounded_vec2);\n }\n }\n\n mod from_parts {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test]\n fn from_parts() {\n // docs:start:from-parts\n let vec: BoundedVec<u32, 4> = BoundedVec::from_parts([1, 2, 3, 0], 3);\n assert_eq(vec.len(), 3);\n\n // Any elements past the given length are zeroed out, so these\n // two BoundedVecs will be completely equal\n let vec1: BoundedVec<u32, 4> = BoundedVec::from_parts([1, 2, 3, 1], 3);\n let vec2: BoundedVec<u32, 4> = BoundedVec::from_parts([1, 2, 3, 2], 3);\n assert_eq(vec1, vec2);\n // docs:end:from-parts\n }\n\n #[test]\n fn from_parts_unchecked() {\n // docs:start:from-parts-unchecked\n let vec: BoundedVec<u32, 4> = BoundedVec::from_parts_unchecked([1, 2, 3, 0], 3);\n assert_eq(vec.len(), 3);\n\n // invalid use!\n let vec1: BoundedVec<u32, 4> = BoundedVec::from_parts_unchecked([1, 2, 3, 1], 3);\n let vec2: BoundedVec<u32, 4> = BoundedVec::from_parts_unchecked([1, 2, 3, 2], 3);\n\n // both vecs have length 3 so we'd expect them to be equal, but this\n // fails because elements past the length are still checked in eq\n assert(vec1 != vec2);\n // docs:end:from-parts-unchecked\n }\n }\n}\n","path":"std/collections/bounded_vec.nr"},"22":{"source":"pub mod hash;\npub mod aes128;\npub mod array;\npub mod slice;\npub mod ecdsa_secp256k1;\npub mod ecdsa_secp256r1;\npub mod embedded_curve_ops;\npub mod field;\npub mod collections;\npub mod compat;\npub mod convert;\npub mod option;\npub mod string;\npub mod test;\npub mod cmp;\npub mod ops;\npub mod default;\npub mod prelude;\npub mod runtime;\npub mod meta;\npub mod append;\npub mod mem;\npub mod panic;\npub mod hint;\n\nuse convert::AsPrimitive;\n\n// Oracle calls are required to be wrapped in an unconstrained function\n// Thus, the only argument to the `println` oracle is expected to always be an ident\n#[oracle(print)]\nunconstrained fn print_oracle<T>(with_newline: bool, input: T) {}\n\nunconstrained fn print_unconstrained<T>(with_newline: bool, input: T) {\n print_oracle(with_newline, input);\n}\n\npub fn println<T>(input: T) {\n // Safety: a print statement cannot be constrained\n unsafe {\n print_unconstrained(true, input);\n }\n}\n\npub fn print<T>(input: T) {\n // Safety: a print statement cannot be constrained\n unsafe {\n print_unconstrained(false, input);\n }\n}\n\npub fn verify_proof<let N: u32, let M: u32, let K: u32>(\n verification_key: [Field; N],\n proof: [Field; M],\n public_inputs: [Field; K],\n key_hash: Field,\n) {\n verify_proof_internal(verification_key, proof, public_inputs, key_hash, 0);\n}\n\npub fn verify_proof_with_type<let N: u32, let M: u32, let K: u32>(\n verification_key: [Field; N],\n proof: [Field; M],\n public_inputs: [Field; K],\n key_hash: Field,\n proof_type: u32,\n) {\n if !crate::runtime::is_unconstrained() {\n crate::assert_constant(proof_type);\n }\n verify_proof_internal(verification_key, proof, public_inputs, key_hash, proof_type);\n}\n\n#[foreign(recursive_aggregation)]\nfn verify_proof_internal<let N: u32, let M: u32, let K: u32>(\n verification_key: [Field; N],\n proof: [Field; M],\n public_inputs: [Field; K],\n key_hash: Field,\n proof_type: u32,\n) {}\n\n// Asserts that the given value is known at compile-time.\n// Useful for debugging for-loop bounds.\n#[builtin(assert_constant)]\npub fn assert_constant<T>(x: T) {}\n\n// Asserts that the given value is both true and known at compile-time\n#[builtin(static_assert)]\npub fn static_assert<let N: u32>(predicate: bool, message: str<N>) {}\n\n#[deprecated(\"wrapping operations should be done with the Wrapping traits. E.g: x.wrapping_add(y)\")]\npub fn wrapping_add<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#[deprecated(\"wrapping operations should be done with the Wrapping traits. E.g: x.wrapping_sub(y)\")]\npub fn wrapping_sub<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow\n AsPrimitive::as_(x.as_() + 340282366920938463463374607431768211456 - y.as_())\n}\n#[deprecated(\"wrapping operations should be done with the Wrapping traits. E.g: x.wrapping_mul(y)\")]\npub fn wrapping_mul<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\n#[builtin(as_witness)]\npub fn as_witness(x: Field) {}\n\nmod tests {\n use super::ops::arith::WrappingMul;\n\n #[test(should_fail_with = \"custom message\")]\n fn test_static_assert_custom_message() {\n super::static_assert(1 == 2, \"custom message\");\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 // 1*0==0\n assert_eq(zero, zero.wrapping_mul(one));\n\n // 0*1==0\n assert_eq(zero, one.wrapping_mul(zero));\n\n // 1*1==1\n assert_eq(one, one.wrapping_mul(one));\n\n // 0 * ( 1 << 64 ) == 0\n assert_eq(zero, zero.wrapping_mul(two_pow_64));\n\n // ( 1 << 64 ) * 0 == 0\n assert_eq(zero, two_pow_64.wrapping_mul(zero));\n\n // 1 * ( 1 << 64 ) == 1 << 64\n assert_eq(two_pow_64, two_pow_64.wrapping_mul(one));\n\n // ( 1 << 64 ) * 1 == 1 << 64\n assert_eq(two_pow_64, one.wrapping_mul(two_pow_64));\n\n // ( 1 << 64 ) * ( 1 << 64 ) == 1 << 64\n assert_eq(zero, two_pow_64.wrapping_mul(two_pow_64));\n // -1 * -1 == 1\n assert_eq(one, u128_max.wrapping_mul(u128_max));\n }\n}\n","path":"std/lib.nr"},"50":{"source":"use dep::mock_types::{\n AppPublicInputs, CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS, PrivateKernelPublicInputs,\n PrivateKernelPublicInputsBuilder, PROOF_TYPE_OINK, TxRequest,\n};\n\nfn main(\n tx: TxRequest,\n app_inputs: call_data(1) AppPublicInputs,\n app_vk: [Field; CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS],\n) -> return_data PrivateKernelPublicInputs {\n std::verify_proof_with_type(app_vk, [], [], 0, PROOF_TYPE_OINK);\n\n let mut private_kernel_inputs = PrivateKernelPublicInputsBuilder::from_tx(tx);\n private_kernel_inputs.ingest_app_inputs(app_inputs);\n private_kernel_inputs.finish()\n}\n","path":"/home/aztec-dev/aztec-packages/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-init/src/main.nr"},"51":{"source":"pub global MAX_COMMITMENTS_PER_CALL: u32 = 2;\npub global MAX_COMMITMENTS_PER_TX: u32 = 4;\npub global MAX_COMMITMENT_READ_REQUESTS_PER_CALL: u32 = 2;\npub global MAX_COMMITMENT_READ_REQUESTS_PER_TX: u32 = 4;\n\npub use protocol_types::{\n constants::{\n CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS, NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,\n PROOF_TYPE_OINK, PROOF_TYPE_PG, PROOF_TYPE_ROLLUP_HONK, PROOF_TYPE_ROOT_ROLLUP_HONK,\n ROLLUP_HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS, TUBE_PROOF_LENGTH,\n },\n proof::verification_key::{RollupHonkVerificationKey, VerificationKey},\n traits::Serialize,\n};\n\npub struct TxRequest {\n pub number_of_calls: u32,\n}\n\npub struct AppPublicInputs {\n pub commitments: [Field; MAX_COMMITMENTS_PER_CALL],\n pub read_requests: [Field; MAX_COMMITMENT_READ_REQUESTS_PER_CALL],\n}\n\nimpl Default for AppPublicInputs {\n fn default() -> Self {\n Self {\n commitments: [0; MAX_COMMITMENTS_PER_CALL],\n read_requests: [0; MAX_COMMITMENT_READ_REQUESTS_PER_CALL],\n }\n }\n}\n\npub struct PrivateKernelPublicInputs {\n pub remaining_calls: u32,\n pub commitments: [Field; MAX_COMMITMENTS_PER_TX],\n pub read_requests: [Field; MAX_COMMITMENT_READ_REQUESTS_PER_TX],\n}\n\nimpl Default for PrivateKernelPublicInputs {\n fn default() -> Self {\n Self {\n remaining_calls: 0,\n commitments: [0; MAX_COMMITMENTS_PER_TX],\n read_requests: [0; MAX_COMMITMENT_READ_REQUESTS_PER_TX],\n }\n }\n}\n\npub struct PrivateKernelPublicInputsBuilder {\n pub remaining_calls: u32,\n pub commitments: BoundedVec<Field, MAX_COMMITMENTS_PER_TX>,\n pub read_requests: BoundedVec<Field, MAX_COMMITMENT_READ_REQUESTS_PER_TX>,\n}\n\nimpl PrivateKernelPublicInputsBuilder {\n pub fn from_tx(tx: TxRequest) -> Self {\n Self {\n remaining_calls: tx.number_of_calls,\n commitments: BoundedVec::new(),\n read_requests: BoundedVec::new(),\n }\n }\n\n pub fn from_previous_kernel(prev_kernel_public_inputs: PrivateKernelPublicInputs) -> Self {\n let mut builder = PrivateKernelPublicInputsBuilder {\n remaining_calls: prev_kernel_public_inputs.remaining_calls,\n commitments: BoundedVec::new(),\n read_requests: BoundedVec::new(),\n };\n for i in 0..MAX_COMMITMENTS_PER_TX {\n if prev_kernel_public_inputs.commitments[i] != 0 {\n builder.commitments.push(prev_kernel_public_inputs.commitments[i]);\n }\n }\n for i in 0..MAX_COMMITMENT_READ_REQUESTS_PER_TX {\n if prev_kernel_public_inputs.read_requests[i] != 0 {\n builder.read_requests.push(prev_kernel_public_inputs.read_requests[i]);\n }\n }\n builder\n }\n\n pub fn ingest_app_inputs(&mut self, app_inputs: AppPublicInputs) {\n for i in 0..MAX_COMMITMENTS_PER_CALL {\n if app_inputs.commitments[i] != 0 {\n self.commitments.push(app_inputs.commitments[i]);\n }\n }\n\n for i in 0..MAX_COMMITMENT_READ_REQUESTS_PER_CALL {\n if app_inputs.read_requests[i] != 0 {\n self.read_requests.push(app_inputs.read_requests[i]);\n }\n }\n\n self.remaining_calls -= 1;\n }\n\n pub fn finish(self) -> PrivateKernelPublicInputs {\n PrivateKernelPublicInputs {\n remaining_calls: self.remaining_calls,\n commitments: self.commitments.storage(),\n read_requests: self.read_requests.storage(),\n }\n }\n}\n\npub struct KernelPublicInputs {\n pub commitments: [Field; MAX_COMMITMENTS_PER_TX],\n}\n\nimpl Default for KernelPublicInputs {\n fn default() -> Self {\n Self { commitments: [0; MAX_COMMITMENTS_PER_TX] }\n }\n}\n\nimpl Serialize<MAX_COMMITMENTS_PER_TX> for KernelPublicInputs {\n fn serialize(self) -> [Field; MAX_COMMITMENTS_PER_TX] {\n self.commitments\n }\n}\n\npub struct RollupPublicInputs {\n accumulated: u32,\n}\n\nimpl RollupPublicInputs {\n pub fn new(accumulated: u32) -> Self {\n Self { accumulated }\n }\n\n pub fn merge(self, other: Self) -> Self {\n Self { accumulated: self.accumulated + other.accumulated }\n }\n}\n\nimpl Serialize<1> for RollupPublicInputs {\n fn serialize(self) -> [Field; 1] {\n [self.accumulated as Field]\n }\n}\n\npub struct PreviousRollupData {\n base_or_merge_public_inputs: RollupPublicInputs,\n proof: [Field; NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH],\n vk: RollupHonkVerificationKey,\n}\n\nimpl PreviousRollupData {\n pub fn verify(self, is_root: bool) {\n let inputs = self.base_or_merge_public_inputs.serialize();\n\n std::verify_proof_with_type(\n self.vk.key,\n self.proof,\n inputs,\n self.vk.hash,\n if is_root {\n PROOF_TYPE_ROOT_ROLLUP_HONK\n } else {\n PROOF_TYPE_ROLLUP_HONK\n },\n );\n }\n\n pub fn public_inputs(self) -> RollupPublicInputs {\n self.base_or_merge_public_inputs\n }\n}\n\npub struct TubeData {\n pub public_inputs: KernelPublicInputs,\n pub proof: [Field; TUBE_PROOF_LENGTH],\n pub vk_data: VerificationKey<ROLLUP_HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS>,\n}\n\nimpl TubeData {\n pub fn verify(self) {\n let inputs = KernelPublicInputs::serialize(self.public_inputs);\n std::verify_proof_with_type(\n self.vk_data.key,\n self.proof,\n inputs,\n self.vk_data.hash,\n PROOF_TYPE_ROLLUP_HONK,\n );\n }\n}\n","path":"/home/aztec-dev/aztec-packages/noir-projects/mock-protocol-circuits/crates/mock-types/src/lib.nr"}},"names":["main"],"brillig_names":["directive_invert","directive_integer_quotient"]}
|
|
1
|
+
{"noir_version":"1.0.0-beta.5+0000000000000000000000000000000000000000","hash":"17304896886774099022","abi":{"parameters":[{"name":"tx","type":{"kind":"struct","path":"mock_types::TxRequest","fields":[{"name":"number_of_calls","type":{"kind":"integer","sign":"unsigned","width":32}}]},"visibility":"private"},{"name":"app_inputs","type":{"kind":"struct","path":"mock_types::AppPublicInputs","fields":[{"name":"commitments","type":{"kind":"array","length":2,"type":{"kind":"field"}}},{"name":"read_requests","type":{"kind":"array","length":2,"type":{"kind":"field"}}}]},"visibility":"databus"},{"name":"app_vk","type":{"kind":"array","length":127,"type":{"kind":"field"}},"visibility":"private"}],"return_type":{"abi_type":{"kind":"struct","path":"mock_types::PrivateKernelPublicInputs","fields":[{"name":"remaining_calls","type":{"kind":"integer","sign":"unsigned","width":32}},{"name":"commitments","type":{"kind":"array","length":4,"type":{"kind":"field"}}},{"name":"read_requests","type":{"kind":"array","length":4,"type":{"kind":"field"}}}]},"visibility":"databus"},"error_types":{"2920182694213909827":{"error_kind":"string","string":"attempt to subtract with overflow"},"5727012404371710682":{"error_kind":"string","string":"push out of bounds"},"14225679739041873922":{"error_kind":"string","string":"Index out of bounds"}}},"bytecode":"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","debug_symbols":"pZXdisIwEEbfJde9yEz+fZVlkap1KZQq3XZhEd99p5lpXS8iojdzbOMcPjKkuahDs5u+tm1/PH2rzcdF7Ya269qvbXfa12N76unt5Vqp5XE7Dk1Dr9S/deo610PTj2rTT11XqZ+6m/Kfvs91nznWA63qSjX9gUjCY9s1869rdevW5VYTgjRbe2t39/1Q7gdvnAggQFwNiM8mcGaJ73wqJTDlfkwGRIDJw80AzxqM1igGozG8YMAU9WrQxQy+bPDJWjH45G4Z/NOC6FZBDPCCIGm3JsBSgkfbCOskDXh8ZRC4RjBoXjJAhNWgbckA+O4kHhqeGsXjDO/OAn1c9yGZ0j48OpZx+TB4cHfH8pOe6n073H3KFNApqBTmauhrUimbq8vV5xpyjbkmtaGEoBnAQIZhWAYZEsEzAiMyUgZqBlkoNCLDMCzDMTwjMMgCtAeYmEYLQYhCIyQXUHbjhF4YhFGYmHb20SAtCFFohFbohLOPpmqDMAoT080+OsJu9vnrPLyhrXddI5fJcer3/+6W8fe8rCy3z3k47ZvDNDTz8PIajfMP","file_map":{"6":{"source":"use crate::{cmp::Eq, convert::From, runtime::is_unconstrained, static_assert};\n\n/// A `BoundedVec<T, MaxLen>` is a growable storage similar to a `Vec<T>` except that it\n/// is bounded with a maximum possible length. Unlike `Vec`, `BoundedVec` is not implemented\n/// via slices and thus is not subject to the same restrictions slices are (notably, nested\n/// slices - and thus nested vectors as well - are disallowed).\n///\n/// Since a BoundedVec is backed by a normal array under the hood, growing the BoundedVec by\n/// pushing an additional element is also more efficient - the length only needs to be increased\n/// by one.\n///\n/// For these reasons `BoundedVec<T, N>` should generally be preferred over `Vec<T>` when there\n/// is a reasonable maximum bound that can be placed on the vector.\n///\n/// Example:\n///\n/// ```noir\n/// let mut vector: BoundedVec<Field, 10> = BoundedVec::new();\n/// for i in 0..5 {\n/// vector.push(i);\n/// }\n/// assert(vector.len() == 5);\n/// assert(vector.max_len() == 10);\n/// ```\npub struct BoundedVec<T, let MaxLen: u32> {\n storage: [T; MaxLen],\n len: u32,\n}\n\nimpl<T, let MaxLen: u32> BoundedVec<T, MaxLen> {\n /// Creates a new, empty vector of length zero.\n ///\n /// Since this container is backed by an array internally, it still needs an initial value\n /// to give each element. To resolve this, each element is zeroed internally. This value\n /// is guaranteed to be inaccessible unless `get_unchecked` is used.\n ///\n /// Example:\n ///\n /// ```noir\n /// let empty_vector: BoundedVec<Field, 10> = BoundedVec::new();\n /// assert(empty_vector.len() == 0);\n /// ```\n ///\n /// Note that whenever calling `new` the maximum length of the vector should always be specified\n /// via a type signature:\n ///\n /// ```noir\n /// fn good() -> BoundedVec<Field, 10> {\n /// // Ok! MaxLen is specified with a type annotation\n /// let v1: BoundedVec<Field, 3> = BoundedVec::new();\n /// let v2 = BoundedVec::new();\n ///\n /// // Ok! MaxLen is known from the type of `good`'s return value\n /// v2\n /// }\n ///\n /// fn bad() {\n /// // Error: Type annotation needed\n /// // The compiler can't infer `MaxLen` from the following code:\n /// let mut v3 = BoundedVec::new();\n /// v3.push(5);\n /// }\n /// ```\n ///\n /// This defaulting of `MaxLen` (and numeric generics in general) to zero may change in future noir versions\n /// but for now make sure to use type annotations when using bounded vectors. Otherwise, you will receive a\n /// constraint failure at runtime when the vec is pushed to.\n pub fn new() -> Self {\n let zeroed = crate::mem::zeroed();\n BoundedVec { storage: [zeroed; MaxLen], len: 0 }\n }\n\n /// Retrieves an element from the vector at the given index, starting from zero.\n ///\n /// If the given index is equal to or greater than the length of the vector, this\n /// will issue a constraint failure.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn foo<let N: u32>(v: BoundedVec<u32, N>) {\n /// let first = v.get(0);\n /// let last = v.get(v.len() - 1);\n /// assert(first != last);\n /// }\n /// ```\n pub fn get(self, index: u32) -> T {\n assert(index < self.len, \"Attempted to read past end of BoundedVec\");\n self.get_unchecked(index)\n }\n\n /// Retrieves an element from the vector at the given index, starting from zero, without\n /// performing a bounds check.\n ///\n /// Since this function does not perform a bounds check on length before accessing the element,\n /// it is unsafe! Use at your own risk!\n ///\n /// Example:\n ///\n /// ```noir\n /// fn sum_of_first_three<let N: u32>(v: BoundedVec<u32, N>) -> u32 {\n /// // Always ensure the length is larger than the largest\n /// // index passed to get_unchecked\n /// assert(v.len() > 2);\n /// let first = v.get_unchecked(0);\n /// let second = v.get_unchecked(1);\n /// let third = v.get_unchecked(2);\n /// first + second + third\n /// }\n /// ```\n pub fn get_unchecked(self, index: u32) -> T {\n self.storage[index]\n }\n\n /// Writes an element to the vector at the given index, starting from zero.\n ///\n /// If the given index is equal to or greater than the length of the vector, this will issue a constraint failure.\n ///\n /// Example:\n ///\n /// ```noir\n /// fn foo<let N: u32>(v: BoundedVec<u32, N>) {\n /// let first = v.get(0);\n /// assert(first != 42);\n /// v.set(0, 42);\n /// let new_first = v.get(0);\n /// assert(new_first == 42);\n /// }\n /// ```\n pub fn set(&mut self, index: u32, value: T) {\n assert(index < self.len, \"Attempted to write past end of BoundedVec\");\n self.set_unchecked(index, value)\n }\n\n /// Writes an element to the vector at the given index, starting from zero, without performing a bounds check.\n ///\n /// Since this function does not perform a bounds check on length before accessing the element, it is unsafe! Use at your own risk!\n ///\n /// Example:\n ///\n /// ```noir\n /// fn set_unchecked_example() {\n /// let mut vec: BoundedVec<u32, 5> = BoundedVec::new();\n /// vec.extend_from_array([1, 2]);\n ///\n /// // Here we're safely writing within the valid range of `vec`\n /// // `vec` now has the value [42, 2]\n /// vec.set_unchecked(0, 42);\n ///\n /// // We can then safely read this value back out of `vec`.\n /// // Notice that we use the checked version of `get` which would prevent reading unsafe values.\n /// assert_eq(vec.get(0), 42);\n ///\n /// // We've now written past the end of `vec`.\n /// // As this index is still within the maximum potential length of `v`,\n /// // it won't cause a constraint failure.\n /// vec.set_unchecked(2, 42);\n /// println(vec);\n ///\n /// // This will write past the end of the maximum potential length of `vec`,\n /// // it will then trigger a constraint failure.\n /// vec.set_unchecked(5, 42);\n /// println(vec);\n /// }\n /// ```\n pub fn set_unchecked(&mut self, index: u32, value: T) {\n self.storage[index] = value;\n }\n\n /// Pushes an element to the end of the vector. This increases the length\n /// of the vector by one.\n ///\n /// Panics if the new length of the vector will be greater than the max length.\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut v: BoundedVec<Field, 2> = BoundedVec::new();\n ///\n /// v.push(1);\n /// v.push(2);\n ///\n /// // Panics with failed assertion \"push out of bounds\"\n /// v.push(3);\n /// ```\n pub fn push(&mut self, elem: T) {\n assert(self.len < MaxLen, \"push out of bounds\");\n\n self.storage[self.len] = elem;\n self.len += 1;\n }\n\n /// Returns the current length of this vector\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut v: BoundedVec<Field, 4> = BoundedVec::new();\n /// assert(v.len() == 0);\n ///\n /// v.push(100);\n /// assert(v.len() == 1);\n ///\n /// v.push(200);\n /// v.push(300);\n /// v.push(400);\n /// assert(v.len() == 4);\n ///\n /// let _ = v.pop();\n /// let _ = v.pop();\n /// assert(v.len() == 2);\n /// ```\n pub fn len(self) -> u32 {\n self.len\n }\n\n /// Returns the maximum length of this vector. This is always\n /// equal to the `MaxLen` parameter this vector was initialized with.\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut v: BoundedVec<Field, 5> = BoundedVec::new();\n ///\n /// assert(v.max_len() == 5);\n /// v.push(10);\n /// assert(v.max_len() == 5);\n /// ```\n pub fn max_len(_self: BoundedVec<T, MaxLen>) -> u32 {\n MaxLen\n }\n\n /// Returns the internal array within this vector.\n ///\n /// Since arrays in Noir are immutable, mutating the returned storage array will not mutate\n /// the storage held internally by this vector.\n ///\n /// Note that uninitialized elements may be zeroed out!\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut v: BoundedVec<Field, 5> = BoundedVec::new();\n ///\n /// assert(v.storage() == [0, 0, 0, 0, 0]);\n ///\n /// v.push(57);\n /// assert(v.storage() == [57, 0, 0, 0, 0]);\n /// ```\n pub fn storage(self) -> [T; MaxLen] {\n self.storage\n }\n\n /// Pushes each element from the given array to this vector.\n ///\n /// Panics if pushing each element would cause the length of this vector\n /// to exceed the maximum length.\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut vec: BoundedVec<Field, 3> = BoundedVec::new();\n /// vec.extend_from_array([2, 4]);\n ///\n /// assert(vec.len == 2);\n /// assert(vec.get(0) == 2);\n /// assert(vec.get(1) == 4);\n /// ```\n pub fn extend_from_array<let Len: u32>(&mut self, array: [T; Len]) {\n let new_len = self.len + array.len();\n assert(new_len <= MaxLen, \"extend_from_array out of bounds\");\n for i in 0..array.len() {\n self.storage[self.len + i] = array[i];\n }\n self.len = new_len;\n }\n\n /// Pushes each element from the given slice to this vector.\n ///\n /// Panics if pushing each element would cause the length of this vector\n /// to exceed the maximum length.\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut vec: BoundedVec<Field, 3> = BoundedVec::new();\n /// vec.extend_from_slice(&[2, 4]);\n ///\n /// assert(vec.len == 2);\n /// assert(vec.get(0) == 2);\n /// assert(vec.get(1) == 4);\n /// ```\n pub fn extend_from_slice(&mut self, slice: [T]) {\n let new_len = self.len + slice.len();\n assert(new_len <= MaxLen, \"extend_from_slice out of bounds\");\n for i in 0..slice.len() {\n self.storage[self.len + i] = slice[i];\n }\n self.len = new_len;\n }\n\n /// Pushes each element from the other vector to this vector. The length of\n /// the other vector is left unchanged.\n ///\n /// Panics if pushing each element would cause the length of this vector\n /// to exceed the maximum length.\n ///\n /// ```noir\n /// let mut v1: BoundedVec<Field, 5> = BoundedVec::new();\n /// let mut v2: BoundedVec<Field, 7> = BoundedVec::new();\n ///\n /// v2.extend_from_array([1, 2, 3]);\n /// v1.extend_from_bounded_vec(v2);\n ///\n /// assert(v1.storage() == [1, 2, 3, 0, 0]);\n /// assert(v2.storage() == [1, 2, 3, 0, 0, 0, 0]);\n /// ```\n pub fn extend_from_bounded_vec<let Len: u32>(&mut self, vec: BoundedVec<T, Len>) {\n let append_len = vec.len();\n let new_len = self.len + append_len;\n assert(new_len <= MaxLen, \"extend_from_bounded_vec out of bounds\");\n\n if is_unconstrained() {\n for i in 0..append_len {\n self.storage[self.len + i] = vec.get_unchecked(i);\n }\n } else {\n let mut exceeded_len = false;\n for i in 0..Len {\n exceeded_len |= i == append_len;\n if !exceeded_len {\n self.storage[self.len + i] = vec.get_unchecked(i);\n }\n }\n }\n self.len = new_len;\n }\n\n /// Creates a new vector, populating it with values derived from an array input.\n /// The maximum length of the vector is determined based on the type signature.\n ///\n /// Example:\n ///\n /// ```noir\n /// let bounded_vec: BoundedVec<Field, 10> = BoundedVec::from_array([1, 2, 3])\n /// ```\n pub fn from_array<let Len: u32>(array: [T; Len]) -> Self {\n static_assert(Len <= MaxLen, \"from array out of bounds\");\n let mut vec: BoundedVec<T, MaxLen> = BoundedVec::new();\n vec.extend_from_array(array);\n vec\n }\n\n /// Pops the element at the end of the vector. This will decrease the length\n /// of the vector by one.\n ///\n /// Panics if the vector is empty.\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut v: BoundedVec<Field, 2> = BoundedVec::new();\n /// v.push(1);\n /// v.push(2);\n ///\n /// let two = v.pop();\n /// let one = v.pop();\n ///\n /// assert(two == 2);\n /// assert(one == 1);\n ///\n /// // error: cannot pop from an empty vector\n /// let _ = v.pop();\n /// ```\n pub fn pop(&mut self) -> T {\n assert(self.len > 0);\n self.len -= 1;\n\n let elem = self.storage[self.len];\n self.storage[self.len] = crate::mem::zeroed();\n elem\n }\n\n /// Returns true if the given predicate returns true for any element\n /// in this vector.\n ///\n /// Example:\n ///\n /// ```noir\n /// let mut v: BoundedVec<u32, 3> = BoundedVec::new();\n /// v.extend_from_array([2, 4, 6]);\n ///\n /// let all_even = !v.any(|elem: u32| elem % 2 != 0);\n /// assert(all_even);\n /// ```\n pub fn any<Env>(self, predicate: fn[Env](T) -> bool) -> bool {\n let mut ret = false;\n if is_unconstrained() {\n for i in 0..self.len {\n ret |= predicate(self.storage[i]);\n }\n } else {\n let mut ret = false;\n let mut exceeded_len = false;\n for i in 0..MaxLen {\n exceeded_len |= i == self.len;\n if !exceeded_len {\n ret |= predicate(self.storage[i]);\n }\n }\n }\n ret\n }\n\n /// Creates a new vector of equal size by calling a closure on each element in this vector.\n ///\n /// Example:\n ///\n /// ```noir\n /// let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n /// let result = vec.map(|value| value * 2);\n ///\n /// let expected = BoundedVec::from_array([2, 4, 6, 8]);\n /// assert_eq(result, expected);\n /// ```\n pub fn map<U, Env>(self, f: fn[Env](T) -> U) -> BoundedVec<U, MaxLen> {\n let mut ret = BoundedVec::new();\n ret.len = self.len();\n\n if is_unconstrained() {\n for i in 0..self.len() {\n ret.storage[i] = f(self.get_unchecked(i));\n }\n } else {\n for i in 0..MaxLen {\n if i < self.len() {\n ret.storage[i] = f(self.get_unchecked(i));\n }\n }\n }\n\n ret\n }\n\n /// Creates a new vector of equal size by calling a closure on each element\n /// in this vector, along with its index.\n ///\n /// Example:\n ///\n /// ```noir\n /// let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n /// let result = vec.mapi(|i, value| i + value * 2);\n ///\n /// let expected = BoundedVec::from_array([2, 5, 8, 11]);\n /// assert_eq(result, expected);\n /// ```\n pub fn mapi<U, Env>(self, f: fn[Env](u32, T) -> U) -> BoundedVec<U, MaxLen> {\n let mut ret = BoundedVec::new();\n ret.len = self.len();\n\n if is_unconstrained() {\n for i in 0..self.len() {\n ret.storage[i] = f(i, self.get_unchecked(i));\n }\n } else {\n for i in 0..MaxLen {\n if i < self.len() {\n ret.storage[i] = f(i, self.get_unchecked(i));\n }\n }\n }\n\n ret\n }\n\n /// Calls a closure on each element in this vector.\n ///\n /// Example:\n ///\n /// ```noir\n /// let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n /// let mut result = BoundedVec::<u32, 4>::new();\n /// vec.for_each(|value| result.push(value * 2));\n ///\n /// let expected = BoundedVec::from_array([2, 4, 6, 8]);\n /// assert_eq(result, expected);\n /// ```\n pub fn for_each<Env>(self, f: fn[Env](T) -> ()) {\n if is_unconstrained() {\n for i in 0..self.len() {\n f(self.get_unchecked(i));\n }\n } else {\n for i in 0..MaxLen {\n if i < self.len() {\n f(self.get_unchecked(i));\n }\n }\n }\n }\n\n /// Calls a closure on each element in this vector, along with its index.\n ///\n /// Example:\n ///\n /// ```noir\n /// let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n /// let mut result = BoundedVec::<u32, 4>::new();\n /// vec.for_eachi(|i, value| result.push(i + value * 2));\n ///\n /// let expected = BoundedVec::from_array([2, 5, 8, 11]);\n /// assert_eq(result, expected);\n /// ```\n pub fn for_eachi<Env>(self, f: fn[Env](u32, T) -> ()) {\n if is_unconstrained() {\n for i in 0..self.len() {\n f(i, self.get_unchecked(i));\n }\n } else {\n for i in 0..MaxLen {\n if i < self.len() {\n f(i, self.get_unchecked(i));\n }\n }\n }\n }\n\n /// Creates a new BoundedVec from the given array and length.\n /// The given length must be less than or equal to the length of the array.\n ///\n /// This function will zero out any elements at or past index `len` of `array`.\n /// This incurs an extra runtime cost of O(MaxLen). If you are sure your array is\n /// zeroed after that index, you can use `from_parts_unchecked` to remove the extra loop.\n ///\n /// Example:\n ///\n /// ```noir\n /// let vec: BoundedVec<u32, 4> = BoundedVec::from_parts([1, 2, 3, 0], 3);\n /// assert_eq(vec.len(), 3);\n /// ```\n pub fn from_parts(mut array: [T; MaxLen], len: u32) -> Self {\n assert(len <= MaxLen);\n let zeroed = crate::mem::zeroed();\n\n if is_unconstrained() {\n for i in len..MaxLen {\n array[i] = zeroed;\n }\n } else {\n for i in 0..MaxLen {\n if i >= len {\n array[i] = zeroed;\n }\n }\n }\n\n BoundedVec { storage: array, len }\n }\n\n /// Creates a new BoundedVec from the given array and length.\n /// The given length must be less than or equal to the length of the array.\n ///\n /// This function is unsafe because it expects all elements past the `len` index\n /// of `array` to be zeroed, but does not check for this internally. Use `from_parts`\n /// for a safe version of this function which does zero out any indices past the\n /// given length. Invalidating this assumption can notably cause `BoundedVec::eq`\n /// to give incorrect results since it will check even elements past `len`.\n ///\n /// Example:\n ///\n /// ```noir\n /// let vec: BoundedVec<u32, 4> = BoundedVec::from_parts_unchecked([1, 2, 3, 0], 3);\n /// assert_eq(vec.len(), 3);\n ///\n /// // invalid use!\n /// let vec1: BoundedVec<u32, 4> = BoundedVec::from_parts_unchecked([1, 2, 3, 1], 3);\n /// let vec2: BoundedVec<u32, 4> = BoundedVec::from_parts_unchecked([1, 2, 3, 2], 3);\n ///\n /// // both vecs have length 3 so we'd expect them to be equal, but this\n /// // fails because elements past the length are still checked in eq\n /// assert_eq(vec1, vec2); // fails\n /// ```\n pub fn from_parts_unchecked(array: [T; MaxLen], len: u32) -> Self {\n assert(len <= MaxLen);\n BoundedVec { storage: array, len }\n }\n}\n\nimpl<T, let MaxLen: u32> Eq for BoundedVec<T, MaxLen>\nwhere\n T: Eq,\n{\n fn eq(self, other: BoundedVec<T, MaxLen>) -> bool {\n // TODO: https://github.com/noir-lang/noir/issues/4837\n //\n // We make the assumption that the user has used the proper interface for working with `BoundedVec`s\n // rather than directly manipulating the internal fields as this can result in an inconsistent internal state.\n if self.len == other.len {\n self.storage == other.storage\n } else {\n false\n }\n }\n}\n\nimpl<T, let MaxLen: u32, let Len: u32> From<[T; Len]> for BoundedVec<T, MaxLen> {\n fn from(array: [T; Len]) -> BoundedVec<T, MaxLen> {\n BoundedVec::from_array(array)\n }\n}\n\nmod bounded_vec_tests {\n\n mod get {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test(should_fail_with = \"Attempted to read past end of BoundedVec\")]\n fn panics_when_reading_elements_past_end_of_vec() {\n let vec: BoundedVec<Field, 5> = BoundedVec::new();\n\n crate::println(vec.get(0));\n }\n }\n\n mod set {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test]\n fn set_updates_values_properly() {\n let mut vec = BoundedVec::from_array([0, 0, 0, 0, 0]);\n\n vec.set(0, 42);\n assert_eq(vec.storage, [42, 0, 0, 0, 0]);\n\n vec.set(1, 43);\n assert_eq(vec.storage, [42, 43, 0, 0, 0]);\n\n vec.set(2, 44);\n assert_eq(vec.storage, [42, 43, 44, 0, 0]);\n\n vec.set(1, 10);\n assert_eq(vec.storage, [42, 10, 44, 0, 0]);\n\n vec.set(0, 0);\n assert_eq(vec.storage, [0, 10, 44, 0, 0]);\n }\n\n #[test(should_fail_with = \"Attempted to write past end of BoundedVec\")]\n fn panics_when_writing_elements_past_end_of_vec() {\n let mut vec: BoundedVec<Field, 5> = BoundedVec::new();\n vec.set(0, 42);\n\n // Need to use println to avoid DIE removing the write operation.\n crate::println(vec.get(0));\n }\n }\n\n mod map {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test]\n fn applies_function_correctly() {\n // docs:start:bounded-vec-map-example\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = vec.map(|value| value * 2);\n // docs:end:bounded-vec-map-example\n let expected = BoundedVec::from_array([2, 4, 6, 8]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn applies_function_that_changes_return_type() {\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = vec.map(|value| (value * 2) as Field);\n let expected: BoundedVec<Field, 4> = BoundedVec::from_array([2, 4, 6, 8]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn does_not_apply_function_past_len() {\n let vec: BoundedVec<u32, 3> = BoundedVec::from_array([0, 1]);\n let result = vec.map(|value| if value == 0 { 5 } else { value });\n let expected = BoundedVec::from_array([5, 1]);\n\n assert_eq(result, expected);\n assert_eq(result.get_unchecked(2), 0);\n }\n }\n\n mod mapi {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test]\n fn applies_function_correctly() {\n // docs:start:bounded-vec-mapi-example\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = vec.mapi(|i, value| i + value * 2);\n // docs:end:bounded-vec-mapi-example\n let expected = BoundedVec::from_array([2, 5, 8, 11]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn applies_function_that_changes_return_type() {\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = vec.mapi(|i, value| (i + value * 2) as Field);\n let expected: BoundedVec<Field, 4> = BoundedVec::from_array([2, 5, 8, 11]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn does_not_apply_function_past_len() {\n let vec: BoundedVec<u32, 3> = BoundedVec::from_array([0, 1]);\n let result = vec.mapi(|_, value| if value == 0 { 5 } else { value });\n let expected = BoundedVec::from_array([5, 1]);\n\n assert_eq(result, expected);\n assert_eq(result.get_unchecked(2), 0);\n }\n }\n\n mod for_each {\n use crate::collections::bounded_vec::BoundedVec;\n\n // map in terms of for_each\n fn for_each_map<T, U, Env, let MaxLen: u32>(\n input: BoundedVec<T, MaxLen>,\n f: fn[Env](T) -> U,\n ) -> BoundedVec<U, MaxLen> {\n let mut output = BoundedVec::<U, MaxLen>::new();\n let output_ref = &mut output;\n input.for_each(|x| output_ref.push(f(x)));\n output\n }\n\n #[test]\n fn smoke_test() {\n let mut acc = 0;\n let acc_ref = &mut acc;\n // docs:start:bounded-vec-for-each-example\n let vec: BoundedVec<u32, 3> = BoundedVec::from_array([1, 2, 3]);\n vec.for_each(|value| { *acc_ref += value; });\n // docs:end:bounded-vec-for-each-example\n assert_eq(acc, 6);\n }\n\n #[test]\n fn applies_function_correctly() {\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = for_each_map(vec, |value| value * 2);\n let expected = BoundedVec::from_array([2, 4, 6, 8]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn applies_function_that_changes_return_type() {\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = for_each_map(vec, |value| (value * 2) as Field);\n let expected: BoundedVec<Field, 4> = BoundedVec::from_array([2, 4, 6, 8]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn does_not_apply_function_past_len() {\n let vec: BoundedVec<u32, 3> = BoundedVec::from_array([0, 1]);\n let result = for_each_map(vec, |value| if value == 0 { 5 } else { value });\n let expected = BoundedVec::from_array([5, 1]);\n\n assert_eq(result, expected);\n assert_eq(result.get_unchecked(2), 0);\n }\n }\n\n mod for_eachi {\n use crate::collections::bounded_vec::BoundedVec;\n\n // mapi in terms of for_eachi\n fn for_eachi_mapi<T, U, Env, let MaxLen: u32>(\n input: BoundedVec<T, MaxLen>,\n f: fn[Env](u32, T) -> U,\n ) -> BoundedVec<U, MaxLen> {\n let mut output = BoundedVec::<U, MaxLen>::new();\n let output_ref = &mut output;\n input.for_eachi(|i, x| output_ref.push(f(i, x)));\n output\n }\n\n #[test]\n fn smoke_test() {\n let mut acc = 0;\n let acc_ref = &mut acc;\n // docs:start:bounded-vec-for-eachi-example\n let vec: BoundedVec<u32, 3> = BoundedVec::from_array([1, 2, 3]);\n vec.for_eachi(|i, value| { *acc_ref += i * value; });\n // docs:end:bounded-vec-for-eachi-example\n\n // 0 * 1 + 1 * 2 + 2 * 3\n assert_eq(acc, 8);\n }\n\n #[test]\n fn applies_function_correctly() {\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = for_eachi_mapi(vec, |i, value| i + value * 2);\n let expected = BoundedVec::from_array([2, 5, 8, 11]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn applies_function_that_changes_return_type() {\n let vec: BoundedVec<u32, 4> = BoundedVec::from_array([1, 2, 3, 4]);\n let result = for_eachi_mapi(vec, |i, value| (i + value * 2) as Field);\n let expected: BoundedVec<Field, 4> = BoundedVec::from_array([2, 5, 8, 11]);\n\n assert_eq(result, expected);\n }\n\n #[test]\n fn does_not_apply_function_past_len() {\n let vec: BoundedVec<u32, 3> = BoundedVec::from_array([0, 1]);\n let result = for_eachi_mapi(vec, |_, value| if value == 0 { 5 } else { value });\n let expected = BoundedVec::from_array([5, 1]);\n\n assert_eq(result, expected);\n assert_eq(result.get_unchecked(2), 0);\n }\n }\n\n mod from_array {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test]\n fn empty() {\n let empty_array: [Field; 0] = [];\n let bounded_vec = BoundedVec::from_array([]);\n\n assert_eq(bounded_vec.max_len(), 0);\n assert_eq(bounded_vec.len(), 0);\n assert_eq(bounded_vec.storage(), empty_array);\n }\n\n #[test]\n fn equal_len() {\n let array = [1, 2, 3];\n let bounded_vec = BoundedVec::from_array(array);\n\n assert_eq(bounded_vec.max_len(), 3);\n assert_eq(bounded_vec.len(), 3);\n assert_eq(bounded_vec.storage(), array);\n }\n\n #[test]\n fn max_len_greater_then_array_len() {\n let array = [1, 2, 3];\n let bounded_vec: BoundedVec<Field, 10> = BoundedVec::from_array(array);\n\n assert_eq(bounded_vec.max_len(), 10);\n assert_eq(bounded_vec.len(), 3);\n assert_eq(bounded_vec.get(0), 1);\n assert_eq(bounded_vec.get(1), 2);\n assert_eq(bounded_vec.get(2), 3);\n }\n\n #[test(should_fail_with = \"from array out of bounds\")]\n fn max_len_lower_then_array_len() {\n let _: BoundedVec<Field, 2> = BoundedVec::from_array([0; 3]);\n }\n }\n\n mod trait_from {\n use crate::collections::bounded_vec::BoundedVec;\n use crate::convert::From;\n\n #[test]\n fn simple() {\n let array = [1, 2];\n let bounded_vec: BoundedVec<Field, 10> = BoundedVec::from(array);\n\n assert_eq(bounded_vec.max_len(), 10);\n assert_eq(bounded_vec.len(), 2);\n assert_eq(bounded_vec.get(0), 1);\n assert_eq(bounded_vec.get(1), 2);\n }\n }\n\n mod trait_eq {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test]\n fn empty_equality() {\n let mut bounded_vec1: BoundedVec<Field, 3> = BoundedVec::new();\n let mut bounded_vec2: BoundedVec<Field, 3> = BoundedVec::new();\n\n assert_eq(bounded_vec1, bounded_vec2);\n }\n\n #[test]\n fn inequality() {\n let mut bounded_vec1: BoundedVec<Field, 3> = BoundedVec::new();\n let mut bounded_vec2: BoundedVec<Field, 3> = BoundedVec::new();\n bounded_vec1.push(1);\n bounded_vec2.push(2);\n\n assert(bounded_vec1 != bounded_vec2);\n }\n }\n\n mod from_parts {\n use crate::collections::bounded_vec::BoundedVec;\n\n #[test]\n fn from_parts() {\n // docs:start:from-parts\n let vec: BoundedVec<u32, 4> = BoundedVec::from_parts([1, 2, 3, 0], 3);\n assert_eq(vec.len(), 3);\n\n // Any elements past the given length are zeroed out, so these\n // two BoundedVecs will be completely equal\n let vec1: BoundedVec<u32, 4> = BoundedVec::from_parts([1, 2, 3, 1], 3);\n let vec2: BoundedVec<u32, 4> = BoundedVec::from_parts([1, 2, 3, 2], 3);\n assert_eq(vec1, vec2);\n // docs:end:from-parts\n }\n\n #[test]\n fn from_parts_unchecked() {\n // docs:start:from-parts-unchecked\n let vec: BoundedVec<u32, 4> = BoundedVec::from_parts_unchecked([1, 2, 3, 0], 3);\n assert_eq(vec.len(), 3);\n\n // invalid use!\n let vec1: BoundedVec<u32, 4> = BoundedVec::from_parts_unchecked([1, 2, 3, 1], 3);\n let vec2: BoundedVec<u32, 4> = BoundedVec::from_parts_unchecked([1, 2, 3, 2], 3);\n\n // both vecs have length 3 so we'd expect them to be equal, but this\n // fails because elements past the length are still checked in eq\n assert(vec1 != vec2);\n // docs:end:from-parts-unchecked\n }\n }\n}\n","path":"std/collections/bounded_vec.nr"},"22":{"source":"pub mod hash;\npub mod aes128;\npub mod array;\npub mod slice;\npub mod ecdsa_secp256k1;\npub mod ecdsa_secp256r1;\npub mod embedded_curve_ops;\npub mod field;\npub mod collections;\npub mod compat;\npub mod convert;\npub mod option;\npub mod string;\npub mod test;\npub mod cmp;\npub mod ops;\npub mod default;\npub mod prelude;\npub mod runtime;\npub mod meta;\npub mod append;\npub mod mem;\npub mod panic;\npub mod hint;\n\nuse convert::AsPrimitive;\n\n// Oracle calls are required to be wrapped in an unconstrained function\n// Thus, the only argument to the `println` oracle is expected to always be an ident\n#[oracle(print)]\nunconstrained fn print_oracle<T>(with_newline: bool, input: T) {}\n\nunconstrained fn print_unconstrained<T>(with_newline: bool, input: T) {\n print_oracle(with_newline, input);\n}\n\npub fn println<T>(input: T) {\n // Safety: a print statement cannot be constrained\n unsafe {\n print_unconstrained(true, input);\n }\n}\n\npub fn print<T>(input: T) {\n // Safety: a print statement cannot be constrained\n unsafe {\n print_unconstrained(false, input);\n }\n}\n\npub fn verify_proof<let N: u32, let M: u32, let K: u32>(\n verification_key: [Field; N],\n proof: [Field; M],\n public_inputs: [Field; K],\n key_hash: Field,\n) {\n verify_proof_internal(verification_key, proof, public_inputs, key_hash, 0);\n}\n\npub fn verify_proof_with_type<let N: u32, let M: u32, let K: u32>(\n verification_key: [Field; N],\n proof: [Field; M],\n public_inputs: [Field; K],\n key_hash: Field,\n proof_type: u32,\n) {\n if !crate::runtime::is_unconstrained() {\n crate::assert_constant(proof_type);\n }\n verify_proof_internal(verification_key, proof, public_inputs, key_hash, proof_type);\n}\n\n#[foreign(recursive_aggregation)]\nfn verify_proof_internal<let N: u32, let M: u32, let K: u32>(\n verification_key: [Field; N],\n proof: [Field; M],\n public_inputs: [Field; K],\n key_hash: Field,\n proof_type: u32,\n) {}\n\n// Asserts that the given value is known at compile-time.\n// Useful for debugging for-loop bounds.\n#[builtin(assert_constant)]\npub fn assert_constant<T>(x: T) {}\n\n// Asserts that the given value is both true and known at compile-time.\n// The message can be a string, a format string, or any value, as long as it is known at compile-time\n#[builtin(static_assert)]\npub fn static_assert<T>(predicate: bool, message: T) {}\n\n#[deprecated(\"wrapping operations should be done with the Wrapping traits. E.g: x.wrapping_add(y)\")]\npub fn wrapping_add<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#[deprecated(\"wrapping operations should be done with the Wrapping traits. E.g: x.wrapping_sub(y)\")]\npub fn wrapping_sub<T>(x: T, y: T) -> T\nwhere\n T: AsPrimitive<Field>,\n Field: AsPrimitive<T>,\n{\n //340282366920938463463374607431768211456 is 2^128, it is used to avoid underflow\n AsPrimitive::as_(x.as_() + 340282366920938463463374607431768211456 - y.as_())\n}\n#[deprecated(\"wrapping operations should be done with the Wrapping traits. E.g: x.wrapping_mul(y)\")]\npub fn wrapping_mul<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\n#[builtin(as_witness)]\npub fn as_witness(x: Field) {}\n\nmod tests {\n use super::ops::arith::WrappingMul;\n\n #[test(should_fail_with = \"custom message\")]\n fn test_static_assert_custom_message() {\n super::static_assert(1 == 2, \"custom message\");\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 // 1*0==0\n assert_eq(zero, zero.wrapping_mul(one));\n\n // 0*1==0\n assert_eq(zero, one.wrapping_mul(zero));\n\n // 1*1==1\n assert_eq(one, one.wrapping_mul(one));\n\n // 0 * ( 1 << 64 ) == 0\n assert_eq(zero, zero.wrapping_mul(two_pow_64));\n\n // ( 1 << 64 ) * 0 == 0\n assert_eq(zero, two_pow_64.wrapping_mul(zero));\n\n // 1 * ( 1 << 64 ) == 1 << 64\n assert_eq(two_pow_64, two_pow_64.wrapping_mul(one));\n\n // ( 1 << 64 ) * 1 == 1 << 64\n assert_eq(two_pow_64, one.wrapping_mul(two_pow_64));\n\n // ( 1 << 64 ) * ( 1 << 64 ) == 1 << 64\n assert_eq(zero, two_pow_64.wrapping_mul(two_pow_64));\n // -1 * -1 == 1\n assert_eq(one, u128_max.wrapping_mul(u128_max));\n }\n}\n","path":"std/lib.nr"},"50":{"source":"use dep::mock_types::{\n AppPublicInputs, CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS, PrivateKernelPublicInputs,\n PrivateKernelPublicInputsBuilder, PROOF_TYPE_OINK, TxRequest,\n};\n\nfn main(\n tx: TxRequest,\n app_inputs: call_data(1) AppPublicInputs,\n app_vk: [Field; CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS],\n) -> return_data PrivateKernelPublicInputs {\n std::verify_proof_with_type(app_vk, [], [], 0, PROOF_TYPE_OINK);\n\n let mut private_kernel_inputs = PrivateKernelPublicInputsBuilder::from_tx(tx);\n private_kernel_inputs.ingest_app_inputs(app_inputs);\n private_kernel_inputs.finish()\n}\n","path":"/home/aztec-dev/aztec-packages/noir-projects/mock-protocol-circuits/crates/mock-private-kernel-init/src/main.nr"},"51":{"source":"pub global MAX_COMMITMENTS_PER_CALL: u32 = 2;\npub global MAX_COMMITMENTS_PER_TX: u32 = 4;\npub global MAX_COMMITMENT_READ_REQUESTS_PER_CALL: u32 = 2;\npub global MAX_COMMITMENT_READ_REQUESTS_PER_TX: u32 = 4;\n\npub use protocol_types::{\n constants::{\n CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS, NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,\n PROOF_TYPE_OINK, PROOF_TYPE_PG, PROOF_TYPE_ROLLUP_HONK, PROOF_TYPE_ROOT_ROLLUP_HONK,\n ROLLUP_HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS, TUBE_PROOF_LENGTH,\n },\n proof::verification_key::{RollupHonkVerificationKey, VerificationKey},\n traits::Serialize,\n};\n\npub struct TxRequest {\n pub number_of_calls: u32,\n}\n\npub struct AppPublicInputs {\n pub commitments: [Field; MAX_COMMITMENTS_PER_CALL],\n pub read_requests: [Field; MAX_COMMITMENT_READ_REQUESTS_PER_CALL],\n}\n\nimpl Default for AppPublicInputs {\n fn default() -> Self {\n Self {\n commitments: [0; MAX_COMMITMENTS_PER_CALL],\n read_requests: [0; MAX_COMMITMENT_READ_REQUESTS_PER_CALL],\n }\n }\n}\n\npub struct PrivateKernelPublicInputs {\n pub remaining_calls: u32,\n pub commitments: [Field; MAX_COMMITMENTS_PER_TX],\n pub read_requests: [Field; MAX_COMMITMENT_READ_REQUESTS_PER_TX],\n}\n\nimpl Default for PrivateKernelPublicInputs {\n fn default() -> Self {\n Self {\n remaining_calls: 0,\n commitments: [0; MAX_COMMITMENTS_PER_TX],\n read_requests: [0; MAX_COMMITMENT_READ_REQUESTS_PER_TX],\n }\n }\n}\n\npub struct PrivateKernelPublicInputsBuilder {\n pub remaining_calls: u32,\n pub commitments: BoundedVec<Field, MAX_COMMITMENTS_PER_TX>,\n pub read_requests: BoundedVec<Field, MAX_COMMITMENT_READ_REQUESTS_PER_TX>,\n}\n\nimpl PrivateKernelPublicInputsBuilder {\n pub fn from_tx(tx: TxRequest) -> Self {\n Self {\n remaining_calls: tx.number_of_calls,\n commitments: BoundedVec::new(),\n read_requests: BoundedVec::new(),\n }\n }\n\n pub fn from_previous_kernel(prev_kernel_public_inputs: PrivateKernelPublicInputs) -> Self {\n let mut builder = PrivateKernelPublicInputsBuilder {\n remaining_calls: prev_kernel_public_inputs.remaining_calls,\n commitments: BoundedVec::new(),\n read_requests: BoundedVec::new(),\n };\n for i in 0..MAX_COMMITMENTS_PER_TX {\n if prev_kernel_public_inputs.commitments[i] != 0 {\n builder.commitments.push(prev_kernel_public_inputs.commitments[i]);\n }\n }\n for i in 0..MAX_COMMITMENT_READ_REQUESTS_PER_TX {\n if prev_kernel_public_inputs.read_requests[i] != 0 {\n builder.read_requests.push(prev_kernel_public_inputs.read_requests[i]);\n }\n }\n builder\n }\n\n pub fn ingest_app_inputs(&mut self, app_inputs: AppPublicInputs) {\n for i in 0..MAX_COMMITMENTS_PER_CALL {\n if app_inputs.commitments[i] != 0 {\n self.commitments.push(app_inputs.commitments[i]);\n }\n }\n\n for i in 0..MAX_COMMITMENT_READ_REQUESTS_PER_CALL {\n if app_inputs.read_requests[i] != 0 {\n self.read_requests.push(app_inputs.read_requests[i]);\n }\n }\n\n self.remaining_calls -= 1;\n }\n\n pub fn finish(self) -> PrivateKernelPublicInputs {\n PrivateKernelPublicInputs {\n remaining_calls: self.remaining_calls,\n commitments: self.commitments.storage(),\n read_requests: self.read_requests.storage(),\n }\n }\n}\n\npub struct KernelPublicInputs {\n pub commitments: [Field; MAX_COMMITMENTS_PER_TX],\n}\n\nimpl Default for KernelPublicInputs {\n fn default() -> Self {\n Self { commitments: [0; MAX_COMMITMENTS_PER_TX] }\n }\n}\n\nimpl Serialize<MAX_COMMITMENTS_PER_TX> for KernelPublicInputs {\n fn serialize(self) -> [Field; MAX_COMMITMENTS_PER_TX] {\n self.commitments\n }\n}\n\npub struct RollupPublicInputs {\n accumulated: u32,\n}\n\nimpl RollupPublicInputs {\n pub fn new(accumulated: u32) -> Self {\n Self { accumulated }\n }\n\n pub fn merge(self, other: Self) -> Self {\n Self { accumulated: self.accumulated + other.accumulated }\n }\n}\n\nimpl Serialize<1> for RollupPublicInputs {\n fn serialize(self) -> [Field; 1] {\n [self.accumulated as Field]\n }\n}\n\npub struct PreviousRollupData {\n base_or_merge_public_inputs: RollupPublicInputs,\n proof: [Field; NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH],\n vk: RollupHonkVerificationKey,\n}\n\nimpl PreviousRollupData {\n pub fn verify(self, is_root: bool) {\n let inputs = self.base_or_merge_public_inputs.serialize();\n\n std::verify_proof_with_type(\n self.vk.key,\n self.proof,\n inputs,\n self.vk.hash,\n if is_root {\n PROOF_TYPE_ROOT_ROLLUP_HONK\n } else {\n PROOF_TYPE_ROLLUP_HONK\n },\n );\n }\n\n pub fn public_inputs(self) -> RollupPublicInputs {\n self.base_or_merge_public_inputs\n }\n}\n\npub struct TubeData {\n pub public_inputs: KernelPublicInputs,\n pub proof: [Field; TUBE_PROOF_LENGTH],\n pub vk_data: VerificationKey<ROLLUP_HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS>,\n}\n\nimpl TubeData {\n pub fn verify(self) {\n let inputs = KernelPublicInputs::serialize(self.public_inputs);\n std::verify_proof_with_type(\n self.vk_data.key,\n self.proof,\n inputs,\n self.vk_data.hash,\n PROOF_TYPE_ROLLUP_HONK,\n );\n }\n}\n","path":"/home/aztec-dev/aztec-packages/noir-projects/mock-protocol-circuits/crates/mock-types/src/lib.nr"}},"names":["main"],"brillig_names":["directive_invert","directive_integer_quotient"]}
|