Skip to content

Instantly share code, notes, and snippets.

@DavidBurkett
Last active November 5, 2021 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DavidBurkett/ba41f314b12566987dc9ba3534c6c773 to your computer and use it in GitHub Desktop.
Save DavidBurkett/ba41f314b12566987dc9ba3534c6c773 to your computer and use it in GitHub Desktop.

1. Design

1.1 Stealth Addresses

A stealth address is a pair (A = a*G, B = b*G) where A is the scan key and B the spend key. Additional subaddress support is described here.

1.2 Transaction Structure

A transaction consists of:

1.2.1 Outputs

A list of outputs: tuples of the form (C, π, v', n', Ks, Kr, Ke, ρ) associated to an output address (A, B) composed of:

  • an ephemeral key Ks = ks*G, chosen by the sender
  • a receiver public key Kr = kr*G whose private key is known only by the receiver
  • A key exchange public key Ke = sB = sb*G, where s can be calculated by sender and receiver, but b is known only by the receiver
  • a masked value v' which is the value v encrypted by a shared secret t
  • a masked nonce n' which is a one-time nonce n encrypted by a shared secret t
  • a coin C = v*H + q*G for its value v, the opening q of the coin is shared between the sender and recipient of the coin (see 2.3)
  • a rangeproof π that attests that C is a commitment to a value v < v_max and also commits to a message (v'||n'||Ks||Kr||Ke||ρ)
  • a signature ρ, valid under verification key Ks and message (v'||n'||Ks||Kr||Ke)

Section 2.3.1 describes the calculation of n, s, t, and q.

1.2.2 Inputs

A list of inputs. An input is just a signature σ under some verification key Kr referencing a previously unspent output.

1.2.3 Kernels

A kernel, which is composed of:

  • the supply s, indicating the money created in the transaction
  • the fee f, indicating the fee paid for the transaction
  • the excess E = (ΣC + f*H) - (ΣC' + t*G) where t is the transaction's kernel offset
  • a signature ψ, valid under verification key E and message (s||f)

1.2.4 Kernel offset

The kernel offset t is a randomly generated scalar which is used to prevent deaggregation of a transaction.

1.2.5 Stealth Excess

Each kernel could have an associated stealth excess (prunable beyond horizon), which is composed of:

  • a reference to a kernel in the transaction: λ = (s||f||E||ψ)
  • stealth excess E' = e'*G where e' is randomly generated
  • a signature φ, valid under verification key E' and message λ

1.2.6 Offsets

A transaction must also have 2 associated offsets(scalars), easily summed when aggregating transactions:

  • a kernel offset t = (Σks - Σkr) - Σe
  • a stealth offset t' = (Σks - Σkr) - Σe'

1.3 Transaction Creation

1.3.1 Output Creation

To create an output for value v to a receiver's stealth address pair (A, B), the sender must:

  1. Randomly generate the sender's keypair (ks, Ks)
  2. Derive the nonce n = HASH16(T_NONCE||ks)
  3. Derive the sending key s = HASH32(T_SEND||A||B||v||n)
  4. Derive the shared secret t = HASH32(T_DERIVE||s*A)
  5. Compute the receiver's one-time public key Kr = B + HASH32(T_RECEIVE||t)*G
  6. Compute the key exchange public key Ke = s*B
  7. Encrypt the value v' = v ^ HASH8(T_VMASK, t)
  8. Encrypt the nonce n' = n ^ HASH16(T_NMASK, t)
  9. Generate the signature ρ for message (v'||n'||Ks||Kr||Ke) using the sender's key ks
  10. Compute the commitment C = v*H + q*G where q = HASH32(T_BLIND, t)
  11. Generate the rangeproof π, proving v < v_max, while also committing to the message (v'||n'||Ks||Kr||Ke||ρ)

1.3.2 Input Creation

Using the receiver private key (kr) of an unspent output, sign a message (message can be empty string).

1.3.3 Kernel & Offset

same as vanilla MW...need to document

1.3.4 Stealth Excess & Offset

similar to kernel...need to document

1.4 Aggregate Transactions

In the vanilla Mimblewimble protocol, the chain state can be aggregated into a single transaction with no inputs, all historical kernels, and all unspent outputs (the UTXO set).

With our proposal however, inputs are kept until they have been buried under a sufficient amount of PoW. In particular, we define a horizon height h for which all inputs & stealth excesses must be kept, and their signatures verified.

To aggregate multiple transactions together, create a new transaction with the combination of all inputs, all outputs, all kernels, all stealth excesses, and calculate:

  • kernel offset t_agg = Σt (mod p)
  • stealth offset t_agg' = Σt' (mod p)

1.5 Transaction Verification

A transaction (or aggregated transaction) is valid iff:

(1) all input signatures are valid signatures under verification key Kr of the corresponding UTXO
(2) all range proofs are valid, and commit to the associated output data (v'||n'||Ks||Kr||Ke||ρ)
(3) all output signatures ρ are valid under verification key Ks and message (v'||n'||Ks||Kr||Ke)
(4) all kernel signatures ψ are valid under verification key E and message (s||f)
(5) all stealth excess signatures φ are valid under verification key E' and message λ
(6) all kernels referenced (λ) by stealth excesses must be present in the transaction
(7) values are balanced: (ΣC + (Σf - Σs)*H) - ΣC' = ΣE + t*G
(8) stealth excesses are balanced: (ΣKs - ΣKr) = ΣE' + t'*G
(9) all inputs reference valid UTXOs

1.6 Cut-Through

While in vanilla MW, outputs could be cut-through as soon as a block spends them, or for unconfirmed transactions, before ever even being included in a block, our proposal explicitly prevents this.

Cut-through (pruning of spent outputs) does not occur until the spend has occured h blocks in the past (i.e. beyond the horizon). Without knowledge of ks, which only the sender (output originator) knows, neither receiver nor adversarial observer is able to cut-through an output while still balancing the stealth excess equation (8).




TODO

Would like to Discuss:

  • Transaction Malleability
  • Consequences of leaking stealth offset t' (Σks - Σkr) in a 1-1 transaction
    • NOTE: LTC's MWEB currently always creates a change output, even if zero-valued, to avoid this and other issues
  • Replay Attacks
    • The best solution I could come up with is to have the inputs include an additional "epoch" field, which is basically an acceptable height range.
  • Receiver Public Key (Kr) reuse
    • Aside from the obvious privacy leak, could this be used to somehow learn kr?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment