mirror of
https://github.com/mimblewimble/grin.git
synced 2025-04-24 03:11:14 +03:00
Introduction to MimbleWimble and Grin
Documentation aimed at a technical audience, just requiring some basic knowledge of bitcoin, to explain how MimbleWimble works and how it's applied in Grin.
This commit is contained in:
parent
cb84f588fb
commit
95592d6624
1 changed files with 386 additions and 0 deletions
386
doc/intro.md
Normal file
386
doc/intro.md
Normal file
|
@ -0,0 +1,386 @@
|
|||
Introduction to MimbleWimble and Grin
|
||||
=====================================
|
||||
|
||||
MimbleWimble is a blockchain format and protocol that provides
|
||||
extremely good scalability, privacy and fungibility by relying on strong
|
||||
cryptographic primitives. It addresses gaps existing in almost all current
|
||||
blockchain implementations.
|
||||
|
||||
Grin is an open source software project that implements a MimbleWimble
|
||||
blockchain and fills the gaps required for a full blockchain and
|
||||
cryptocurrency deployment.
|
||||
|
||||
The main goal and characteristics of the Grin project are:
|
||||
|
||||
* Privacy as a default. This enables complete fungibility without precluding
|
||||
the possibility to ability to optionally disclose information as needed.
|
||||
* Scales with the number of users and not the number of transactions, with very
|
||||
large space savings compared to other blockchains.
|
||||
* Strong and proven cryptography. MimbleWimble only relies on Elliptic Curve
|
||||
Cryptography which has been tried and tested for decades.
|
||||
* Design simplicity that makes it easy to audit and maintain over time.
|
||||
* Community driven, using an asic-resistent mining algorithm (Cuckoo Cycles)
|
||||
encouraging mining decentralization.
|
||||
|
||||
# Tongue Tying for Everyone
|
||||
|
||||
This document is targeted at readers with a good
|
||||
understanding of blockchains and basic cryptography. With that in mind, we attempt
|
||||
to explain the technical buildup of MimbleWimble and how it's applied in Grin. We hope
|
||||
this document is understandable to most technically minded readers. Our objective is
|
||||
to encourage you to get interested in Grin and contribute in any way possible.
|
||||
|
||||
To achieve this objective, we will introduce the main concepts required for a good
|
||||
understanding of Grin as a MimbleWimble implementation. We will start with brief
|
||||
description of some relevant properties of Elliptic Curve Cryptography (ECC) to lay the
|
||||
foundation on which Grin is based and then describe all the key elements of a
|
||||
MimbleWimble blockchain's transactions and blocks.
|
||||
|
||||
## Tiny Bits of Elliptic Curves
|
||||
|
||||
We start with a brief primer on Elliptic Curve Cryptography, reviewing just the
|
||||
properties necessary to understand how MimbleWimble works and without
|
||||
delving too much into the intricacies of ECC. For readers who would want to
|
||||
dive deeper into those assumption, there are other opportunities to
|
||||
[learn more](http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/).
|
||||
|
||||
An Elliptic Curve for the purpose of cryptography is simply a large set of points that
|
||||
we will call _H_. On those points,
|
||||
the addition and multiplication operations have been defined, just like we know how
|
||||
to do additions and multiplications on numbers or vectors. Given a number _k_ and
|
||||
using the multiplication operation we can compute `k*H`, which is also a point on
|
||||
_H_. Given another number _j_ we can also calculate `(k+j)*H` which is equivalent
|
||||
to `k*H + j*H`. Given that the addition and multiplication operations on an elliptic
|
||||
curve maintain the commutative and associative properties of addition and
|
||||
multiplication:
|
||||
|
||||
(k+j)*H = k*H + j*H
|
||||
|
||||
In ECC, if we pick a very large number _k_ used as a private key, `k*H` is
|
||||
defined as the corresponding public key. Even if one knows the
|
||||
value of the public key `k*H`, deducing _k_ is close to impossible (or said
|
||||
differently, while multiplication is trivial, "division" is extremely difficult).
|
||||
|
||||
The previous formula `(k+j)*H = k*H + j*H`, with _k_ and _j_ both private
|
||||
keys, demonstrates that a public key obtained from the addition of two private
|
||||
keys (`(k+j)*H`) is identical to the addition of the public keys for each of those
|
||||
two private keys (`k*H + j*H`). In the Bitcoin blockchain, Hierarchical
|
||||
Deterministic wallets heavily rely on this principle. MimbleWimble and the Grin
|
||||
implementation do as well.
|
||||
|
||||
## Transacting with MimbleWimble
|
||||
|
||||
The structure of transactions demonstrate a crucial tenet of MimbleWimble:
|
||||
strong privacy and confidentiality guarantees.
|
||||
|
||||
The validation of MimbleWimble transactions rely on two basic properties:
|
||||
|
||||
* **Verification of zero sums.** The sum of outputs minus the inputs always equals zero,
|
||||
proving that the transaction did not create new funds, _without revealing the actual amounts_.
|
||||
* **Possession of private keys.** Like with most other cryptocurrencies, ownership of
|
||||
transaction outputs is guaranteed by the possession of ECC private keys. However,
|
||||
theproof that an entity own those private keys is not achieved by directly signing
|
||||
the transaction.
|
||||
|
||||
The next sections on balance, ownership, change and proofs details how those two
|
||||
fundamental properties are achieved.
|
||||
|
||||
### Balance
|
||||
|
||||
Building up on the properties of ECC we described above, one can obscure the values
|
||||
in a transaction.
|
||||
|
||||
If _v_ is the value of a transaction input or output and _G_ an ECC curve, we can simply
|
||||
embed `v*G` instead of _v_ in a transaction. This works because using the ECC
|
||||
operations, we can still validate that the sum of the outputs of a transaction equals the
|
||||
sum of inputs:
|
||||
|
||||
v1 + v2 = v3 => v1*G + v2*G = v3*G
|
||||
|
||||
Verifying this property on every transaction allows the protocol to verify that a
|
||||
transaction doesn't create money out of thin air, without knowing what the actual
|
||||
values are. However, there are a finite number of possible values and one could try every single
|
||||
one of them to guess the value of your transaction. In addition, knowing v1 (from
|
||||
a previous transaction for example) and the resulting `v1*G` reveals all outputs with
|
||||
value v1 across the blockchain. For these reasons, we introduce a second ECC curve
|
||||
_H_ and a private key _k_ used as a *blinding factor*.
|
||||
|
||||
An input or output value in a transaction can then be expressed as:
|
||||
|
||||
v*G + k*H
|
||||
|
||||
Where:
|
||||
|
||||
* _v_ is the value of an input or output and _G_ is an elliptical curve.
|
||||
* _k_ is a private key used as a blinding factor, _H_ is another elliptical curve and their product `k*H` is the public key for _k_ on _H_.
|
||||
|
||||
Neither _v_ nor _k_ can be deduced, leveraging the fundamental properties of Elliptic
|
||||
Curve Cryptography. `v*G + k*H` is called a _Pedersen Commitment_.
|
||||
|
||||
As a an example, let's assume we want to build a transaction with one input and two
|
||||
outputs. We have (ignoring fees):
|
||||
|
||||
* vi1 and vi2 as input values.
|
||||
* vo3 as output value.
|
||||
|
||||
Such that:
|
||||
|
||||
vi1 + vi2 = vo3
|
||||
|
||||
Generating a private key as a blinding factor for each input value and replacing each value
|
||||
with their respective Pedersen Commitments in the previous equation, we obtain:
|
||||
|
||||
(vi1*G + ki1*H) + (vi2*G + ki2*H) = (vo3*G + ko3*H)
|
||||
|
||||
Which as a consequence requires that:
|
||||
|
||||
ki1 + ki2 = ko3
|
||||
|
||||
This is the first pillar of MimbleWimble: the arithmetic required to validate a
|
||||
transaction can be done without knowing any of the values.
|
||||
|
||||
As a final note, this idea is actually derived from Greg Maxwell's
|
||||
[Confidential Transactions](https://www.elementsproject.org/elements/confidential-transactions/),
|
||||
which is itself derived from an Adam Back proposal for homomorphic values applied
|
||||
to Bitcoin.
|
||||
|
||||
### Ownership
|
||||
|
||||
In the previous section we introduced a private key as a blinding factor to obscure the
|
||||
transaction's values. The second insight of MimbleWimble is that this private
|
||||
key can be leveraged to prove ownership of the value.
|
||||
|
||||
Alice sends you 3 coins and to obscure that amount, you chose 113 as your
|
||||
blinding factor (note that in practice, the blinding factor being a private key, it's an
|
||||
extremely large number). Somewhere on the blockchain, the following output appears and
|
||||
should only be spendable by you:
|
||||
|
||||
X = 3*G + 113*H
|
||||
|
||||
_X_, the result of the addition, is visible by everyone. The value 3 is only known to you and Alice,
|
||||
and 113 is only known to you.
|
||||
|
||||
To transfer those 3 coins again, the protocol needs to require 113 to be known somehow.
|
||||
To demonstrate how this works, let's say you want to transfer those 3 same coins to Carol.
|
||||
You need build a simple transaction such that:
|
||||
|
||||
Xi => Y
|
||||
|
||||
Where _Xi_ is an input that spends your _X_ output and Y is Carol's output. There is no way to build
|
||||
such a transaction and balance it without knowing your private key of 113. Indeed, if Carol
|
||||
is to balance this transaction, she needs to know both the value sent and your private key
|
||||
so that:
|
||||
|
||||
Y - Xi = (3*G + 113*H) - (3*G + 113*H) = 0*G + 0*H
|
||||
|
||||
By checking that everything has been zeroed out, we can again make sure that
|
||||
no new money has been created.
|
||||
|
||||
Wait! Stop! Now you know the private key in Carol's output (which, in this case, must
|
||||
be the same as yours to balance out) and so you could
|
||||
steal the money back from Carol!
|
||||
|
||||
To solve this, we allow Carol to add another value of her choosing. She picks 28, and
|
||||
what ends up on the blockchain is:
|
||||
|
||||
Y - Xi = (3*G + (113+28)*H) - (3*G + 113*H) = 0*G + 28*H
|
||||
|
||||
Now the transaction doesn't sum to zero anymore, we have an _excess value_ on _H_
|
||||
(28), which is the result of the summation of all blinding factors. But because `28*H` is
|
||||
a valid public key on the elliptic curve _H_, with private key 28,
|
||||
for any x and y, only if `x = 0` is `x*G + y*H` a valid public key on H.
|
||||
|
||||
So all the protocol needs to verify is that (`Y - Xi`) is a valid public key on H and that
|
||||
the transaction author knows the private key (28 in our transaction with Carol). The
|
||||
simplest way to do so is to require an ECDSA signature built with the excess value (28),
|
||||
when then validates that:
|
||||
|
||||
* The author of the transaction knows the excess value (which is also the
|
||||
private key for the output)
|
||||
* The sum of the transaction's outputs, minus the inputs, adds to a zero value
|
||||
(because only a valid public key, matching the private key, will check against
|
||||
the signature).
|
||||
|
||||
Hence, what is being signed does not even matter (it can just be an empty string "").
|
||||
That signature, attached to every transaction, together with some additional data (like mining
|
||||
fees), is called a _transaction kernel_.
|
||||
|
||||
### Some Finer Points
|
||||
|
||||
This section elaborates on the building of transactions by discussing how change is
|
||||
introduced and the requirement for range proofs so all values are proven to be
|
||||
positive. Neither of these are absolutely required to understand MimbleWimble and
|
||||
Grin, so if you're in a hurry, fee free to jump straight to
|
||||
[Putting It All Together](#transaction-conclusion).
|
||||
|
||||
#### Change
|
||||
|
||||
In the above example, you had to share your private key (the blinding factor) with
|
||||
Carol. In general, even though private keys should never be reused, this isn't
|
||||
generally very desirable. Practically, this isn't an issue because transactions
|
||||
include a change output.
|
||||
|
||||
Let's say you only want to send 2 coins to Carol from the 3 you received from
|
||||
Alice. You simply generate another private key (say 42) as a blinding factor to
|
||||
protect your change output, and tell Carol you're sending her 2 coins and that for her transaction to be
|
||||
balanced she should use 113-42 as sum of blinding factors.
|
||||
|
||||
Then Carol adds her own excess value of 28 (for example) and we get as outputs:
|
||||
|
||||
Your change: 1*G + 42*H
|
||||
Carol: 2*G + (113-42+28)*H
|
||||
|
||||
The final sum that all validators end up doing looks like:
|
||||
|
||||
(1*G + 42*H) + (2*G + 99*H) - (3*G + 113*H) = 0*G + 28*H
|
||||
|
||||
Carol generates a signature with `28*H` as public key, as described in the previous
|
||||
section, to prove that the value is zero and that she was given the summation of blinding
|
||||
factors for the input and change. The signature is included in the _transaction kernel_
|
||||
which will be checked by all transaction validators.
|
||||
|
||||
#### Range Proofs
|
||||
|
||||
In all the above calculations, we rely on the transaction values to always be positive. The
|
||||
introduction of negative amounts would be extremely problematic as one could
|
||||
create new funds in every transaction.
|
||||
|
||||
For example, one could create a transaction with an input of 2 and outputs of 5
|
||||
and -3 and still obtain a well-balanced transaction, following the definition in
|
||||
the previous sections. This can't be easily detected because even if _x_ is
|
||||
negative, the corresponding point `x.G` on the ECDSA curve may not be.
|
||||
|
||||
To solve this problem, MimbleWimble leverages another cryptographic concept (also
|
||||
coming from Confidential Transactions) called
|
||||
range proofs: a proof that a number falls within a given range, without revealing
|
||||
the number. We won't elaborate on the range proof, but you just need to know
|
||||
that for any `v.G + k.H` we can build a proof that will show that _v_ is greater than
|
||||
zero and does not overflow.
|
||||
|
||||
<a name="transaction-conclusion"></a>
|
||||
### Putting It All Together
|
||||
|
||||
A MimbleWimble transaction includes the following:
|
||||
|
||||
* A set of inputs, that reference and spend a set of previous outputs.
|
||||
* A set of new outputs that include:
|
||||
* A value and a blinding factor (which is just a new private key) multiplied on
|
||||
a curve and summed to be `v.G + k.H`.
|
||||
* A range proof that shows that v is positive.
|
||||
* An explicit transaction fee, in clear.
|
||||
* A signature, computed by taking the excess blinding value (the sum of all
|
||||
outputs plus the fee, minus the inputs) and using it as a private key.
|
||||
|
||||
## Blocks and Chain State
|
||||
|
||||
We've explained above how MimbleWimble transactions can provide
|
||||
strong anonymity guarantees while maintaining the properties required for a valid
|
||||
blockchain, i.e., a transaction does not create money and proof of ownership
|
||||
is established through private keys.
|
||||
|
||||
The MimbleWimble block format builds on this by introducing one additional
|
||||
concept: _cut-through_. With this addition, a MimbleWimble chain gains:
|
||||
|
||||
* Extremely good scalability, as the great majority of transaction data can be
|
||||
eliminated over time, without compromising security;
|
||||
* Further anonymity by mixing and removing transaction data;
|
||||
* And the ability for new nodes to sync up with the rest of the network very
|
||||
efficiently.
|
||||
|
||||
### Cut-through
|
||||
|
||||
Blocks let miners assemble multiple transactions into a single set that's added
|
||||
to the chain. In the following block representations, containing 3 transactions,
|
||||
we only show inputs and
|
||||
outputs of transactions. Inputs reference outputs they spend. An output included
|
||||
in a previous block is marked with a lower-case x.
|
||||
|
||||
I1(x1) --- O1
|
||||
|- O2
|
||||
|
||||
I2(x2) --- O3
|
||||
I3(O2) -|
|
||||
|
||||
I4(O3) --- O4
|
||||
|- O5
|
||||
|
||||
We notice the two following properties:
|
||||
|
||||
* Within this block, some outputs are directly spent by included inputs (I3
|
||||
spends O2 and I4 spends O3).
|
||||
* The structure of each transaction does not actually matter. As all transactions
|
||||
individually sum to zero, the sum of all transaction inputs and outputs must be zero.
|
||||
|
||||
Similarly to a transaction, all that needs to be checked in a block is that ownership
|
||||
has been proven (which comes from _transaction kernels_) and that the whole block did
|
||||
not add any money supply (other than what's allowed by the coinbase).
|
||||
Therefore, matching inputs and outputs can be eliminated, as their contribution to the overall
|
||||
sum cancels out. Which leads to the following, much more compact block:
|
||||
|
||||
I1(x1) | O1
|
||||
I2(x2) | O4
|
||||
| O5
|
||||
|
||||
Note that all transaction structure has been eliminated and the order of inputs and
|
||||
outputs does not matter anymore. However, the sum of all outputs in this block,
|
||||
minus the inputs, is still guaranteed to be zero.
|
||||
|
||||
A block is simply built from:
|
||||
|
||||
* A block header.
|
||||
* The list of inputs remaining after cut-through.
|
||||
* The list of outputs remaining after cut-through.
|
||||
* The transaction kernels containing, for each transaction:
|
||||
* The public key `k*H` obtained from the summation of all the commitments.
|
||||
* The signatures generated using the excess value.
|
||||
* The mining fee.
|
||||
|
||||
When structured this way, a MimbleWimble block offers extremely good privacy
|
||||
guarantees:
|
||||
|
||||
* More transactions may have been done but do not appear.
|
||||
* All outputs look the same: just very large numbers that are impossible to
|
||||
differentiate from one another. If one wanted to exclude some outputs, they'd have
|
||||
to exclude all.
|
||||
* All transaction structure has been removed, making it impossible to tell which output
|
||||
was matched with each input.
|
||||
|
||||
And yet, it all still validates!
|
||||
|
||||
### Cut-through All The Way
|
||||
|
||||
Going back to the previous example block, outputs x1 and x2, spent by I1 and
|
||||
I2, must have appeared previously in the blockchain. So after the addition of
|
||||
this block, those outputs as well as I1 and I2 an also be removed from the
|
||||
overall chain, as they do not contribute to the overall sum.
|
||||
|
||||
Generalizing, we conclude that the chain state (excluding headers) at any point
|
||||
in time can be summarized by just these pieces of information:
|
||||
|
||||
1. The total amount of coins created by mining in the chain.
|
||||
2. The complete set of unspent outputs.
|
||||
3. The transactions kernels for each transaction.
|
||||
|
||||
The first piece of information can be deduced just using the block
|
||||
height (its distance from the genesis block). And both the unspent outputs and the
|
||||
transaction kernels are extremely compact. This has 2 important consequences:
|
||||
|
||||
* The state a given node in a MimbleWimble blockchain needs to maintain is very
|
||||
small (on the order of a few gigabytes for a bitcoin-sized blockchain, and
|
||||
potentially optimizable to a few hundreds of megabytes).
|
||||
* When a new node joins a network building up a MimbleWimble chain, the amount of
|
||||
information that needs to be transferred is also very small.
|
||||
|
||||
In addition, the complete set of unspent outputs cannot be tampered with, even
|
||||
only by adding or removing an output. Doing so would cause the summation of all
|
||||
blinding factors in the transaction kernels to differ from the summation of blinding
|
||||
factors in the outputs.
|
||||
|
||||
## Conclusion
|
||||
|
||||
In this document we covered the basic principles that underlie a MimbleWimble
|
||||
blockchain. By using the addition properties of Elliptic Curve Cryptography, we're
|
||||
able to build transactions that are completely opaque but can still be properly
|
||||
validated. And by generalizing those properties to blocks, we can eliminate a large
|
||||
amount of blockchain data, allowing for great scaling and fast sync of new peers.
|
||||
|
Loading…
Add table
Reference in a new issue