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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
// LNP/BP Core Library implementing LNPBP specifications & standards
// Written in 2020 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 MIT License
// along with this software.
// If not, see <https://opensource.org/licenses/MIT>.
//
// The author of the code acknowledges significant input from Peter Todd,
// who is the author of single-use-seal concept and who spent a lot of his time
// to help to understanding single-use-seal concept and write the current
// implementation.
//! # Single-use-seals
//!
//! Set of traits that allow to implement Peter's Todd **single-use seal**
//! paradigm. Information in this file partially contains extracts from Peter's
//! works listed in "Further reading" section.
//!
//! ## Single-use-seal definition
//!
//! Analogous to the real-world, physical, single-use-seals used to secure
//! shipping containers, a single-use-seal primitive is a unique object that can
//! be closed over a message exactly once. In short, a single-use-seal is an
//! abstract mechanism to prevent double-spends.
//!
//! A single-use-seal implementation supports two fundamental operations:
//! * `Close(l,m) → w` — Close seal l over message m, producing a witness `w`.
//! * `Verify(l,w,m) → bool` — Verify that the seal l was closed over message
//! `m`.
//!
//! A single-use-seal implementation is secure if it is impossible for an
//! attacker to cause the Verify function to return true for two distinct
//! messages m1, m2, when applied to the same seal (it is acceptable, although
//! non-ideal, for there to exist multiple witnesses for the same seal/message
//! pair).
//!
//! Practical single-use-seal implementations will also obviously require some
//! way of generating new single-use-seals:
//! * `Gen(p)→l` — Generate a new seal basing on some seal definition data `p`.
//!
//! ## Terminology
//!
//! **Single-use-seal**: a commitment to commit to some (potentially unknown)
//! message. The first commitment (i.e. single-use-seal) must be a
//! well-defined (i.e. fully specified and unequally identifiable
//! in some space, like in time/plance or within a given formal informational
//! system).
//! **Closing of a single-use-seal over message**: a fulfilment of the first
//! commitment: creation of the actual commitment to some message in a form
//! unequally defined by the seal.
//! **Witness**: data produced with closing of a single use seal which are
//! required and sufficient for an independent party to verify that the seal
//! was indeed closed over a given message (i.e. the commitment to the message
//! had being created according to the seal definition).
//!
//! NB: It's important to note, that while its possible to deterministically
//! define was a given seal closed it yet may be not possible to find out
//! if the seal is open; i.e. seal status may be either "closed over message"
//! or "unknown". Some specific implementations of single-use-seals may define
//! procedure to deterministically prove that a given seal is not closed (i.e.
//! opened), however this is not a part of the specification and we should
//! not rely on the existence of such possibility in all cases.
//!
//! ## Trait structure
//!
//! The module defines trait [SingleUseSeal] that can be used for implementation
//! of single-use-seals with methods for seal close and verification. A type
//! implementing this trait operates only with messages (which is represented
//! by [Message] type alias – in fact any type that implements `AsRef<[u8]>`,
//! i.e. can be represented as a sequence of bytes) and witnesses (which is
//! represented by an associated type [SingleUseSeal::Witness]). At the same
//! time, [SingleUseSeal] can't define seals by itself — and also knows nothing
//! about whether the seal is in fact closed: this requires a "seal medium": a
//! proof of publication medium on which the seals are defined.
//!
//! The module provides two options of implementing sch medium: synchonous
//! [SealMedium] and asynchronous [AsyncSealMedium].
//!
//! ## Sample implementation
//!
//! Examples of implementations can be found in [bp::seals][crate::bp::seals]
//! module of the crate source code.
//!
//! ## Further reading
//!
//! * Peter Todd. Preventing Consensus Fraud with Commitments and
//! Single-Use-Seals.
//! <https://petertodd.org/2016/commitments-and-single-use-seals>.
//! * Peter Todd. Scalable Semi-Trustless Asset Transfer via Single-Use-Seals
//! and Proof-of-Publication. 1. Single-Use-Seal Definition.
//! <https://petertodd.org/2017/scalable-single-use-seal-asset-transfer>
/// Message type that can be used to close the seal over it
pub type Message = dyn ;
/// Single-use-seal trait: implement for a data structure that will hold a
/// single-use-seal definition and will contain a business logic for closing
/// seal over some message and verification of the seal against the message
/// and witness.
///
/// NB: It is recommended that single-use-seal instances to be instantiated
/// not by a constructor, but by a factory, i.e. "seal medium": data type
/// implementing either [SealMedium] or [AsyncSealMedium] traits.
/// Trait for proof-of-publication medium on which the seals are defined and
/// which can be used for convenience operations related to seals:
/// * finding out the seal status
/// * publishing witness information
/// * get some identifier on the exact place of the witness publication
/// * check validity of the witness publication identifier
///
/// Since the medium may require network communications or extensive computing
/// involved (like in case with blockchain) there is a special asynchronous
/// version of the SealMedium [AsyncSealMedium], which requires use of
/// `async` feature of this crate.
///
/// All these operations are medium-specific; for the same single-use-seal type
/// they may differ when are applied to different proof of publication mediums.
///
/// To read more on proof-of-publication please check
/// <https://petertodd.org/2014/setting-the-record-proof-of-publication>
/// Asynchronous version of the [SealMedium] trait.
/// Single-use-seal status returned by [SealMedium::get_seal_status] and
/// [AsyncSealMedium::get_seal_status] functions.
///
/// NB: It's important to note, that while its possible to deterministically
/// define was a given seal closed it yet may be not possible to find out
/// if the seal is open without provision of the message and witness; i.e.
/// seal status may be either "closed over message"
/// or "unknown". Some specific implementations of single-use-seals may define
/// procedure to deterministically prove that a given seal is not closed (i.e.
/// opened), however this is not a part of the specification and we should
/// not rely on the existence of such possibility in all cases.
/// Error returned by [SealMedium] and [AsyncSealMedium] functions related
/// to work with publication id ([SealMedium::PublicationId]). Required since
/// not all implementation of [SealMedia] may define publication identifier,
/// and the traits provide default implementation for these functions always
/// returning [SealMediumError::OperationNotSupported]. If the implementation
/// would like to provide custom implementation, it may embed standard error
/// related to [SealMedium] operations within
/// [SealMediumError::MediumAccessError] case; the type of MediumAccessError is
/// defined through generic argument to [SealMediumError].