Files
nutshell/docs/specs/00.md
2023-01-14 19:43:29 +01:00

5.7 KiB

NUT-0 - Notation and Models

Sending user: Alice Receiving user: Carol Mint: Bob

Bob (mint)

  • k private key of mint (one for each amount)
  • K public key of mint
  • Q promise (blinded signature)

Alice (user)

  • x random string (secret message), corresponds to point Y on curve
  • r private key (blinding factor)
  • T blinded message
  • Z proof (unblinded signature)

Blind Diffie-Hellmann key exchange (BDHKE)

  • Mint Bob publishes K = kG
  • Alice picks secret x and computes Y = hash_to_curve(x)
  • Alice sends to Bob: T = Y + rG with r being a random nonce
  • Bob sends back to Alice blinded key: Q = kT (these two steps are the DH key exchange)
  • Alice can calculate the unblinded key as Q - rK = kY + krG - krG = kY = Z
  • Alice can take the pair (x, Z) as a token and can send it to Carol.
  • Carol can send (x, Z) to Bob who then checks that k*hash_to_curve(x) == Z, and if so treats it as a valid spend of a token, adding x to the list of spent secrets.

0.1 - Models

BlindedMessage

An encrypted ("blinded") secret and an amount sent from Alice to Bob.

Alice sends this to Bob when she mints tokens. amount is the value of the requested token and B_ is the encrypted secret message generated by Alice.

{
	"amount": int,
	"B_": str
}

BlindedSignature

A signature on the BlindedMessage sent from Bob to Alice.

Bob sends this to Alice when she mints tokens. 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][02] of the mint public keys that signed the token.

{
	"amount": int,
	"C_": str,
	"id": str | None
}

Proof

A Proof is also called a Token in its serialized form. Alice sends the serialized to Carol to initiate a payment. Upon receiving the token, Carol deserializes it and requests a split from Bob to exchange it for new BlindedSignature's. Carol sends the Proof to Bob together with new BlindedMessage's that she wants to have signed.

amount is the value of the Proof, secret is the secret message, C is the unblinded signature on secret, id is the [keyset id][02] of the mint public keys that signed the token. script is a P2SHScript that specifies the spending condition for this Proof [TODO: P2SH documentation].

{
	"amount": int, 
	"secret": str,
	"C": str,
	"id": None | str,
	"script": P2SHScript | None,
}

Proofs

An array (list) of Proof's. In general, this will be used for most operations instead of a single Proof. Proofs can be serialized (see Methods/Serialization [TODO: Link Serialization])

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==