-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EIP: Reduce ECADD and ECMUL gas costs #1088
Comments
Antonio, thank you for opening it. Right now the main show-stopper for practical confidential transactions and ring-signature based votings is a price of MUL operation in G1, that has picked up 20 fold speed-up after changes you’ve mentioned. I’d propose dropping price of ADD from 500 to 50 and the price of MUL operation from 40000 to 2000. Also it's worth including a reduction of paring operation cost too as all those optimizations are closely related. For the reference of what would be a practical use of such ops I’ll try to give you an estimate of checking a single “Bulletproof” based range proof for 32 bit long integer tomorrow as I’ll release the set of provers, verifiers and mixers. Sincerely, Alex |
I probably don't have the most efficient Bulletproof verification logic, but for a 32-bit proof with a multiplication of a power of 10 and an offset it costs about 4,482,466 gas currently (tx). |
@shamatar an excellent point re: the pairing check, which I've added with a 15-fold drop (except for the constant factor, which seems to be ~the same in the benchmarks). I also took a closer look at ECMUL and you're absolutely right, it's 20-fold, not just 10-fold. Updated accordingly. |
@solidblu1992 have you published your Bulletproof verification code? We're considering them as an alternative to an accusation-based system |
Eh I've been digging through optimized curve implementations the last couple months, I'm sure it's not that bad @solidblu1992- thanks for the link! |
I've run quick tests, for 64 bits Single proof for 64 bits gas estimate = 20120556 Implementation is almost 1 to 1 (hashing was changed to be compatible with Ethereum keccak256() call) compatible with original Bulletproof repo from Stanford and "nothing up my sleeve". So 20-fold decrease makes it completely usable - reduce it to 32 bits and use 3 separate proofs (need at least 1->3 UTXOs mixing for confidentiality), so price will be around 1.5 million per full transaction if full precision is required, or less in case of partial indirect compromise of confidentiality. Source code is located here. It also has a prover to be run locally using JavaScript. Sincerely, Alex |
This looks like it's ready to be a draft EIP. If you agree, please submit it as a PR. |
Shouldn't gas cost per extra bytes also be reduced? As per precompile code base price is a flat fixed price, while extra price per 192 bytes is actually a price per pairing check.
|
@shamatar isn't that reflected above? The base price remains the same, the per-pairing price is divided by 15, to 5500k + 10000. |
@Arachnid I will do so today, thank you! |
Than you have a small typo in original prices, it should be 80000k + 100000 per pair, while you listed 80000k + 10000 per pair. My mistake, apologies. Sincerely, Alex |
Yikes! You're completely right, thanks for the catch 🙊 |
I’d still suggest lowering a fixed cost from 100000 down to 10000 (if you didn’t make another typing error). Having a large fixed price per call is no point as no expensive operations are done prior to actual pairing computations. So 5500 gas per element + 10000 fixed would be optimal I think. Sincerely, Alex |
I would be super-interested in that as well; I didn't change the fixed cost because if you look at the linked benchmarks, the “empty data” benchmark sees significantly smaller (~20%) drops. Still perhaps meriting 80 000 instead of 100, but I'm not sure a 10x decrease is justified. That said, I don't see a clear articulation in the EIP-197 regarding the motivation for that constant factor, so I might be missing something. |
I didn't see a motivation for a large fixed cost either, it costs virtually nothing
Can you add to EIP that sending 0 bytes to it should revert with a corresponding check
and set fixed price to zero? Such thing can be elaborated inside of EIP discussion. Having fixed price is quite unreasonable - I didn't see any context creation operations or something like this (such operations are anyway should only be done once on a startup). Sincerely, Alex |
@shamatar I'd recommend reducing the number of inv() function calls as I've found those to be quite gas intensive. For instance when calling haddamard_inv(publicParameters.hs(), b.ys), you are doing 64 mod inverses when you really only need to be doing one: haddamard(publicParameters.hs(), powers(b.y.inv()). Again, sorry if this is too far off topic. In any case, I'd be very happy to see the gas costs lowered. |
I was mainly porting a prover to abstract curve and JS to be run client side, and make a protocol as itself + tools for key exchange and mixing, but yes, optimizations should be done. By the way, what do you mean under “multiplication by a power of 10 and an offset” in your implementation? Sincerely, Alex |
So I was leveraging a technique used by Borromean Range Proofs where you can supply a power of 10 and an offset which are publicly known in order to reduce the number of bits required. For example, if I want to commit to 0.051 ETH, that's 5 x (10^16) + (10^15) wei. So, I could do a range proof on 5 for a lesser number of bits (at least 3, but probably more), and tell the contract that I'm multiplying my value by 10^16 and adding an offset of 10^15 (though in practice I rarely use the offset). The way I do this with bullet proofs is that after the bullet proof is verified, I have the contract modify the commitment and store that one as positive instead: C' = (10^power10)C + (offset)H. Note that if adding a power of 10, the blinding factor is scaled up by that same power of 10: bf' = bf x (10^power10) mod N. |
Oh, I see. I've first required a separate "deposit" procedure that normalizes everything to 3 decimals after the point for similar point. Thank you for clarification. Sincerely, Alex |
Hello @solidblu1992 While it's may be not the most appropriate place to discuss bulletproofs, I've implemented optimizations and fixed a test. Checking a proof by itself is 13 mil of gas, while the rest was coming from loading H[], G[], G and H vectors and points from storage. Out of those 13 mil around 6 are coming from multiExp in inner product proof at the final stage, and another 6 are from range proof pre-check and challenges computation. If you can share some numbers from you and suggestions - would be highly appreciated. Also, may be you have another communication channel? Sincerely, Alex |
Closing this in favor of the draft EIP @ #1108; apologies for the delay! |
Preamble
Short Description
Recent changes to the underlying library used by the official Go reference implementation led to significant performance gains for the ECADD and ECMUL precompiled contracts on the alt_bn128 elliptic curve, which should be reflected in reduced gas costs.
Motivation
Recently, the underlying library used by the official Go reference implementation to implement the
ECADD
(at address 0x06) andECMUL
(at address 0x07) precompiled contracts was shifted to Cloudflare's bn256 library. Based on the initial PR that introduced this change, and corroborated in a later note, the computational cost ofECADD
,ECMUL
, and pairing checks (excepting the constant) has dropped roughly an order of magnitude across the board.I am introducing this early EIP to propose dropping the gas costs accordingly.
Specification
Following is a table with the current gas cost and (current) suggested new gas cost:
ECADD
0x06
ECMUL
0x07
0x08
[1]- Per EIP-196.
[2]- Per EIP-197.
The text was updated successfully, but these errors were encountered: