@@ -14,90 +14,72 @@ use dep::protocol_types::{
1414 traits ::{Serialize , ToField },
1515};
1616
17- /// Specifies the configuration parameters for message delivery across three key dimensions :
17+ /// Specifies the configuration parameters for message delivery. There are two fundamental aspects to consider :
1818///
19- /// +--------------------------------------------------------------------------------------------------------+
20- /// | 1. Constrained or unconstrained encryption |
21- /// | - When the encryption is constrained we have a guarantee that the resulting ciphertext is formed |
22- /// | correctly. If we don't need this guarantee and we are fine with trusting the sender, it is |
23- /// | recommended to use unconstrained encryption as it's cheaper constraint-wise. |
24- /// +--------------------------------------------------------------------------------------------------------+
19+ /// +----------------------------------------------------------------------------------------------------------+
20+ /// | 1. Delivery Mechanism |
21+ /// | - Messages can be delivered either on-chain or out-of-band |
22+ /// | - On-chain delivery uses the Aztec protocol's private log stream, submitted to L1 blobs and consuming DA |
23+ /// | - Out-of-band delivery is implemented by the application (e.g. storing ciphertexts in cloud storage) |
24+ /// | - Out-of-band delivery cannot have any cryptographic constraints since messages are never stored on-chain|
25+ /// +----------------------------------------------------------------------------------------------------------+
2526///
26- /// +--------------------------------------------------------------------------------------------------------+
27- /// | 2. Delivery mechanism |
28- /// | - The message ciphertext can be delivered either via the private log stream or as an offchain message. |
29- /// | - The private log stream is handled by the Aztec protocol, is submitted to L1 blobs and consumes DA. |
30- /// | - The offchain message mechanism is implemented by the app and hence is not expected to consume DA |
31- /// | (imagine an app submitting all the ciphertext to cloud storage). |
32- /// +--------------------------------------------------------------------------------------------------------+
27+ /// For on-chain delivery, we must also consider:
3328///
34- /// +--------------------------------------------------------------------------------------------------------+
35- /// | 3. Constrained or unconstrained tagging |
36- /// | - Tagging is an indexing mechanism that enables recipients to locate private logs in the system. When |
37- /// | tagging is unconstrained, there is not a cryptographic guarantee about it being performed correctly. |
38- /// | This may prevent recipients from successfully discovering their messages. Therefore, unconstrained |
39- /// | tagging should only be used in scenarios where the recipient is trusted or has clear incentives to |
40- /// | ensure proper message delivery. |
41- /// | - Tagging is not used in the offchain message mechanism. |
42- /// +--------------------------------------------------------------------------------------------------------+
29+ /// +---------------------------------------------------------------------------------------------------------- +
30+ /// | 2. Message Encryption and Tagging |
31+ /// | - Messages can use either constrained or unconstrained encryption |
32+ /// | - Constrained encryption guarantees the ciphertext is formed correctly but costs more in constraints, |
33+ /// | which results in slower proving times |
34+ /// | - Unconstrained encryption trusts the sender but is cheaper constraint-wise and hence faster to prove |
35+ /// | - Tagging is an indexing mechanism that helps recipients locate their messages |
36+ /// | - If tagging is not performed correctly by the sender, the recipient will not be able to find the message |
37+ /// +---------------------------------------------------------------------------------------------------------- +
4338///
39+ /// For off-chain delivery, constrained encryption is not relevant since it doesn't provide any additional guarantees
40+ /// over unconstrained encryption and is slower to prove (requiring more constraints).
4441///
45- /// # Message Delivery Variants and Their Use Cases
46- ///
47- /// The following section outlines the recommended delivery variants and when to use each one.
48- /// Each variant represents a different tradeoff between security guarantees, gas costs, and trust
49- /// assumptions.
50- ///
51- /// We are currently still exploring the design space but it seems that there are only 2 meaningful
52- /// combinations:
53- ///
54- /// +--------------------------------------------------------------------------------------------------------+
55- /// | 1. Constrained encryption, constrained tagging, private log stream |
56- /// | |
57- /// | This combination gives us an on-chain guarantee that a recipient is able to discover, receive and |
58- /// | decrypt a message. This is to be used when a smart contract (rather than a person or some offchain |
59- /// | system) needs to make decisions based on the message. For example, consider a contract that escrows a |
60- /// | privately-stored NFT (i.e. an NFT represented by a note) and releases it to a buyer only after |
61- /// | receiving a payment in a specific token. Without on-chain delivery and guaranteed discoverability |
62- /// | afforded by constrained tagging and encryption, the buyer could potentially obtain the NFT without |
63- /// | sending a valid payment message (i.e. the token note hash preimage) to the seller, rugging the seller. |
64- /// | |
65- /// | (To clarify the above, while the malicious buyer's payment token would still be deducted from their |
66- /// | balance, they would obtain the NFT while the seller would be unable to spend the payment token, |
67- /// | keeping the payment token note in limbo.) |
68- /// +--------------------------------------------------------------------------------------------------------+
69- ///
70- /// +--------------------------------------------------------------------------------------------------------+
71- /// | 2. Unconstrained encryption, offchain message |
72- /// | |
73- /// | This combination is useful when we either trust the sender to behave or the sender is incentivized to |
74- /// | deliver the message. To give you an example let's consider a payment app. When you are buying |
75- /// | groceries, the merchant can consider the payment successful once he receives the payment message, can |
76- /// | successfully decrypt it and see that its contents correspond to a valid token note. |
77- /// +--------------------------------------------------------------------------------------------------------+
78- ///
79- ///
80- /// Other combinations like unconstrained encryption, unconstrained tagging, private log stream don't seem
81- /// to be meaningful because they are costlier than combination 2 above while providing no meaningful
82- /// additional guarantees.
42+ /// There are three available delivery modes described below.
8343pub struct MessageDeliveryEnum {
84- /// Constrained encryption + constrained tagging + private log stream
44+ /// 1. Constrained On-chain
45+ /// - Uses constrained encryption and in the future constrained tagging (issue #14565) with on-chain delivery
46+ /// - Provides cryptographic guarantees that recipients can discover and decrypt messages (once #14565 is tackled)
47+ /// - Slowest proving times since encryption is constrained
48+ /// - Expensive since it consumes L1 blob space
49+ /// - Use when smart contracts need to make decisions based on message contents
50+ /// - Example 1: An escrow contract facilitating a private NFT sale that needs to verify payment before releasing
51+ /// the NFT to the buyer.
52+ /// - Example 2: An application with private configuration where changes must be broadcast to all participants.
53+ /// This ensures every user can access the latest configuration. Without notification of config changes,
54+ /// users would be unable to read updated variables and therefore blocked from using the application's
55+ /// functions. This pattern applies to all critical events that require universal broadcast.
8556 ///
86- /// This gives us an on-chain guarantee that a recipient is able to discover and receive a message. See
87- /// combination 1 above for details.
57+ /// Safety: Despite being called CONSTRAINED_ONCHAIN, this delivery mode is currently NOT fully constrained.
58+ /// The tag prefixing is unconstrained, meaning a malicious sender could manipulate the tag to prevent
59+ /// recipient decryption. TODO(#14565): Implement proper constrained tag prefixing.
8860 pub CONSTRAINED_ONCHAIN : u8 ,
8961
90- /// Unconstrained encryption + unconstrained tagging + private log stream
91- ///
92- /// As mentioned above, this combination is not meaningful but we keep it here as it's currently used in the
93- /// codebase.
94- /// TODO: Consider dropping this.
62+ /// 2. Unconstrained On-chain
63+ /// - Uses unconstrained encryption and tagging with on-chain delivery
64+ /// - Faster proving times since no constraints are used for encryption
65+ /// - Expensive since it consumes L1 blob space
66+ /// - Suitable when recipients can verify message validity through other means
67+ /// - Use this if you don't need the cryptographic guarantees of constrained encryption and tagging but
68+ /// don't want to deal with setting up out-of-band delivery infrastructure as required by mode 3
69+ /// - Example: Depositing a privately-held NFT into an NFT-sale escrow contract. The buyers know the escrow
70+ /// contract's decryption keys, they receive the message on-chain and are willing to buy the NFT only if the NFT
71+ /// contained in the message is legitimate.
9572 pub UNCONSTRAINED_ONCHAIN : u8 ,
9673
97- /// Unconstrained encryption + offchain message
98- ///
99- /// Useful when we trust the sender or the sender is incentivized to deliver the message. See combination 2
100- /// above for details.
74+ /// 3. Out-of-band
75+ /// - Uses unconstrained encryption with off-chain delivery
76+ /// - Lowest cost since no on-chain storage is needed and short proving times since no constraints are used
77+ /// for encryption
78+ /// - Suitable when recipients can verify message validity through other means
79+ /// - Requires setting up custom infrastructure for handling off-chain delivery (e.g. cloud storage)
80+ /// - Example: A payment app where a merchant receives the message off-chain and is willing to release the goods
81+ /// once he verifies that the payment is correct (i.e. can decrypt the message and verify that it contains
82+ /// a legitimate token note - note with note commitment in the note hash tree).
10183 pub UNCONSTRAINED_OFFCHAIN : u8 ,
10284}
10385
@@ -157,9 +139,7 @@ where
157139 // oracle which we don't use for anything besides its side effects, therefore this is safe to call.
158140 unsafe { emit_offchain_message (ciphertext , recipient ) };
159141 } else {
160- // Safety: Despite being called CONSTRAINED_ONCHAIN, this delivery mode is currently NOT fully constrained.
161- // The tag prefixing is unconstrained, meaning a malicious sender could manipulate the tag to prevent
162- // recipient decryption. This is a significant security risk that needs to be addressed.
142+ // Safety: Currently unsafe. See description of CONSTRAINED_ONCHAIN in MessageDeliveryEnum.
163143 // TODO(#14565): Implement proper constrained tag prefixing to make this truly CONSTRAINED_ONCHAIN
164144 let log_content = prefix_with_tag (ciphertext , recipient );
165145
0 commit comments