1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// LNP/BP client-side-validation foundation libraries implementing LNPBP
// specifications & standards (LNPBP-4, 7, 8, 9, 42, 81)
//
// Written in 2019-2022 by
// Dr. Maxim Orlovsky <orlovsky@pandoracore.com>
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the Apache 2.0 License along with this
// software. If not, see <https://opensource.org/licenses/Apache-2.0>.
//! Convolved commitments (convolve-commit-verify scheme).
use crate VerifyEq;
use crate::;
/// Proof type used by [`ConvolveCommitVerify`] protocol.
/// Trait for *convolve-commit-verify scheme*, where some data structure (named
/// *container*) may commit to existing *message* using *supplement* and
/// producing final *commitment* value. The commitment can't be used to restore
/// original message, however the fact of the commitment may be
/// deterministically *verified* when the message and the supplement (now acting
/// as a *proof*) proof are *revealed*.
///
/// In other words, *convolve-commit* takes an object (`self`), a *supplement*,
/// convolves them in certain way together and than uses the result to produce a
/// commitment to a *message* and a *proof*:
/// - `self + supplement -> internal_repr`;
/// - `internal_repr + msg -> (commitment, proof)`.
/// Later on, a verifier presented with a message and the proof may do the
/// commitment verification in the following way:
/// `msg, proof, commitment -> bool`.
///
/// To use *convolve-commit-verify scheme* one needs to implement this trait for
/// a data structure acting as a container for a specific commitment under
/// certain protocol, specified as generic parameters. The container type must
/// specify commitment types as associated type [`Self::Commitment`]. The
/// commitment type in certain cases may be equal to the original container
/// type; when the commitment represents internally modified container.
///
/// The difference between *convolve-commit-verify* and *embed-commit-verify*
/// schemes is in the fact that unlike embed-commit, convolve-commit does not
/// produce a proof external to the commitment, but instead requires additional
/// immutable supplement information which is not a part of the container
/// converted into the commitment. As an example one may consider procedures of
/// homomorphic public key tweaking with the hash of the message, which is
/// a case of embed-commit procedure, producing original public key as a proof
/// and tweaked public key as a commitment -- and procedure of pay-to-contract
/// commitment in scriptPubkey of a transaction output, which requires
/// additional information about the public key or scripts present in the
/// scriptPubkey only in hashed form (this is *supplement*), and producing just
/// a modified version of the scriptPubkey (commitment) without any additional
/// proof data.
///
/// Operations with *convolve-commit-verify scheme* may be represented in form
/// of `ConvolveCommit: (Container, Supplement, Message) -> Commitment` (see
/// [`Self::convolve_commit`] and
/// `Verify: (Container', Supplement, Message) -> bool` (see
/// [`ConvolveCommitProof::verify`]).
///
/// This trait is heavily used in **deterministic bitcoin commitments**.
///
/// # Protocol definition
///
/// Generic parameter `Protocol` provides context & configuration for commitment
/// scheme protocol used for this container type.
///
/// Introduction of this generic allows to:
/// - implement trait for foreign data types;
/// - add multiple implementations under different commitment protocols to the
/// combination of the same message and container type (each of each will have
/// its own `Proof` type defined as an associated generic).
///
/// Usually represents an uninstantiable type, but may be a structure
/// containing commitment protocol configuration or context objects.
///
/// ```
/// # use bitcoin_hashes::sha256::Midstate;
/// # use lnpbp_secp256k1zkp::Secp256k1;
/// # use commit_verify::CommitmentProtocol;
///
/// // Uninstantiable type
/// pub enum Lnpbp6 {}
///
/// impl CommitmentProtocol for Lnpbp6 {
/// const HASH_TAG_MIDSTATE: Option<Midstate> = Some(Midstate(
/// [0u8; 32], // replace with the actual midstate constant
/// ));
/// }
///
/// // Protocol definition containing context object
/// pub struct Lnpbp1 {
/// pub secp: Secp256k1,
/// }
/// // ...
/// ```