ethereumjs-monorepo icon indicating copy to clipboard operation
ethereumjs-monorepo copied to clipboard

VM: Fixed-width BN / BigInt

Open s1na opened this issue 6 years ago • 4 comments

Most values used in the VM have a pre-specified width, and the EVM operates on 256 bit words. Built-in javascript numbers have 53 bits, which is not enough for most of the Ethereum values. As such, VM utilizes bn.js, which offers arbitrary-precision big numbers and operations on them.

BN is very convenient and works very well. The only downside is that validating the width of these numbers becomes paramount to ensure safety, and sometimes when the size hasn't been validated, an out-of-bound value can cause issues, e.g. see #464.

This issue was created to discuss solutions or alternatives to the current approach, and the requirements for any such solution.

One solution that I've seen is fixed-bn.js, which is a wrapper over bn.js, that checks the width of value in its constructor. But it's very new, and it's missing some features, e.g. https://github.com/ewasm/fixed-bn.js/issues/6.

s1na avatar Mar 12 '19 14:03 s1na

The current approach that fixed-bn.js takes is to simply wrap an arbitrary-precision bignum and do validations and modulo operations on top.

An alternative is to implement a pure fixed-precision bignum library (e.g. intx (cpp) or uint256 (go)). Fixed-precision bignum has the benefits of fixed-bn.js but is expected to be more performant.

Downsides that I see are: Needs to be implemented from scratch either in pure JS (not sure how this would compare to native BigInt) or use a WebAssembly version. It's not as flexible as an arbitrary-precision bignum and it would need types for multiple variants, e.g. u64, u128, u256 (possibly bigger variants in future).

s1na avatar May 28 '19 11:05 s1na

Since we are now migrating to BigInt, is this issue still relevant?

gabrocheleau avatar Mar 17 '22 17:03 gabrocheleau

BigInt is also arbitrary precision so one could imagine a fixed-bigint

s1na avatar Mar 17 '22 17:03 s1na

I guess it could be worth taking up at some point to decide if we need to add an overlay for fixed-width as it should be pretty feasiible. Native Bigints offer the BigInt.asUintN and BigInt.asIntN constructor methods to define Bigints with a set width so shouldn't be too bad to implement if the team felt like we wanted to take that on.

acolytec3 avatar Mar 17 '22 17:03 acolytec3