5.9 KiB
NUT-0: Notation and Models
Sending user: Alice
Receiving user: Carol
Mint: Bob
Bob (mint)
kprivate key of mint (one for each amount)Kpublic key of mintQpromise (blinded signature)
Alice (user)
xrandom string (secret message), corresponds to pointYon curverprivate key (blinding factor)Tblinded messageZproof (unblinded signature)
Blind Diffie-Hellmann key exchange (BDHKE)
- Mint
BobpublishesK = kG Alicepicks secretxand computesY = hash_to_curve(x)Alicesends toBob:T = Y + rGwithrbeing a random nonce (blinding)Bobsends back toAliceblinded key:Q = kT(these two steps are the DH key exchange) (signing)Alicecan calculate the unblinded key asQ - rK = kY + krG - krG = kY = Z(unblinding)- Alice can take the pair
(x, Z)as a token and can send it toCarol. Carolcan send(x, Z)toBobwho then checks thatk*hash_to_curve(x) == Z(verification), and if so treats it as a valid spend of a token, addingxto the list of spent secrets.
0.1 - Models
BlindedMessage
An encrypted ("blinded") secret and an amount is sent from Alice to Bob for minting tokens or for splitting tokens. A BlindedMessage is also called an output.
{
"amount": int,
"B_": str
}
amount is the value of the requested token and B_ is the encrypted secret message generated by Alice.
BlindedSignature
A signature on the BlindedMessage is sent from Bob to Alice after minting tokens or after splitting tokens. A BlindedSignature is also called a promise.
{
"amount": int,
"C_": str,
"id": str | None
}
amount is the value of the blinded token, C_ is the blinded signature on the secret message B_ sent in the previous step. id is the keyset id of the mint public keys that signed the token.
Proof
A Proof is sent to Bob for melting tokens. A Proof can also be sent from Alice to Carol for which it is first can be serialized. Upon receiving the token, Carol deserializes it and requests a split from Bob to receive new tokens.
{
"amount": int,
"secret": str,
"C": str,
"id": None | str,
"script": P2SHScript | None,
}
amount is the value of the Proof, secret is the secret message, C is the unblinded signature on secret, id is the keyset id of the mint public keys that signed the token. script is a P2SHScript that specifies the spending condition for this Proof [TODO: P2SH documentation].
Proofs
An array (list) of Proof's. In general, this will be used for most operations instead of a single Proof. Proofs must be serialized before sending between wallets (see Serialization of proofs).
0.2 - Methods
Serialization of Proofs
To send and receive Proofs, wallets serialize them in a base64_urlsafe format. There are two versions of the serialization format.
0.2.1 - V1 tokens
This token format is a list of Proofs. Each Proof contains the keyset id in the field id that can be used by a wallet to identify the mint of this token. A wallet that encounters an unknown id, it CAN ask the user to enter the mint url of this yet unknown mint. The wallet SHOULD explicity ask the user whether they trust the mint.
Example JSON:
[
{
"id": "DSAl9nvvyfva",
"amount": 8,
"secret": "DbRKIya0etdwI5sFAN0AXQ",
"C": "02df7f2fc29631b71a1db11c163b0b1cb40444aa2b3d253d43b68d77a72ed2d625"
},
{
"id": "DSAl9nvvyfva",
"amount": 16,
"secret": "d_PPc5KpuAB2M60WYAW5-Q",
"C": "0270e0a37f7a0b21eab43af751dd3c03f61f04c626c0448f603f1d1f5ae5a7d7e6"
}
]
When serialized, this becomes:
W3siaWQiOiAiRFNBbDludnZ5ZnZhIiwgImFtb3VudCI6IDgsICJzZWNyZXQiOiAiRGJSS0l5YTBldGR3STVzRkFOMEFYUSIsICJDIjogIjAyZGY3ZjJmYzI5NjMxYjcxYTFkYjExYzE2M2IwYjFjYjQwNDQ0YWEyYjNkMjUzZDQzYjY4ZDc3YTcyZWQyZDYyNSJ9LCB7ImlkIjogIkRTQWw5bnZ2eWZ2YSIsICJhbW91bnQiOiAxNiwgInNlY3JldCI6ICJkX1BQYzVLcHVBQjJNNjBXWUFXNS1RIiwgIkMiOiAiMDI3MGUwYTM3ZjdhMGIyMWVhYjQzYWY3NTFkZDNjMDNmNjFmMDRjNjI2YzA0NDhmNjAzZjFkMWY1YWU1YTdkN2U2In1d
0.2.2 - V2 tokens
This token format includes information about the mint as well. The field proofs is like a V1 token. Additionally, the field mints can include a list of multiple mints from which the proofs are from. The url field is the URL of the mint. ks is a list of the keyset IDs belonging to this mint. All keyset IDs of the proofs must be present here to allow a wallet to map each proof to a mint.
Example JSON:
{
"proofs": [
{
"id": "DSAl9nvvyfva",
"amount": 2,
"secret": "bdYCbHGONundLeYvv1P5dQ",
"C": "02e6117fb1b1633a8c1657ed34ab25ecf8d4974091179c4773ec59f85f4e3991cf"
},
{
"id": "DSAl9nvvyfva",
"amount": 8,
"secret": "KxyUPt5Mur_-RV8pCECJ6A",
"C": "03b9dcdb7f195e07218b95b7c2dadc8289159fc44047439830f765b8c50bfb6bda"
}
],
"mints": {
"MINT_NAME": {
"url": "http://server.host:3339",
"ks": ["DSAl9nvvyfva"]
}
}
}
When serialized, this becomes:
eyJwcm9vZnMiOlt7ImlkIjoiRFNBbDludnZ5ZnZhIiwiYW1vdW50IjoyLCJzZWNyZXQiOiJiZFlDYkhHT051bmRMZVl2djFQNWRRIiwiQyI6IjAyZTYxMTdmYjFiMTYzM2E4YzE2NTdlZDM0YWIyNWVjZjhkNDk3NDA5MTE3OWM0NzczZWM1OWY4NWY0ZTM5OTFjZiJ9LHsiaWQiOiJEU0FsOW52dnlmdmEiLCJhbW91bnQiOjgsInNlY3JldCI6Ikt4eVVQdDVNdXJfLVJWOHBDRUNKNkEiLCJDIjoiMDNiOWRjZGI3ZjE5NWUwNzIxOGI5NWI3YzJkYWRjODI4OTE1OWZjNDQwNDc0Mzk4MzBmNzY1YjhjNTBiZmI2YmRhIn1dLCJtaW50cyI6eyJNSU5UX05BTUUiOnsidXJsIjoiaHR0cDovL3NlcnZlci5ob3N0OjMzMzkiLCJrcyI6WyJEU0FsOW52dnlmdmEiXX19fQ==