-
Notifications
You must be signed in to change notification settings - Fork 46
Standard Simplicity Script Pubkey
The disassembled DAG of the standard Simplicity program for a single public key looks as follows.
let e0 = Word <32-byte x-only-public-key> -- : π β’ π^256 let e1 = iden -- : π^256 Γ π β’ π^256 Γ π let e2 = Jet sigAllHash -- : π β’ π^256 let e3 = disconnect e1 e2 -- : π β’ π^256 Γ π^256 let e4 = pair e0 e3 -- : π β’ π^256 Γ π^512 let e5 = witness <64-byte BIP-0340-signature> -- : π β’ π^512 let e6 = pair e4 e5 -- : π β’ (π^256 Γ π^512) Γ π^512 let e7 = Jet checkSigVerify -- : (π^256 Γ π^512) Γ π^512 β’ π in comp e6 e7 -- : π β’ π
For each subexpression above we have a comment showing the inferred type of every subexpression.
Letβs go through this program line by line.
let e0 = Word <32-byte x-only-public-key> -- : π β’ π^256
This expression is a constant function that outputs the userβs 256-bit public key.
This will be the first component of the data that will be passed to the checkSigVerify
jet in e7
.
let e1 = iden -- : π^256 Γ π β’ π^256 Γ π
This expression is passed to disconnect
in e3
.
It receives the Commitment Merkle Root (CMR) of the hash mode expression (see e2
), and any other input to the disconnect
function.
In this example there is no other input, so we just have a unit type here.
Normally the purpose of this expression is to determine if the CMR is authorized.
However in this case we simply pass the CMR along when it will be included in the message generated by disconnect
in e3
.
let e2 = Jet sigAllHash -- : π β’ π^256
This is a jet that computes a transaction hash of all transaction data.
It is analogous to Bitcoin Scriptβs SIGHASH_ALL
digest, but differs in its exact implementation.
let e3 = disconnect e1 e2 -- : π β’ π^256 Γ π^256
This expression assemble the 512-bit message that will make up the second component of the data that will be passed to the checkSigVerify
jet in e7
.
The disconnect
combinator passes the CMR of e2
as an input to e1
, which in turn simply passes it back and it ends up as the first component of disconnect
βs output.
The second component of the output is the output of e2
itself, which is a 256-bit transaction digest.
The important property of disconnect
is that its CMR excludes e2
.
This means that the expression e2
is only decided at redemption time, and the user can replace the digest expression with any other transaction digest jet, or even make up their own digest expression themselves.
What ever expression winds up being used for e2
, its CMR necessarily becomes part of the signed message, and this cannot be altered (unless a new signature is generated).
let e4 = pair e0 e3 -- : π β’ π^256 Γ π^512
This expression pairs up the output of e0
, the userβs public key, with the 512-bit message generated by e3
.
let e5 = witness <64-byte BIP-0340-signature> -- : π β’ π^512
witness
expressions denote constant functions that output Simplicity values. In this example we output a 512-bit BIP-0340 signature value.
The key difference between witness
expressions and Word
expressions like in e0
is that the CMR of witness
excludes the witnessβs value. Similar to disconnect
, this means that the witnessβs value is not decided until redemption time.
Naturally signature values cannot be forged by third parties who do not know the private key corresponding to the fixed public key in e0
.
let e6 = pair e4 e5 -- : π β’ (π^256 Γ π^512) Γ π^512
This expression pairs up the output of e4
and e5
, creating a tuple with
- the userβs public key
- a 512-bit message consisting of the CMR of the chosen hash mode expression, and the output of that hash mode expression.
- a 512-bit BIP-0340 signature value.
let e7 = Jet checkSigVerify -- : (π^256 Γ π^512) Γ π^512 β’ π
This is jet that verifies a signature on a message with a given public key. The message is additionally tagged with a Simplicity signature application specific tag.
This jet has no output. It either succeeds or aborts. This allows this jet to be compatible with batch verification, allowing an implementation to optimistically succeed and continue, while validating the signature in batch at a later time.
in comp e6 e7 -- : π β’ π
The expression root simply composes e6
, which generates the public key, message and signature, with e7
which consumes them and validates the signature.
This expression has type π β’ π
which is the type that is required by all Simplicity programs.