# LNPBP-8: Single-use-seals

```
LNPBP: 0008
Vertical: Cryptographic primitives
Title: Single-use-seals
Author: Peter Todd
Comments-URI: https://github.com/LNP-BP/lnpbps/issues/117
Status: Proposal
Type: Standards Track
Created: 2017-12-05
Finalized: 2021-11-16
Based on: https://petertodd.org/2017/scalable-single-use-seal-asset-transfer
License: CC0-1.0
```

* [Abstract](#abstract)
* [Background](#background)
* [Motivation](#motivation)
* [Design](#design)
* [Specification](#specification)
* [Trust](#trust)
* [Reference implementation](#reference-implementation)
* [References](#references)
* [Copyright](#copyright)

### Abstract

A single-use-seal is an abstract mechanism to prevent double-spends. The current proposal defines core single-use-seal terminology and procedures which must be supported and implemented according to this guidelines by any specific single-use-seal implementation.

### Background

Concept of single-use-seal was developed as a result of research work on cryptographic commitments, consensus protocols in distributed systems and client-side-validation \[1, 2, 3, 4].

### Motivation

Existing cryptographic commitment primitives does not allow to create "two-level" commitments, whether at initial stage a commiter commits to commit to a certain (potentially yet unknown) message in the future, once and only once. Given a trustless way of performing verification of such commitments the primitive may be a basic building block for creating decentralized, private and censorship-resistant state machines and smart contracting systems which will be protected from "double-spend" attacks.

### Design

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.

### Specification

For a given data structure $l$ providing *single-use-seal definition* and a *messag*e $m$ single-use-seal implementation MUST support two fundamental operations:

* *Close seal* $l$ over *message* $m$, producing a *witness* $w\_l$:

  `Close(`$l$,$m$`)`→$w\_l$
* *Verify* that the *seal* $l$ was closed over *message* $m$:

  `Verify(`$l$,$w\_l$,$m$`)`→`bool`

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. Secondly, authentication is generally useful. Thus we have:

* *Generate* a new seal bound to pubkey p:

  `Gen(`$p$`)`→$l$
* *Close seal* $l$ over *message* $m$, authenticated by signature $s$ valid for pubkey $p$:

  `Close(`$l$,$m$,$s$`)`→$w\_l$

  Obviously, in the above, pubkey can be replaced by any cryptographic identity scheme, such as a Bitcoin-style predicate script, zero-knowledge proof, etc.
* Finally, while some single-use-seal implementations MAY support the ability to prove that a seal is open, e.g. as of a given block height or point in time. This however is optional, and as it can be difficult to implement, it is suggested that seal-using protocols SHOULD avoid depending on this functionality existing.

### Trust

An obvious single-use-seal implementation is to simply have a trusted notary, with each seal committing to that notary’s identity, and witnesses being cryptographic signatures produced by that notary. A further obvious refinement is to use disposable keys, with a unique private key being generated by the notary for each seal, and the private key being securely destroyed when the seal is closed.

For a scalable, trust-minimized, single-use-seal implementation we can use a proof-of-publication ledger, where consensus over the state of the ledger is achieved in a trust-minimized manner (i.e. Bitcoin blockchain).

### Reference implementation

The reference implementation is version `1.0` of [`single_use_seals` crate](https://github.com/LNP-BP/LNPBPs/blob/master/single_use_seals/README.md), which is a part of the [client-side-validation library](https://github.com/LNP-BP/LNPBPs/blob/master/client_side_validation/README.md) developed and maintained Dr Maxim Orlovsky at LNP/BP Strandards Association.

If the implementation differs from the spec, the spec has a higher priority.

### References

1. Peter Todd. Preventing Consensus Fraud with Commitments and Single-Use-Seals <https://petertodd.org/2016/commitments-and-single-use-seals>
2. Peter Todd. Scalable Semi-Trustless Asset Transfer via Single-Use-Seals and Proof-of-Publication. <https://petertodd.org/2017/scalable-single-use-seal-asset-transfer>
3. Peter Todd. Closed Seal Sets and Truth Lists for Better Privacy and Censorship Resistance. <https://petertodd.org/2016/closed-seal-sets-and-truth-lists-for-privacy>
4. Peter Todd. Building Blocks of the State Machine Approach to Consensus. <https://petertodd.org/2016/state-machine-consensus-building-blocks>

### Copyright

This document is licensed under the Creative Commons CC0 1.0 Universal license.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://standards.lnp-bp.org/commitment-schemes/lnpbp-0008.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
