Skip to content
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

Create bigint_modexp.md #198

Merged
merged 17 commits into from Mar 27, 2018

Conversation

@vbuterin
Copy link
Collaborator

commented Jan 30, 2017

Precompile for bigint modular exponentiation. Meant to supersede #101.


<length_of_BASE> <length_of_EXPONENT> <length_of_MODULUS> <BASE> <EXPONENT> <MODULUS>

Where every length is a 32-byte left-padded integer representing the number of bytes to be taken up by the next value. Call data is assumed to be infinitely right-padded with zero bytes, and excess data is ignored. Consumes `floor(max(length_of_MODULUS, length_of_BASE) ** 2 * max(length_of_EXPONENT, 1) / GQUADDIVISOR)` gas, and if there is enough gas, returns an output `(BASE**EXPONENT) % MODULUS` as a byte array with the same length as the modulus.

This comment has been minimized.

Copy link
@axic

axic Feb 6, 2017

Member

Would it be safe assuming that it is unlikely to have calls consuming gigabytes of data?

If yes, how about making each length field 32 bits wide (or even less):

     00000001
     00000020
     00000020
     03
     fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e
     fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f

I understand we have 0 gas for 0 bytes in the payload, but does that make any sense?

This comment has been minimized.

Copy link
@pirapira

pirapira Apr 24, 2017

Member

"representing the number of bytes to be taken up by the next value" <- I don't think this is correct anymore. It used to be like that in the initial drafts, but not anymore.

@vbuterin

This comment has been minimized.

Copy link
Collaborator Author

commented Feb 10, 2017

I like 32 bytes more for two reasons:

  1. Similarity to how the existing ABI works, and generally how ethereum works (we don't really do static sizes other than 32 at this point)
  2. It's actually easier to pack 32 bytes in EVM than it is to pack 4 bytes in EVM; the latter requires some arithmetic manipulations to fit the slice in, whereas the former is the same width as MLOAD/MSTORE so it works directly.
@axic

This comment has been minimized.

Copy link
Member

commented Feb 11, 2017

It's actually easier to pack 32 bytes in EVM than it is to pack 4 bytes in EVM

We could also pack them into a single 32 byte slot, that would make it easier. That would only need multiplication (2 times) and a single mstore.

If however the motivation is to make it easy on ABI encoding, then I would change the gas calculation not to be based on supplied length, but based on first byte set. That would allow sending each field as a multiple of 32 bytes.

Your example would become:

     0000000000000000000000000000000000000000000000000000000000000020
     0000000000000000000000000000000000000000000000000000000000000020
     0000000000000000000000000000000000000000000000000000000000000020
     0000000000000000000000000000000000000000000000000000000000000003
     fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e
     fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f

This way it is up to the caller's implementation to decide which is more beneficial: allocating more memory or using more instructions to pack them tight.

@Souptacular

This comment has been minimized.

Copy link
Member

commented Feb 21, 2017

Please make compliant with EIP-0 (eg, add a header with number/status etc), renumber to EIP 198 (or the issue number), update in response to any comments, and tag with editor-needs-to-review when it's ready for merge.

@pirapira

This comment has been minimized.

Copy link
Member

commented Mar 3, 2017

@vbuterin What is the value of (0 ** 0) % 10000? Zero or one? Maybe one because PUSH_1 0 PUSH_1 0 EXP results in one.

@arkpar arkpar referenced this pull request Mar 9, 2017

Closed

Byzantium release #4833

12 of 12 tasks complete
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e
fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f

Would be parsed as a base of 0, exponent of `2**256 - 2**32 - 978` and modulus of `2**256 - 2**32 - 978`, and so would return 0. Notice how if the length_of_BASE is 0, then it does not interpret _any_ data as the base, instead immediately interpreting the next 32 bytes as length_of_EXPONENT.

This comment has been minimized.

Copy link
@rphmeier

rphmeier Mar 15, 2017

Collaborator

length_of_EXPONENT -> EXPONENT?

This comment has been minimized.

Copy link
@pirapira

pirapira Mar 15, 2017

Member

Why? BASE is followed by length_of_EXPONENT.

This comment has been minimized.

Copy link
@rphmeier

rphmeier Mar 15, 2017

Collaborator

L9: <length_of_BASE> <length_of_EXPONENT> <length_of_MODULUS> <BASE> <EXPONENT> <MODULUS>

Since length_of_BASE is zero, it does not interpret any data as the base. The following 32 bytes (after the zero-length BASE) are the EXPONENT, not the length_of_EXPONENT.

This comment has been minimized.

Copy link
@gumb0

gumb0 Apr 4, 2017

Member

Also, modulus is interpreted as 2**256 - 2**32 - 977

@pirapira

This comment has been minimized.

Copy link
Member

commented Mar 15, 2017

@gumb0 gumb0 referenced this pull request Apr 3, 2017

Merged

EIP198 - Bigint modexp precompiled contract #4028

3 of 3 tasks complete
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd

Would parse a base length of 0, a modulus length of 32, and an exponent length of `2**256 - 1`, where the base is empty, the modulus is `2**256 - 2` and the exponent is `(2**256 - 3) * 256**(2**256 - 33)` (yes, that's a really big number). It would then immediately fail, as it's not possible to provide enough gas to make that computation.

This comment has been minimized.

Copy link
@gumb0

gumb0 Apr 4, 2017

Member

This is base of length 0, an exponent of length 32 and modulus of length 2**256 - 1.
The exponent is 2**256 - 2, the modulus is (2**256 - 3) * 256**(2**256 - 33)

This comment has been minimized.

Copy link
@pirapira

pirapira Dec 1, 2017

Member

This seems correct. I apply this change.

@Arachnid

This comment has been minimized.

Copy link
Collaborator

commented Apr 14, 2017

Please update to follow the template here and rename to eip-198.md, and we'll merge as draft.

@chfast chfast referenced this pull request Apr 21, 2017

Closed

[META] Byzantium implementation progress #4050

17 of 17 tasks complete
@axic

This comment has been minimized.

Copy link
Member

commented Apr 23, 2017

I would change the gas calculation not to be based on supplied length, but based on first byte set. That would allow sending each field as a multiple of 32 bytes.

I would like to propose this again. This enables callers to save on gas costs. (See the explanation above)

@vbuterin ?

@chfast

This comment has been minimized.

Copy link
Contributor

commented Apr 23, 2017

I support for paying only for significant bytes in the provided data (the same way it is done for exponent of EXP).

If the field lengths are known at the "compile" time in most of the use cases, can we represent all lengths in a single word, with 32-bit reserved per field length?

  • When the lengths are combined (and known up-front) we have: PUSH 0x200000002000000020 PUSH 0x00 MSTORE (13 bytes of code).
  • When the lengths occupy a word each we have: PUSH 0x20 PUSH 0x00 MSTORE PUSH 0x20 PUSH 0x01 MSTORE PUSH 0x20 PUSH 0x02 MSTORE (15 bytes of code).
@pirapira

This comment has been minimized.

Copy link
Member

commented Apr 24, 2017

This PR is meant to replace #101, but I'm not seeing big int addition, subtraction, multiplication or division in this PR. Are they going to be added or not? This affects the choice of addresses for the following precompiled contracts.

@pirapira

This comment has been minimized.

Copy link
Member

commented Apr 24, 2017

Since #101 and #198 use different addresses, there is uncertainty about what address is assigned to which contract. I added [WIP] in the title. I was trying to change my PR in yellowpaper repository.

@riordant

This comment has been minimized.

Copy link

commented Sep 18, 2017

What is recommended for doing bigint division now that the division precompile was removed? Currently I am getting the reciprocal of the divisor using the Newton-Raphson method and multiplying with the dividend using this contract. Is that sufficient?

@tristanhoy

This comment has been minimized.

Copy link

commented Sep 21, 2017

Division is incredibly slow - but there is an alternative for some cases.

Modular reduction (and therefore exponentiation) for any cryptographic scheme operating over a public prime group (Schnorr, ECC, ElGamal) can be massively sped up when a prime is chosen that is close to a power of two (e.g. 2^255 - 19, 2^3072 - 77405 etc).

The algorithm is really simple: https://gist.github.com/tristanhoy/01450b820864aa7205587581c7b12099

Additionally, if a set of recommended public primes are provided, the gas costs for exponentiation will be very predictable (unlike the product of two secret primes).

@pipermerriam pipermerriam referenced this pull request Oct 20, 2017

Merged

Byzantium Fork Rules #123

9 of 9 tasks complete

@pirapira pirapira referenced this pull request Oct 23, 2017

Open

Apply Byzantium changes #459

0 of 10 tasks complete

@nicksavers nicksavers referenced this pull request Nov 17, 2017

Closed

Vbuterin patch 2 #751

pirapira added some commits Nov 30, 2017

@pirapira

This comment has been minimized.

Copy link
Member

commented Dec 1, 2017

@vbuterin do you mind if I append

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

?

@tinybike tinybike referenced this pull request Jan 9, 2018

Closed

No file for EIP-198 #825

pirapira added a commit to pirapira/yellowpaper that referenced this pull request Jan 17, 2018

Remove add, sub, mul and div precompiles
Because ethereum/EIPs#198 supersedes ethereum/EIPs#101 and the new version does not contain these.

pirapira added a commit to pirapira/yellowpaper that referenced this pull request Jan 17, 2018

pirapira added a commit to pirapira/yellowpaper that referenced this pull request Jan 19, 2018

pirapira added a commit to pirapira/yellowpaper that referenced this pull request Jan 19, 2018

@fulldecent

This comment has been minimized.

Copy link
Contributor

commented Mar 22, 2018

@Arachnid You nominated this as an "EIPs that should be merged". Can you please share your notes on that here?

@Arachnid

This comment has been minimized.

Copy link
Collaborator

commented Mar 22, 2018

This pull request is referenced by #609, which has already been merged. As such, it needs to either be finalised and merged, or the dependency in the existing EIP needs to be removed.

Arachnid and others added some commits Mar 25, 2018

Merge pull request #946 from ethereum/vbuterin-patch-2-patch
Rename bigint_modexp.md to eip-198.md, add new prologue and copyrigt notice

@Arachnid Arachnid merged commit a76a0a0 into master Mar 27, 2018

0 of 2 checks passed

continuous-integration/travis-ci/pr The Travis CI build failed
Details
continuous-integration/travis-ci/push The Travis CI build failed
Details

@Arachnid Arachnid deleted the vbuterin-patch-2 branch Mar 27, 2018

@Arachnid

This comment has been minimized.

Copy link
Collaborator

commented Mar 27, 2018

This is a courtesy notice to let you know that the format for EIPs has been modified slightly. If you want your draft merged, you will need to make some small changes to how your EIP is formatted:

  • Frontmatter is now contained between lines with only a triple dash ('---')
  • Headers in the frontmatter are now lowercase.

If your PR is editing an existing EIP rather than creating a new one, this has already been done for you, and you need only rebase your PR.

In addition, a continuous build has been setup, which will check your PR against the rules for EIP formatting automatically once you update your PR. This build ensures all required headers are present, as well as performing a number of other checks.

Please rebase your PR against the latest master, and edit your PR to use the above format for frontmatter. For convenience, here's a sample header you can copy and adapt:

---
eip: <num>
title: <title>
author: <author>
type: [Standards Track|Informational|Meta]
category: [Core|Networking|Interface|ERC] (for type: Standards Track only)
status: Draft
created: <date>
---

Arachnid added a commit to Arachnid/EIPs that referenced this pull request Mar 27, 2018

Create bigint_modexp.md (ethereum#198)
* Create bigint_modexp.md

* Update bigint_modexp.md

* Update bigint_modexp.md

* Update bigint_modexp.md

* Update bigint_modexp.md

* Update bigint_modexp.md

* Update bigint_modexp.md

* Update bigint_modexp.md

* Update bigint_modexp.md

* Update bigint_modexp.md

* Update bigint_modexp.md

* Update bigint_modexp.md

* Update bigint_modexp.md

* Fixing an example after the specification change

https://github.com/ethereum/EIPs/pull/198/files#r106236783

* Fix one example after a format change

https://github.com/ethereum/EIPs/pull/198/files#r109660742

* Rename bigint_modexp.md to eip-198.md, add new prologue and copyright notice.

@aerth aerth referenced this pull request Jun 5, 2018

Merged

HF7 @ 36050 #24

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.