Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

github.com/decred/dcrd/math/uint256

Package Overview
Dependencies
Alerts
File Explorer
Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

github.com/decred/dcrd/math/uint256

  • v1.0.2
  • Source
  • Go
  • Socket score

Version published
Created
Source

uint256

Build Status ISC License Doc

Fixed Precision Unsigned 256-bit Integer Arithmetic

This package implements highly optimized allocation free fixed precision unsigned 256-bit integer arithmetic.

The following is a brief overview of the main features and benefits:

  • Strong focus on performance and correctness
    • Every operation is faster than the stdlib big.Int equivalent and most operations, including the primary math operations, are significantly faster (see performance comparison benchmarks)
  • Allocation free
    • All non-formatting operations with the specialized type are allocation free
  • Supports boolean comparison, bitwise logic, and bitwise shift operations
  • All operations are performed modulo 2^256
  • Ergonomic API with unary-style arguments as well as some binary variants
    • eg: n.SetUint64(1).Lsh(64).SubUint64(1) is equivalent to n = 1<<64 - 1
    • eg: n.Div2(n1, n2) is equivalent to n = n1/n2
  • Conversion-free support for interoperation with native uint64 integers
  • Direct conversion to and from little and big endian byte arrays
  • Full support for formatted output and common base conversions
    • Producing formatted output uses fewer allocations than big.Int
  • 100% test coverage
  • Comprehensive benchmarks

The primary big.Int operations that are NOT currently provided:

  • Modular arithmetic with moduli other than 2^256
  • Signed arithmetic
    • A caller could fairly easily implement it with 2's complement if desired since Negate is provided
  • Remainders from division

These operations may be implemented in the future if the need arises.

Note About Standard Library math/big.Int Conversions

This package provides convenience methods for converting to and from standard library big.Ints, however, callers should make an active effort to avoid that unless it is absolutely necessary as conversion to big.Int requires an unavoidable allocation in most circumstances and big.Int is also slower for every operation, often to a significant degree. Further, big.Ints often cause further allocations while performing arithmetic, notably multiplication and division.

Regarding the aforementioned allocations, standard library big.Ints internally require heap allocations to operate, so conversion to a new big.Int necessarily causes an allocation. This means the ToBig method will always incur at least one allocation.

One feature of big.Ints is that they attempt to reuse their internal buffer when possible, so the number of allocations due to conversion can sometimes be reduced if reusing the same variable is an option. This package provides a PutBig method which allows callers to reuse an existing big.Int for this purpose.

Do note however that even when reusing a big.Int, it will naturally still require an allocation for the internal buffer unless it has already previously allocated one large enough to be reused.

Categorized Uint256 Summary

This section summarizes the majority of the available operations provided by category. See the full documentation for additional details about individual methods and additional available methods.

Arithmetic Methods

OperationNative EquivMethods
Add Assignn += xAdd, AddUint64
Addn = x + yAdd2
Subtract Assignn -= xSub, SubUint64
Subtractn = x - ySub2
Multiply Assignn *= xMul, MulUint64
Multiplyn = x * yMul2
Divide Assignn /= xDiv
Dividen = x / yDiv2
Square Assignn *= nSquare
Squaren = x * xSquareVal
Negate Assignn = -nNegate
Negaten = -xNegateVal

Comparison Methods

OperationNative EquivMethods
Equalityx == yEq, EqUint64
Less Thanx < yLt, LtUint64
Less Or Equalx <= yLtEq, LtEqUint64
Greater Thanx > yGt, GtUint64
Greater Or Equalx >= yGtEq, GtEqUint64
Comparisonn/aCmp, CmpUint64

Bitwise Methods

OperationNative EquivMethod
And Assignn &= xAnd
Or Assignn |= xOr
Xor Assignn ^= xXor
Not Assignn = ^xNot
Left Shift Assignn <<= xLsh
Left Shiftn = x << yLshVal
Right Shift Assignn >>= xRsh
Right Shiftn = x >> yRshVal
Bit Lengthn/aBitLen

Conversion Methods

OperationMethods
From Big EndianSetBytes, SetByteSlice
To Big EndianBytes, PutBytes, PutBytesUnchecked
From Little EndianSetBytesLE, SetByteSliceLE
To Little EndianBytesLE, PutBytesLE, PutBytesUncheckedLE
From math/big.IntSetBig
To math/big.IntToBig, PutBig

Misc Convenience Methods

OperationMethod
Can represent with uint32?IsUint32
Value modulo 2^32Uint32
Can represent with uint64?IsUint64
Value modulo 2^64Uint64
Set to 0Zero
Is equal to zero?IsZero
Is the value odd?IsOdd

Output Formatting Methods

OperationMethod
Binary/Octal/Decimal/HexText
Standard Formatted output (fmt.Formatter)Format
Standard Unformatted output (fmt.Stringer)String

Uint256 Performance Comparison

The following benchmark results demonstrate the performance of most operations as compared to standard library big.Ints. The benchmarks are from a Ryzen 7 1700 processor and are the result of feeding benchstat 10 iterations of each.

Arithmetic Methods

Namebig.Int Time/OpUint256 Time/OpDelta vs big.Int
Add158ns ± 2%2ns ± 1%-98.67%
AddUint6444.4ns ± 3%3.4ns ± 2%-92.27%
Sub53.9ns ± 1%2.1ns ± 1%-96.12%
SubUint6444.8ns ± 1%3.4ns ± 2%-92.37%
Mul419ns ± 1%10ns ± 2%-97.64%
MulUint64263ns ± 1%4ns ± 1%-98.30%
Square418ns ± 0%7ns ± 2%-98.39%
Div/num_lt_den75.4ns ± 1%3.4ns ± 1%-95.51%
Div/num_eq_den253ns ± 2%4ns ± 3%-98.56%
Div/1_by_1_near53.8ns ± 2%4.5ns ± 2%-91.63%
Div/1_by_1_far31.4ns ± 2%14.6ns ± 2%-53.64%
Div/2_by_1_near36.9ns ± 1%10.1ns ± 2%-72.63%
Div/2_by_1_far49.1ns ± 1%28.8ns ± 1%-41.29%
Div/3_by_1_near43.2ns ± 1%13.7ns ± 3%-68.24%
Div/3_by_1_far57.0ns ± 1%43.6ns ± 1%-23.59%
Div/4_by_1_near49.7ns ± 4%18.0ns ± 1%-63.87%
Div/4_by_1_far65.2ns ± 4%57.8ns ± 2%-11.41%
Div/2_by_2_near237ns ± 1%22ns ± 3%-90.81%
Div/2_by_2_far237ns ± 1%30ns ± 3%-87.17%
Div/3_by_2_near258ns ± 1%29ns ± 1%-88.60%
Div/3_by_2_far257ns ± 1%50ns ± 2%-80.42%
Div/4_by_2_near312ns ± 2%40ns ± 3%-87.27%
Div/4_by_2_far310ns ± 1%71ns ± 3%-77.19%
Div/3_by_3_near239ns ± 2%21ns ± 2%-91.39%
Div/3_by_3_far242ns ± 4%33ns ± 3%-86.33%
Div/4_by_3_near279ns ± 6%31ns ± 1%-89.01%
Div/4_by_3_far271ns ± 1%46ns ± 3%-82.99%
Div/4_by_4_near252ns ± 3%20ns ± 3%-91.99%
Div/4_by_4_far249ns ± 2%36ns ± 2%-85.65%
DivRandom202ns ± 1%23ns ± 1%-88.43%
DivUint64129ns ± 1%47ns ± 0%-63.34%
Negate47.3ns ± 2%1.5ns ± 2%-96.91%

Comparison Methods

Namebig.Int Time/OpUint256 Time/OpDelta vs big.Int
Eq12.7ns ± 1%2.1ns ± 1%-83.72%
Lt12.6ns ± 1%3.0ns ± 1%-75.96%
Gt12.6ns ± 1%3.0ns ± 1%-75.91%
Cmp12.6ns ± 1%7.7ns ± 1%-39.01%
CmpUint645.93ns ± 2%3.70ns ± 1%-37.60%

Bitwise Methods

Namebig.Int Time/OpUint256 Time/OpDelta vs big.Int
Lsh/bits_07.15ns ± 3%2.58ns ± 1%-63.94%
Lsh/bits_114.8ns ± 1%4.2ns ± 1%-71.40%
Lsh/bits_6416.7ns ± 1%2.7ns ± 1%-84.00%
Lsh/bits_12816.9ns ± 2%2.7ns ± 0%-84.21%
Lsh/bits_19216.6ns ± 1%2.6ns ± 1%-84.19%
Lsh/bits_25516.3ns ± 2%2.8ns ± 2%-83.11%
Lsh/bits_25616.9ns ± 2%2.6ns ± 2%-84.77%
Rsh/bits_08.76ns ± 2%2.57ns ± 1%-70.63%
Rsh/bits_114.4ns ± 2%4.3ns ± 2%-70.28%
Rsh/bits_6412.8ns ± 1%2.9ns ± 2%-77.31%
Rsh/bits_12811.8ns ± 0%2.9ns ± 2%-75.51%
Rsh/bits_19210.5ns ± 2%2.6ns ± 1%-75.17%
Rsh/bits_25510.5ns ± 3%2.8ns ± 2%-73.89%
Rsh/bits_2565.50ns ± 1%2.58ns ± 2%-53.15%
Not25.4ns ± 2%3.3ns ± 2%-86.79%
Or17.9ns ± 5%3.4ns ± 6%-80.94%
And16.7ns ± 2%3.4ns ± 0%-79.93%
Xor17.9ns ± 1%3.4ns ± 2%-80.91%
BitLen/bits_642.24ns ± 1%1.94ns ± 3%-13.04%
BitLen/bits_1282.25ns ± 2%1.96ns ± 2%-13.17%
BitLen/bits_1922.25ns ± 1%1.60ns ± 1%-28.65%
BitLen/bits_2552.26ns ± 2%1.61ns ± 1%-29.04%

Conversion Methods

Namebig.Int Time/OpUint256 Time/OpDelta vs big.Int
SetBytes9.09ns ±13%3.05ns ± 1%-66.43%
SetBytesLE59.9ns ± 4%3.1ns ± 2%-94.76%
Bytes61.3ns ± 1%13.8ns ± 3%-77.49%
BytesLE83.5ns ± 2%13.9ns ± 2%-83.32%

Misc Convenience Methods

Namebig.Int Time/OpUint256 Time/OpDelta vs big.Int
Zero2.99ns ± 2%1.29ns ± 1%-56.82%
IsZero1.78ns ± 0%1.63ns ± 2%-8.23%
IsOdd3.62ns ± 4%1.64ns ± 1%-54.65%

Output Formatting Methods

Namebig.Int Time/OpUint256 Time/OpDelta vs big.Int
Text/base_2579ns ± 3%496ns ± 2%-14.37%
Text/base_8266ns ± 1%227ns ± 1%-14.58%
Text/base_10536ns ± 1%458ns ± 2%-14.58%
Text/base_16205ns ± 2%180ns ± 4%-11.90%
Format/base_2987ns ±15%852ns ± 2%-13.64%
Format/base_8620ns ± 6%544ns ± 3%-12.31%
Format/base_10888ns ± 1%726ns ± 1%-18.25%
Format/base_16565ns ± 1%449ns ± 1%-20.41%

Installation and Updating

This package is part of the github.com/decred/dcrd/math/uint256 module. Use the standard go tooling for working with modules to incorporate it.

Examples

  • Basic Usage
    Demonstrates calculating the result of a dividing a max unsigned 256-bit integer by a max unsigned 128-bit integer and outputting that result in hex with leading zeros.

License

Package uint256 is licensed under the copyfree ISC License.

FAQs

Package last updated on 23 Aug 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc