uints

package
v0.14.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 22, 2025 License: Apache-2.0 Imports: 10 Imported by: 60

Documentation

Overview

Package uints implements optimised byte and long integer operations.

Usually arithmetic in a circuit is performed in the native field, which is of prime order. However, for compatibility with native operations we rely on operating on smaller primitive types as 8-bit, 32-bit and 64-bit integer. Naively, these operations have to be implemented bitwise as there are no closed equations for boolean operations (XOR, AND, OR).

However, the bitwise approach is very inefficient and leads to several constraints per bit. Accumulating over a long integer, it leads to very inefficients circuits.

This package performs boolean operations using lookup tables on bytes. So, long integers are split into 4 or 8 bytes and we perform the operations bytewise. In the lookup tables, we store results for all possible 2^8×2^8 inputs. With this approach, every bytewise operation costs as single lookup, which depending on the backend is relatively cheap (one to three constraints).

NB! The package is still work in progress. The interfaces and implementation details most certainly changes over time. We cannot ensure the soundness of the operations.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetHints

func GetHints() []solver.Hint

Types

type BinaryField

type BinaryField[T Long] struct {
	*Bytes
}

func New

func New[T Long](api frontend.API) (*BinaryField[T], error)

New is an alias to NewBinaryField. It is retained for backwards compatibility. New uses should use NewBinaryField instead.

func NewBinaryField added in v0.14.0

func NewBinaryField[T Long](api frontend.API) (*BinaryField[T], error)

NewBinaryField creates a new BinaryField for the given integer type T specified by parameter Long. It allows to manipulate long integers in circuit.

func (*BinaryField[T]) Add

func (bf *BinaryField[T]) Add(a ...T) T

func (*BinaryField[T]) And

func (bf *BinaryField[T]) And(a ...T) T

func (*BinaryField[T]) AssertEq

func (bf *BinaryField[T]) AssertEq(a, b T)

func (*BinaryField[T]) ByteAssertEq

func (bf *BinaryField[T]) ByteAssertEq(a, b U8)

func (*BinaryField[T]) ByteValueOf

func (bf *BinaryField[T]) ByteValueOf(a frontend.Variable) U8

ByteValueOf converts a frontend.Variable into a single byte. If the input doesn't fit into a byte then solver fails.

func (*BinaryField[T]) Lrot

func (bf *BinaryField[T]) Lrot(a T, c int) T

func (*BinaryField[T]) Not

func (bf *BinaryField[T]) Not(a T) T

func (*BinaryField[T]) Or added in v0.12.0

func (bf *BinaryField[T]) Or(a ...T) T

func (*BinaryField[T]) PackLSB

func (bf *BinaryField[T]) PackLSB(a ...U8) T

func (*BinaryField[T]) PackMSB

func (bf *BinaryField[T]) PackMSB(a ...U8) T

func (*BinaryField[T]) Rshift

func (bf *BinaryField[T]) Rshift(a T, c int) T

func (*BinaryField[T]) ToValue

func (bf *BinaryField[T]) ToValue(a T) frontend.Variable

ToValue converts a long integer value into a single frontend.Variable.

func (*BinaryField[T]) UnpackLSB

func (bf *BinaryField[T]) UnpackLSB(a T) []U8

func (*BinaryField[T]) UnpackMSB

func (bf *BinaryField[T]) UnpackMSB(a T) []U8

func (*BinaryField[T]) ValueOf

func (bf *BinaryField[T]) ValueOf(a frontend.Variable) T

ValueOf converts a frontend.Variable into a long integer. If the input doesn't fit into T then solver fails.

func (*BinaryField[T]) Xor

func (bf *BinaryField[T]) Xor(a ...T) T

type Bytes added in v0.14.0

type Bytes struct {
	// contains filtered or unexported fields
}

Bytes implements methods for manipulating bytes in circuit. Use NewBytes to create a new instance.

func NewBytes added in v0.14.0

func NewBytes(api frontend.API) (*Bytes, error)

NewBytes creates a new Bytes instance which can manipulate bytes and byte arrays. For manipulating long integers, use BinaryField instead.

This is a caching constructor, meaning that it will return the same instance if called multiple times. This is useful as internally it uses lookup tables for bitwise operations and it amortizes the cost of creating these lookup tables.

func (*Bytes) And added in v0.14.0

func (bf *Bytes) And(a ...U8) U8

func (*Bytes) AssertIsEqual added in v0.14.0

func (bf *Bytes) AssertIsEqual(a, b U8)

func (*Bytes) Not added in v0.14.0

func (bf *Bytes) Not(a U8) U8

func (*Bytes) Or added in v0.14.0

func (bf *Bytes) Or(a ...U8) U8

func (*Bytes) Select added in v0.14.0

func (bf *Bytes) Select(selector frontend.Variable, a, b U8) U8

Select returns a new U8 value which is:

  • if selector is true then a
  • if selector is false then b

func (*Bytes) Value added in v0.14.0

func (bf *Bytes) Value(a U8) frontend.Variable

Value returns the value of the U8 variables, ensuring that it is range checked. It is preferrable to use this method instead of directly using the [U8.Val] field.

func (*Bytes) ValueOf added in v0.14.0

func (bf *Bytes) ValueOf(a frontend.Variable) U8

ValueOf returns a constrainted U8 variable. For a constant value, use NewU8 instead.

func (*Bytes) ValueUnchecked added in v0.14.0

func (bf *Bytes) ValueUnchecked(a U8) frontend.Variable

ValueUnchecked returns the value of the U8 variables without range checking.

func (*Bytes) Xor added in v0.14.0

func (bf *Bytes) Xor(a ...U8) U8

type Long

type Long interface{ U32 | U64 }

type U32

type U32 [4]U8

func NewU32

func NewU32(v uint32) U32

NewU32 creates a new U32 value. It represents a 32-bit unsigned integer which is split into 4 bytes. It can both be used in-circuit to initialize a constant or as a witness assignment. For in-circuit initialization use BinaryField.ValueOf method instead which ensures that the value is range checked.

func NewU32Array

func NewU32Array(v []uint32) []U32

NewU32Array is a utility method to create a slice of U32 from a slice of uint32.

type U64

type U64 [8]U8

func NewU64

func NewU64(v uint64) U64

NewU64 creates a new U64 value. It represents a 64-bit unsigned integer which is split into 4 bytes. It can both be used in-circuit to initialize a constant or as a witness assignment. For in-circuit initialization use BinaryField.ValueOf method instead which ensures that the value is range checked.

func NewU64Array

func NewU64Array(v []uint64) []U64

NewU64Array is a utility method to create a slice of U64 from a slice of uint64.

type U8

type U8 struct {
	// Val is the value of the byte. It can be a constant or a variable.
	// NB! dont't access it directly!
	Val frontend.Variable
	// contains filtered or unexported fields
}

U8 represents a single byte (uint8) in the circuit. Users should not create U8 values directly, but rather use NewU8 (for in-circuit constant initialization or witness assignment) or Bytes.ValueOf (for in-circuit variable initialization).

Users should not access the [U8.Val] field directly, but rather use Bytes.Value method to ensure that the value is range checked to be 8 bits.

func NewU8

func NewU8(v uint8) U8

NewU8 creates a new U8 value. It represents a single byte. It can both be used in-circuit to initialize a constant or as a witness assignment. For in-circuit initialization use Bytes.ValueOf method instead which ensures that the value is range checked.

func NewU8Array

func NewU8Array(v []uint8) []U8

NewU8Array is a utility method to create a slice of U8 from a slice of uint8.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL