Change length proof to degree proof

This commit is contained in:
Dankrad Feist 2020-12-28 16:36:28 +00:00 committed by protolambda
parent a260dbcf15
commit f44b7ffe48
No known key found for this signature in database
GPG Key ID: EC89FDBB2B4C7623

View File

@ -94,9 +94,6 @@ We define the following Python custom types for type hinting and readability:
| `G2_SETUP` | Type `List[G2]`. The G2-side trusted setup `[G, G*s, G*s**2....]`; note that the first point is the generator. |
| `MODULUS` | `0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001` (curve order of BLS12_381) |
| `ROOT_OF_UNITY` | `pow(PRIMITIVE_ROOT_OF_UNITY, (MODULUS - 1) // (MAX_SAMPLES_PER_BLOCK * POINTS_PER_SAMPLE, MODULUS)` |
| `SIZE_CHECK_POINTS` | Type `List[G2, MAX_SAMPLES_PER_BLOCK + 1]`; TO BE COMPUTED |
These points are the G2-side KZG10 commitments to `product[a in i...next_power_of_two(i)] (X ** POINTS_PER_SAMPLE - w ** (reverse_bit_order(a, MAX_SAMPLES_PER_BLOCK * DATA_AVAILABILITY_INVERSE_CODING_RATE) * POINTS_PER_SAMPLE))` for each `i` in `[0...MAX_SAMPLES_PER_BLOCK]`, where `w = ROOT_OF_UNITY`. They are used to verify block size proofs. They can be computed with a one-time O(N**2/log(N)) calculation using fast-linear-combinations in G2.
### Gwei values
@ -181,9 +178,8 @@ class ShardHeader(Container):
shard: Shard
# The actual data commitment
commitment: DataCommitment
# Proof of the length (more precisely, proof that values at
# positions >= the length all equal zero)
length_proof: BLSCommitment
# Proof that the degree < commitment.length
degree_proof: BLSCommitment
```
### `PendingShardHeader`
@ -495,7 +491,7 @@ def process_shard_header(state: BeaconState,
)
# Verify length of the header, and simultaneously verify degree.
assert (
bls.Pairing(header.length_proof, SIZE_CHECK_POINTS[header.commitment.length]) ==
bls.Pairing(header.degree_proof, G2_SETUP[0]) ==
bls.Pairing(header.commitment.point, G2_SETUP[-header.commitment.length]))
)
# Get the correct pending header list
@ -519,9 +515,7 @@ def process_shard_header(state: BeaconState,
))
```
The length-and-degree proof works as follows. For a block `B` with length `l` (so `l` nonzero values in `[0... - 1]`), the length proof is the commitment to the polynomial `(B(X) / Z(X)) * (X**(MAX_DEGREE + 1 - l))`, where `Z` is the minimal polynomial that is zero over `ROOT_OF_UNITY ** [l...next_power_of_two(l) - 1]` (see `SIZE_CHECK_POINTS` above) and `MAX_DEGREE` the the maximum power of `s` available in the setup, which is `MAX_DEGREE = len(G2_SETUP) - 1`. The goal is to ensure that a proof can only be constructed if (i) `B / Z` is itself non-fractional, meaning that `B` is a multiple of `Z`, and (ii) `deg(B) < next_power_of_two(l)` (there are not hidden higher-order terms in the polynomial, which would thwart reconstruction).
The length proof will have the degree of `(B(X) / Z(X)) * X**(MAX_DEGREE + 1 - l)`, so `deg(B) - (next_power_of_two(l) - l) + MAX_DEGREE + 1 - l`, simplified to `deg(B) - next_power_of_two(l) + MAX_DEGREE + 1`. Because it's only possible to commit to polynomials with degree `<= MAX_DEGREE`, it's only possible to generate the proof if this expression is less than or equal to `MAX_DEGREE`, meaning that `deg(B)` must be strictly less than `next_power_of_two(l)`.
The degree proof works as follows. For a block `B` with length `l` (so `l` values in `[0...l - 1]`, seen as a polynomial `B(X)` which takes these values), the length proof is the commitment to the polynomial `B(X) * X**(MAX_DEGREE + 1 - l)`, where `MAX_DEGREE` the the maximum power of `s` available in the setup, which is `MAX_DEGREE = len(G2_SETUP) - 1`. The goal is to ensure that a proof can only be constructed if `deg(B) < l` (there are not hidden higher-order terms in the polynomial, which would thwart reconstruction).
### Shard transition processing