SkillAgentSearch skills...

Uint256

Fixed size 256-bit math library

Install / Use

/learn @holiman/Uint256
About this skill

Quality Score

0/100

Supported Platforms

Universal

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

| benchmark | u256 time/op | big time/op | time diff | u256 B/op| big B/op | B diff| u256 allocs/op | big allocs/op | allocs diff | |--|--|--|--|--|--|--|--|--|--| | And/single | 2.03ns | 8.46ns | -76.04% | 0 | 0 | ~ | 0 | 0 | ~| | Or/single | 2.03ns | 10.98ns | -81.51% | 0 | 0 | ~ | 0 | 0 | ~| | Xor/single | 2.03ns | 12.19ns | -83.34% | 0 | 0 | ~ | 0 | 0 | ~| | Rsh/n_eq_0 | 5.00ns | 48.11ns | -89.61% | 0 | 64 | -100.00% | 0 | 1 | -100.00%| | Rsh/n_gt_0 | 10.42ns | 48.41ns | -78.48% | 0 | 64 | -100.00% | 0 | 1 | -100.00%| | Rsh/n_gt_64 | 6.94ns | 52.39ns | -86.76% | 0 | 64 | -100.00% | 0 | 1 | -100.00%| | Rsh/n_gt_128 | 5.49ns | 44.21ns | -87.59% | 0 | 48 | -100.00% | 0 | 1 | -100.00%| | Rsh/n_gt_192 | 3.43ns | 28.71ns | -88.04% | 0 | 8 | -100.00% | 0 | 1 | -100.00%| | Lsh/n_eq_0 | 4.89ns | 40.49ns | -87.92% | 0 | 64 | -100.00% | 0 | 1 | -100.00%| | Lsh/n_gt_0 | 10.14ns | 53.25ns | -80.96% | 0 | 80 | -100.00% | 0 | 1 | -100.00%| | Lsh/n_gt_64 | 7.50ns | 53.92ns | -86.08% | 0 | 80 | -100.00% | 0 | 1 | -100.00%| | Lsh/n_gt_128 | 5.39ns | 56.86ns | -90.52% | 0 | 96 | -100.00% | 0 | 1 | -100.00%| | Lsh/n_gt_192 | 3.90ns | 57.61ns | -93.23% | 0 | 96 | -100.00% | 0 | 1 | -100.00%|

Conversions

| benchmark | u256 time/op | big time/op | time diff | u256 B/op| big B/op | B diff| u256 allocs/op | big allocs/op | allocs diff | |--|--|--|--|--|--|--|--|--|--| | FromHexString | 116.70ns | 861.30ns | -86.45% | 32 | 88 | -63.64% | 1 | 3 | -66.67%| | FromDecimalString | 7973.00ns | 32850.00ns | -75.73% | 0 | 2464 | -100.00% | 0 | 77 | -100.00%| | Float64/Float64 | 2366.00ns | 28483.00ns | -91.69% | 0 | 23424 | -100.00% | 0 | 510 | -100.00%| | EncodeHex/large | 95.26ns | 184.30ns | -48.31% | 80 | 140 | -42.86% | 1 | 2 | -50.00%| | Decimal/ToDecimal | 67384.00ns | 83431.00ns | -19.23% | 11344 | 31920 | -64.46% | 248 | 594 | -58.25%| | Decimal/ToPrettyDecimal | 84208.00ns | 123953.00ns | -32.06% | 14720 | 61376 | -76.02% | 251 | 1100 | -77.18%|

Math

| benchmark | u256 time/op | big time/op | time diff | u256 B/op| big B/op | B diff| u256 allocs/op | big allocs/op | allocs diff | |--|--|--|--|--|--|--|--|--|--| | Add/single | 1.99ns | 18.11ns | -89.02% | 0 | 0 | ~ | 0 | 0 | ~| | Sub/single | 2.00ns | 17.19ns | -88.35% | 0 | 0 | ~ | 0 | 0 | ~| | Mul/single | 12.10ns | 57.69ns | -79.03% | 0 | 0 | ~ | 0 | 0 | ~| | SDiv/large | 94.64ns | 642.10ns | -85.26% | 0 | 312 | -100.00% | 0 | 6 | -100.00%| | Sqrt/single | 594.90ns | 1844.00ns | -67.74% | 0 | 528 | -100.00% | 0 | 7 | -100.00%| | Square/single | 12.49ns | 56.10ns | -77.74% | 0 | 0 | ~ | 0 | 0 | ~| | Cmp/single | 4.78ns | 12.79ns | -62.61% | 0 | 0 | ~ | 0 | 0 | ~| | Div/small | 12.91ns | 48.31ns | -73.28% | 0 | 8 | -100.00% | 0 | 1 | -100.00%| | Div/mod64 | 65.77ns | 111.20ns | -40.85% | 0 | 8 | -100.00% | 0 | 1 | -100.00%| | Div/mod128 | 93.67ns | 301.40ns | -68.92% | 0 | 80 | -100.00% | 0 | 1 | -100.00%| | Div/mod192 | 86.52ns | 263.80ns | -67.20% | 0 | 80 | -100.00% | 0 | 1 | -100.00%| | Div/mod256 | 77.17ns | 252.80ns | -69.47% | 0 | 80 | -100.00% | 0 | 1 | -100.00%| | AddMod/small | 13.84ns | 48.16ns | -71.26% | 0 | 4 | -100.00% | 0 | 0 | ~| | AddMod/mod64 | 22.83ns | 57.58ns | -60.35% | 0 | 11 | -100.00% | 0 | 0 | ~| | AddMod/mod128 | 48.31ns | 145.00ns | -66.68% | 0 | 12 | -100.00% | 0 | 0 | ~| | AddMod/mod192 | 47.26ns | 160.00ns | -70.46% | 0 | 12 | -100.00% | 0 | 0 | ~| | AddMod/mod256 | 14.44ns | 143.20ns | -89.92% | 0 | 12 | -100.00% | 0 | 0 | ~| | MulMod/small | 40.81ns | 63.14ns | -35.37% | 0 | 8 | -100.00% | 0 | 1 | -100.00%| | MulMod/mod64 | 91.66ns | 112.60ns | -18.60% | 0 | 48 | -100.00% | 0 | 1 | -100.00%| | MulMod/mod128 | 136.00ns | 362.70ns | -62.50% | 0 | 128 | -100.00% | 0 | 2 | -100.00%| | MulMod/mod192 | 151.70ns | 421.20ns | -63.98% | 0 | 144 | -100.00% | 0 | 2 | -100.00%| | MulMod/mod256 | 188.80ns | 489.20ns | -61.41% | 0 | 176 | -100.00% | 0 | 2 | -100.00%| | Exp/small | 433.70ns | 7490.00ns | -94.21% | 0 | 7392 | -100.00% | 0 | 77 | -100.00%| | Exp/large | 5145.00ns | 23043.00ns | -77.67% | 0 | 18144 | -100.00% | 0 | 189 | -100.00%| | Mod/mod64 | 70.94ns | 118.90ns | -40.34% | 0 | 64 | -100.00% | 0 | 1 | -100.00%| | Mod/small | 14.82ns | 46.27ns | -67.97% | 0 | 8 | -100.00% | 0 | 1 | -100.00%| | Mod/mod128 | 99.58ns | 286.90ns | -65.29% | 0 | 64 | -100.00% | 0 | 1 | -100.00%| | Mod/mod192 | 95.31ns | 269.30ns | -64.61% | 0 | 48 | -100.00% | 0 | 1 | -100.00%| | Mod/mod256 | 84.13ns | 222.90ns | -62.26% | 0 | 8 | -100.00% | 0 | 1 | -100.00%| | MulOverflow/single | 27.68ns | 57.52ns | -51.88% | 0 | 0 | ~ | 0 | 0 | ~| | MulDivOverflow/small | 2.83ns | 22.97ns | -87.69% | 0 | 0 | ~ | 0 | 0 | ~| | MulDivOverflow/div64 | 2.85ns | 23.13ns | -87.66% | 0 | 0 | ~ | 0 | 0 | ~| | MulDivOverflow/div128 | 3.14ns | 31.29ns | -89.96% | 0 | 2 | -100.00% | 0 | 0 | ~| | MulDivOverflow/div192 | 3.17ns | 30.28ns | -89.54% | 0 | 2 | -100.00% | 0 | 0 | ~| | MulDivOverflow/div256 | 3.54ns | 35.56ns | -90.06% | 0 | 5 | -100.00% | 0 | 0 | ~| | Lt/small | 3.12ns | 10.43ns | -70.06% | 0 | 0 | ~ | 0 | 0 | ~| | Lt/large | 3.49ns | 10.32ns | -66.18% | 0 | 0 | ~ | 0 | 0 | ~|

Other

| benchmark | u256 time/op | u256 B/op| u256 allocs/op | |--|--|--|--| | SetBytes/generic | 104.30ns | 0 | 0 || | Sub/single/uint256_of | 1.99ns | 0 | 0 || | SetFromBig/overflow | 3.57ns | 0 | 0 || | ToBig/2words | 73.84ns | 64 | 2 || | SetBytes/specific | 45.81ns | 0 | 0 || | ScanScientific | 674.10ns | 0 | 0 || | SetFromBig/4words | 3.82ns | 0 | 0 || | ToBig/4words | 68.82ns | 64 | 2 || | RLPEncoding | 11917.00ns | 11911 | 255 || | SetFromBig/1word | 2.99ns | 0 | 0 || | SetFromBig/3words | 4.12ns | 0 | 0 || | ToBig/3words | 70.12ns | 64 | 2 || | ToBig/1word | 75.38ns | 64 | 2 || | MulMod/mod256/uint256r | 77.11ns | 0 | 0 || | HashTreeRoot | 11.27ns | 0 | 0 || | SetFromBig/2words | 3.90ns | 0 | 0 ||

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

View on GitHub
GitHub Stars373
CategoryDevelopment
Updated13d ago
Forks79

Languages

Go

Security Score

95/100

Audited on Mar 20, 2026

No findings