Update Description
parent
d551e4b5c8
commit
bcdb9a2ce2
124
Description.md
124
Description.md
@ -54,6 +54,130 @@ $$ OR $$
|
|||||||
|
|
||||||
$$ s*G - e*H_{\text{agg}}= R - \sum_i^m (e*(a_i * X_i) + b*R_{\text{i1}} + d*R_{\text{i2}}) $$
|
$$ s*G - e*H_{\text{agg}}= R - \sum_i^m (e*(a_i * X_i) + b*R_{\text{i1}} + d*R_{\text{i2}}) $$
|
||||||
|
|
||||||
|
## Optimization ideas
|
||||||
|
|
||||||
|
### Abuse of `ecrecover` precompile
|
||||||
|
|
||||||
|
Ethereum (majority of EVM-based chains) `ecrecover` returns an address (hash of public key) given an ECDSA signature. Given message `m` and ECDSA signature (`v`, `r`, `s`) where `v` denotes the parity of the y-coordinate for the point where x-coordinate `r`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ecrecover(m, v, r, s):
|
||||||
|
R = point derived from r and v
|
||||||
|
a = -G*m
|
||||||
|
b = R*s
|
||||||
|
Qr = a + b
|
||||||
|
Q = Qr * (1/r)
|
||||||
|
Q = (1/r) * (R*s - G*m) //recovered pubkey
|
||||||
|
```
|
||||||
|
|
||||||
|
Ethereum's `ecrecover` returns the last 20 bytes of the keccak256 hash of the 64-byte public key, [check code here](https://github.com/ethereum/go-ethereum/blob/eb948962704397bb861fd4c0591b5056456edd4d/crypto/crypto.go#L275). Given signature (`R`, `s`), message `m` and public key `P` we can feed values into `ecrecover` such that the returned address can be used in a comparison to the challenge.
|
||||||
|
|
||||||
|
$$ calculate e = H(address(R) || m) and P_x = x-coordinate of P $$
|
||||||
|
|
||||||
|
pass:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
m = -s*P_x
|
||||||
|
v = parity of P
|
||||||
|
r = x-coordinate of P
|
||||||
|
s = -e*P_x
|
||||||
|
```
|
||||||
|
|
||||||
|
then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ecrecover(m=-s*P_x, v=0/1, r=P_x, s=-e*P_x):
|
||||||
|
P = point derived from r and v (public key)
|
||||||
|
a = -G*(-s*P_x) = G*s*P_x
|
||||||
|
b = P*(-m*P_x) = -P*e*P_x
|
||||||
|
Q = (1/P_x) (a+b)
|
||||||
|
Q = (1/P_x)(G*s*P_x - P*e*P_x)
|
||||||
|
Q = G*s - P*e // same as schnorr verify above
|
||||||
|
```
|
||||||
|
|
||||||
|
the returned value is `address(Q)`.
|
||||||
|
|
||||||
|
* calculate e' = h(address(Q) || m)
|
||||||
|
* check e' == e to verify the signature.
|
||||||
|
|
||||||
|
Canoncial `ecrecover` implementations:
|
||||||
|
|
||||||
|
* [go-ethereum](https://github.com/ethereum/go-ethereum/blob/8a134014b4b370b4a3632e32a2fc8e84ee2b6947/crypto/secp256k1/secp256.go#L105)
|
||||||
|
* [bitcoin-core](https://github.com/bitcoin-core/secp256k1/blob/aa5d34a8fe99b1f69306be20819f337dbd3283db/src/modules/recovery/main_impl.h#L87)
|
||||||
|
|
||||||
|
### Minimization of multiplications
|
||||||
|
|
||||||
|
$$ s*G - e*H_{\text{agg}} = R - \sum_i^m (e*(a_i * X_i) + b*R_{\text{i1}} + d*R_{\text{i2}}) $$
|
||||||
|
|
||||||
|
$$ s*G - e*H_{\text{agg}} = b*R_1 + d*R_2 - \sum_i^m (e*(a_i * X_i) + b*R_{\text{i1}} + d*R_{\text{i2}}) $$
|
||||||
|
|
||||||
|
$$ s*G - e*H_{\text{agg}} = b*R_1 + d*R_2 - \sum_i^m (e*(a_i * X_i)) - \sum_i^m (b*R_{\text{i1}}) - \sum_i^m (d*R_{\text{i2}}) $$
|
||||||
|
|
||||||
|
$$ s*G + e*( \sum_i^m (a_i * X_i) - H_{\text{agg}}) = b*(R_1 - \sum_i^m R_{\text{i1}}) + d*(R_2 - \sum_i^m R_{\text{i2}}) $$
|
||||||
|
|
||||||
|
In this variant operations needed:
|
||||||
|
|
||||||
|
* number of additions = `3(m + 1) + 2`
|
||||||
|
* number of multiplications = `4 consant`
|
||||||
|
|
||||||
|
In original version:
|
||||||
|
|
||||||
|
* number of additions = `2m + 2`
|
||||||
|
* number of multiplications = `4m + 2`
|
||||||
|
|
||||||
|
For that reason verifier should reconstruct `R` from the:
|
||||||
|
|
||||||
|
$$ R = b*R_1 + d*R_2 $$
|
||||||
|
|
||||||
|
### Threshold identification
|
||||||
|
|
||||||
|
Because the values $ a_i $, $ X_i $, R_{\text{i1}}, R_{\text{i2}} can be computed locally and only their sums sent to the verifier, a malicious user could try to spoof the threshold. To prevent this, send the full list of original signers to the verifier together with indices for any missing signers; the verifier will then recomput $ H_{\text{agg}} $ and compare it to the stored value. The verifier computes each $ H_i $ based on the provided indexes of missing signers.
|
||||||
|
|
||||||
|
$$ s*G + e*( \sum_i^m (H_i) - H_{\text{agg}}) = b*(R_1 - \sum_i^m R_{\text{i1}}) + d*(R_2 - \sum_i^m R_{\text{i2}}) $$
|
||||||
|
|
||||||
|
### Usage of GLV (Gallant–Lambert–Vanstone) and GLS (Galbraith–Lin–Scott)
|
||||||
|
|
||||||
|
Potentially useful links:
|
||||||
|
|
||||||
|
* [GLV (Gallant–Lambert–Vanstone)](https://www.iacr.org/archive/crypto2001/21390189.pdf)
|
||||||
|
* [GLS (Galbraith–Lin–Scott)](https://eprint.iacr.org/2008/194.pdf)
|
||||||
|
* [GLV-Based Scalar Multiplication](https://eprint.iacr.org/2013/158.pdf)
|
||||||
|
* [The Realm of the Pairings](https://eprint.iacr.org/2013/722)
|
||||||
|
* [Fast and compact elliptic-curve cryptography](https://eprint.iacr.org/2012/309)
|
||||||
|
|
||||||
|
If the final formula is:
|
||||||
|
|
||||||
|
$$ s*G + e*( \sum_i^m (H_i) - H_{\text{agg}}) = b*(R_1 - \sum_i^m R_{\text{i1}}) + d*(R_2 - \sum_i^m R_{\text{i2}}) $$
|
||||||
|
|
||||||
|
The optimization should be focused on:
|
||||||
|
|
||||||
|
$$ b*(R_1 - \sum_i^m R_{\text{i1}}) + d*(R_2 - \sum_i^m R_{\text{i2}}) = k*P + m*Q $$
|
||||||
|
|
||||||
|
For a curve with efficient endomorphism $ ϕ $ where $ ϕ(P) = λP $ in the subgroup of order $ r $:
|
||||||
|
|
||||||
|
$$ k ≡ k_1 +k_2 λ (mod r) $$
|
||||||
|
$$ m ≡ m_1 +m_2 λ (mod r) $$
|
||||||
|
$$ |k_1|, |k_2|, |m_1|, |m_2| ≈ \sqrt{r} $$
|
||||||
|
$$ r≈2^{256} $$
|
||||||
|
$$ k_i, m_i ≈ \sqrt{2^{256}} ≈ 2^{128} $$
|
||||||
|
|
||||||
|
Then use multi-scalar multiplication:
|
||||||
|
|
||||||
|
$$ kP + mQ = (k_1 + k_2λ)P + (m_1 + m_2λ)Q = k_1P + k_2(λP) + m_1Q + m_2(λQ) $$
|
||||||
|
|
||||||
|
$$ P` = λP = ϕ(P) = ϕ((P_x, P_y)) = (βP_x, P_y) $$
|
||||||
|
|
||||||
|
$$ Q` = λQ = ϕ(Q) = ϕ((Q_x, Q_y)) = (βQ_x, Q_y) $$
|
||||||
|
|
||||||
|
$$ kP + mQ = k_1P + k_1P` + m_2Q + m_2Q` $$
|
||||||
|
|
||||||
|
Then use `Straus-Shamir trick` to do simultaneous multiplication of four elements. In theory that will save:
|
||||||
|
|
||||||
|
* 128 doublings, because all scalars are less then 128 bit.
|
||||||
|
* 120 additions, because probability of four zeros is $ 1/16 $.
|
||||||
|
|
||||||
|
Based on the [current solidity implementation](https://git.ghostchain.io/ghostchain/ghost-exodus-draft#gas-usage) final gas cost for the most intensive part can be estimated around 197,080 gas units.
|
||||||
|
|
||||||
## Reporting issues and feedback
|
## Reporting issues and feedback
|
||||||
|
|
||||||
We welcome feedback and bug reports from knowledgeable contributors. If you discover any issues or have suggestions, please contact us via email or any of the social links below. If you have an account here, you may also submit a free-form issue.
|
We welcome feedback and bug reports from knowledgeable contributors. If you discover any issues or have suggestions, please contact us via email or any of the social links below. If you have an account here, you may also submit a free-form issue.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user