Categorygithub.com/holiman/uint256
modulepackage
1.3.2
Repository: https://github.com/holiman/uint256.git
Documentation: pkg.go.dev

# README

Fixed size 256-bit math library

This is a library specialized at replacing the big.Int library for math based on 256-bit types, used by both go-ethereum and erigon.

Go Reference codecov DeepSource

Benchmarks

Current benchmarks, with tests ending with big being the standard big.Int library, and uint256 being this library.

Current status

  • As of 2020-03-18, uint256 wins over math/big in every single case, often with orders of magnitude.
  • And as of release 0.1.0, the uint256 library is alloc-free.
  • With the 1.0.0 release, it also has 100% test coverage.

Bitwise

benchmarku256 time/opbig time/optime diffu256 B/opbig B/opB diffu256 allocs/opbig allocs/opallocs diff
And/single2.03ns8.46ns-76.04%00~00~
Or/single2.03ns10.98ns-81.51%00~00~
Xor/single2.03ns12.19ns-83.34%00~00~
Rsh/n_eq_05.00ns48.11ns-89.61%064-100.00%01-100.00%
Rsh/n_gt_010.42ns48.41ns-78.48%064-100.00%01-100.00%
Rsh/n_gt_646.94ns52.39ns-86.76%064-100.00%01-100.00%
Rsh/n_gt_1285.49ns44.21ns-87.59%048-100.00%01-100.00%
Rsh/n_gt_1923.43ns28.71ns-88.04%08-100.00%01-100.00%
Lsh/n_eq_04.89ns40.49ns-87.92%064-100.00%01-100.00%
Lsh/n_gt_010.14ns53.25ns-80.96%080-100.00%01-100.00%
Lsh/n_gt_647.50ns53.92ns-86.08%080-100.00%01-100.00%
Lsh/n_gt_1285.39ns56.86ns-90.52%096-100.00%01-100.00%
Lsh/n_gt_1923.90ns57.61ns-93.23%096-100.00%01-100.00%

Conversions

benchmarku256 time/opbig time/optime diffu256 B/opbig B/opB diffu256 allocs/opbig allocs/opallocs diff
FromHexString116.70ns861.30ns-86.45%3288-63.64%13-66.67%
FromDecimalString7973.00ns32850.00ns-75.73%02464-100.00%077-100.00%
Float64/Float642366.00ns28483.00ns-91.69%023424-100.00%0510-100.00%
EncodeHex/large95.26ns184.30ns-48.31%80140-42.86%12-50.00%
Decimal/ToDecimal67384.00ns83431.00ns-19.23%1134431920-64.46%248594-58.25%
Decimal/ToPrettyDecimal84208.00ns123953.00ns-32.06%1472061376-76.02%2511100-77.18%

Math

benchmarku256 time/opbig time/optime diffu256 B/opbig B/opB diffu256 allocs/opbig allocs/opallocs diff
Add/single1.99ns18.11ns-89.02%00~00~
Sub/single2.00ns17.19ns-88.35%00~00~
Mul/single12.10ns57.69ns-79.03%00~00~
SDiv/large94.64ns642.10ns-85.26%0312-100.00%06-100.00%
Sqrt/single594.90ns1844.00ns-67.74%0528-100.00%07-100.00%
Square/single12.49ns56.10ns-77.74%00~00~
Cmp/single4.78ns12.79ns-62.61%00~00~
Div/small12.91ns48.31ns-73.28%08-100.00%01-100.00%
Div/mod6465.77ns111.20ns-40.85%08-100.00%01-100.00%
Div/mod12893.67ns301.40ns-68.92%080-100.00%01-100.00%
Div/mod19286.52ns263.80ns-67.20%080-100.00%01-100.00%
Div/mod25677.17ns252.80ns-69.47%080-100.00%01-100.00%
AddMod/small13.84ns48.16ns-71.26%04-100.00%00~
AddMod/mod6422.83ns57.58ns-60.35%011-100.00%00~
AddMod/mod12848.31ns145.00ns-66.68%012-100.00%00~
AddMod/mod19247.26ns160.00ns-70.46%012-100.00%00~
AddMod/mod25614.44ns143.20ns-89.92%012-100.00%00~
MulMod/small40.81ns63.14ns-35.37%08-100.00%01-100.00%
MulMod/mod6491.66ns112.60ns-18.60%048-100.00%01-100.00%
MulMod/mod128136.00ns362.70ns-62.50%0128-100.00%02-100.00%
MulMod/mod192151.70ns421.20ns-63.98%0144-100.00%02-100.00%
MulMod/mod256188.80ns489.20ns-61.41%0176-100.00%02-100.00%
Exp/small433.70ns7490.00ns-94.21%07392-100.00%077-100.00%
Exp/large5145.00ns23043.00ns-77.67%018144-100.00%0189-100.00%
Mod/mod6470.94ns118.90ns-40.34%064-100.00%01-100.00%
Mod/small14.82ns46.27ns-67.97%08-100.00%01-100.00%
Mod/mod12899.58ns286.90ns-65.29%064-100.00%01-100.00%
Mod/mod19295.31ns269.30ns-64.61%048-100.00%01-100.00%
Mod/mod25684.13ns222.90ns-62.26%08-100.00%01-100.00%
MulOverflow/single27.68ns57.52ns-51.88%00~00~
MulDivOverflow/small2.83ns22.97ns-87.69%00~00~
MulDivOverflow/div642.85ns23.13ns-87.66%00~00~
MulDivOverflow/div1283.14ns31.29ns-89.96%02-100.00%00~
MulDivOverflow/div1923.17ns30.28ns-89.54%02-100.00%00~
MulDivOverflow/div2563.54ns35.56ns-90.06%05-100.00%00~
Lt/small3.12ns10.43ns-70.06%00~00~
Lt/large3.49ns10.32ns-66.18%00~00~

Other

benchmarku256 time/opu256 B/opu256 allocs/op
SetBytes/generic104.30ns00
Sub/single/uint256_of1.99ns00
SetFromBig/overflow3.57ns00
ToBig/2words73.84ns642
SetBytes/specific45.81ns00
ScanScientific674.10ns00
SetFromBig/4words3.82ns00
ToBig/4words68.82ns642
RLPEncoding11917.00ns11911255
SetFromBig/1word2.99ns00
SetFromBig/3words4.12ns00
ToBig/3words70.12ns642
ToBig/1word75.38ns642
MulMod/mod256/uint256r77.11ns00
HashTreeRoot11.27ns00
SetFromBig/2words3.90ns00

Helping out

If you're interested in low-level algorithms and/or doing optimizations for shaving off nanoseconds, then this is certainly for you!

Implementation work

Choose an operation, and optimize the s**t out of it!

A few rules, though, to help your PR get approved:

  • Do not optimize for 'best-case'/'most common case' at the expense of worst-case.
  • We'll hold off on go assembly for a while, until the algos and interfaces are finished in a 'good enough' first version. After that, it's assembly time.

Doing benchmarks

To do a simple benchmark for everything, do

go test -run - -bench . -benchmem

To see the difference between a branch and master, for a particular benchmark, do

git checkout master
go test -run - -bench Benchmark_Lsh -benchmem -count=10 > old.txt

git checkout opt_branch
go test -run - -bench Benchmark_Lsh -benchmem -count=10 > new.txt

benchstat old.txt new.txt

# Functions

FromBig is a convenience-constructor from big.Int.
FromDecimal is a convenience-constructor to create an Int from a decimal (base 10) string.
FromHex is a convenience-constructor to create an Int from a hexadecimal string.
MustFromBig is a convenience-constructor from big.Int.
MustFromDecimal is a convenience-constructor to create an Int from a decimal (base 10) string.
MustFromHex is a convenience-constructor to create an Int from a hexadecimal string.
NewInt returns a new initialized Int.
Reciprocal computes a 320-bit value representing 1/m Notes: - specialized for m[3] != 0, hence limited to 2^192 <= m < 2^256 - returns zero if m[3] == 0 - starts with a 32-bit division, refines with newton-raphson iterations.

# Variables

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Type aliases

Int is represented as an array of 4 uint64, in little-endian order, so that Int[3] is the most significant, and Int[0] is the least significant.