bn256

package module
v0.0.0-...-496ed39 Latest Latest
Warning

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

Go to latest
Published: Mar 9, 2025 License: BSD-3-Clause Imports: 9 Imported by: 0

README

BN256

Build Status

This package implements a particular bilinear group. The code is imported from https://github.com/ethereum/go-ethereum/tree/master/crypto/bn256/cloudflare

🚨 WARNING This package originally claimed to operate at a 128-bit level. However, recent work suggest that this is no longer the case.

A note on the selection of the bilinear group

The parameters defined in the constants.go file follow the parameters used in alt-bn128 (libff). These parameters were selected so that r−1 has a high 2-adic order. This is key to improve efficiency of the key and proof generation algorithms of the SNARK used.

Installation

go get github.com/clearmatics/bn256

Development

This project uses go modules. If you develop in your GOPATH and use GO 1.11, make sure to run:

export GO111MODULE=on

In fact:

(Inside $GOPATH/src, for compatibility, the go command still runs in the old GOPATH mode, even if a go.mod is found.) See: https://blog.golang.org/using-go-modules

For more fine-grained control, the module support in Go 1.11 respects a temporary environment variable, GO111MODULE, which can be set to one of three string values: off, on, or auto (the default). If GO111MODULE=off, then the go command never uses the new module support. Instead it looks in vendor directories and GOPATH to find dependencies; we now refer to this as "GOPATH mode." If GO111MODULE=on, then the go command requires the use of modules, never consulting GOPATH. We refer to this as the command being module-aware or running in "module-aware mode". If GO111MODULE=auto or is unset, then the go command enables or disables module support based on the current directory. Module support is enabled only when the current directory is outside GOPATH/src and itself contains a go.mod file or is below a directory containing a go.mod file. See: https://golang.org/cmd/go/#hdr-Preliminary_module_support

The project follows standard Go conventions using gofmt. If you wish to contribute to the project please follow standard Go conventions. The CI server automatically runs these checks.

Documentation

Overview

Package bn256 implements a particular bilinear group at the 128-bit security level.

Bilinear groups are the basis of many of the new cryptographic protocols that have been proposed over the past decade. They consist of a triplet of groups (G₁, G₂ and GT) such that there exists a function e(g₁ˣ,g₂ʸ)=gTˣʸ (where gₓ is a generator of the respective group). That function is called a pairing function.

This package specifically implements the Optimal Ate pairing over a 256-bit Barreto-Naehrig curve as described in http://cryptojedi.org/papers/dclxvi-20100714.pdf. Its output is compatible with the implementation described in that paper.

Package bn256 implements a particular bilinear group at the 128-bit security level.

Bilinear groups are the basis of many of the new cryptographic protocols that have been proposed over the past decade. They consist of a triplet of groups (G₁, G₂ and GT) such that there exists a function e(g₁ˣ,g₂ʸ)=gTˣʸ (where gₓ is a generator of the respective group). That function is called a pairing function.

This package specifically implements the Optimal Ate pairing over a 256-bit Barreto-Naehrig curve as described in http://cryptojedi.org/papers/dclxvi-20100714.pdf. Its output is compatible with the implementation described in that paper.

Package bn256 implements a particular bilinear group at the 128-bit security level.

Bilinear groups are the basis of many of the new cryptographic protocols that have been proposed over the past decade. They consist of a triplet of groups (G₁, G₂ and GT) such that there exists a function e(g₁ˣ,g₂ʸ)=gTˣʸ (where gₓ is a generator of the respective group). That function is called a pairing function.

This package specifically implements the Optimal Ate pairing over a 256-bit Barreto-Naehrig curve as described in http://cryptojedi.org/papers/dclxvi-20100714.pdf. Its output is compatible with the implementation described in that paper.

Index

Constants

View Source
const (
	FqElementSize      = 32
	G1CompressedSize   = FqElementSize + 1   // + 1 accounts for the additional byte used for masking
	G1UncompressedSize = 2*FqElementSize + 1 // + 1 accounts for the additional byte used for masking
)

Constants related to the bn256 pairing friendly curve

View Source
const (
	Fq2ElementSize     = 2 * FqElementSize
	G2CompressedSize   = Fq2ElementSize + 1   // + 1 accounts for the additional byte used for masking
	G2UncompressedSize = 2*Fq2ElementSize + 1 // + 1 accounts for the additional byte used for masking
)

Constants related to the bn256 pairing friendly curve

View Source
const FpUint64Size = 4

FpUint64Size is the number of uint64 chunks to represent a field element

Variables

View Source
var Order = bigFromBase10("21888242871839275222246405745257275088548364400416034343698204186575808495617")

Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u²+6u+1.

View Source
var P = bigFromBase10("21888242871839275222246405745257275088696311157297823662689037894645226208583")

P is a prime over which we form a basic field: 36u⁴+36u³+24u²+6u+1.

Functions

func PairingCheck

func PairingCheck(a []*G1, b []*G2) bool

PairingCheck calculates the Optimal Ate pairing for a set of points.

Types

type G1

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

G1 is an abstract cyclic group. The zero value is suitable for use as the output of an operation, but cannot be used as an input.

func RandomG1

func RandomG1(r io.Reader) (*big.Int, *G1, error)

RandomG1 returns x and g₁ˣ where x is a random, non-zero number read from r.

func (*G1) Add

func (e *G1) Add(a, b *G1) *G1

Add sets e to a+b and then returns e.

func (*G1) DecodeCompressed

func (e *G1) DecodeCompressed(encoding []byte) error

DecodeCompressed decodes a point in the compressed form Take a point P encoded (ie: written in affine form where each coordinate is MontDecoded) and encodes it by going back to Jacobian coordinates and montEncode all coordinates

func (*G1) DecodeUncompressed

func (e *G1) DecodeUncompressed(encoding []byte) error

DecodeUncompressed decodes a point in the uncompressed form Take a point P encoded (ie: written in affine form where each coordinate is MontDecoded) and encodes it by going back to Jacobian coordinates and montEncode all coordinates

func (e *G1) DecodeUncompressed(encoding []byte) error {
	if len(encoding) != G1UncompressedSize {
		return errors.New("wrong encoded point size")
	}
	if encoding[0]&serializationCompressed != 0 { // Also test the length of the encoding to make sure it is 65bytes
		return errors.New("point is compressed")
	}
	if encoding[0]&serializationBigY != 0 { // Also test that the bigY flag if not set
		return errors.New("bigY flag should not be set")
	}

	// Unmarshal the points and check their caps
	if e.p == nil {
		e.p = &curvePoint{}
	} else {
		e.p.x, e.p.y = gfP{0}, gfP{0}
		e.p.z, e.p.t = *newGFp(1), *newGFp(1)
	}

	// Removes the bits of the masking (This does a bitwise AND with `0001 1111`)
	// And thus removes the first 3 bits corresponding to the masking
	// Useless for now because in bn256, we added a full byte to enable masking
	// However, this is needed if we work over BLS12 and its underlying field
	bin := make([]byte, G1UncompressedSize)
	copy(bin, encoding)
	bin[0] &= serializationMask

	// Decode the point at infinity in the compressed form
	if encoding[0]&serializationInfinity != 0 {
		// Makes sense to check that all bytes of bin are 0x0 since we removed the masking above}
		for i := range bin {
			if bin[i] != 0 {
				return errors.New("invalid infinity encoding")
			}
		}
		e.p.SetInfinity()
		return nil
	}

	// Decode the point P (P =/= ∞)
	var err error
	// Decode the x-coordinate
	if err = e.p.x.Unmarshal(bin[1:33]); err != nil {
		return err
	}
	// Decode the y-coordinate
	if err = e.p.y.Unmarshal(bin[33:]); err != nil {
		return err
	}

	// MontEncode our field elements for fast finite field arithmetic
	montEncode(&e.p.x, &e.p.x)
	montEncode(&e.p.y, &e.p.y)

	if !e.p.IsOnCurve() {
		return errors.New("malformed point: Not on the curve")
	}

	return nil
}

func (*G1) EncodeCompressed

func (e *G1) EncodeCompressed() []byte

EncodeCompressed converts the compressed point e into bytes This function takes a point in the Jacobian form This function does not modify the point e (the variable `temp` is introduced to avoid to modify e)

func (*G1) EncodeUncompressed

func (e *G1) EncodeUncompressed() []byte

EncodeUncompressed converts the compressed point e into bytes Take a point P in Jacobian form (where each coordinate is MontEncoded) and encodes it by going back to affine coordinates and montDecode all coordinates This function does not modify the point e (the variable `temp` is introduced to avoid to modify e)

func (e *G1) EncodeUncompressed() []byte {
	// Check nil pointers
	if e.p == nil {
		e.p = &curvePoint{}
	}

	e.p.MakeAffine()
	ret := make([]byte, G1UncompressedSize)

	if e.p.IsInfinity() {
		// Flag the encoding with the infinity flag
		ret[0] |= serializationInfinity
		return ret
	}

	// We start the serialization of the coordinates at the index 1
	// Since the index 0 in the `ret` corresponds to the masking
	temp := &gfP{}
	montDecode(temp, &e.p.x) // Store the montgomery decoding in temp
	temp.Marshal(ret[1:33])  // Write temp in the `ret` slice, this is the x-coordinate
	montDecode(temp, &e.p.y)
	temp.Marshal(ret[33:]) // this is the y-coordinate

	return ret
}

func (*G1) IsHigherY

func (e *G1) IsHigherY() bool

IsHigherY is used to distinguish between the 2 points of E that have the same x-coordinate The point e is assumed to be given in the affine form

func (*G1) Marshal

func (e *G1) Marshal() []byte

Marshal converts e to a byte slice.

func (*G1) Neg

func (e *G1) Neg(a *G1) *G1

Neg sets e to -a and then returns e.

func (*G1) ScalarBaseMult

func (e *G1) ScalarBaseMult(k *big.Int) *G1

ScalarBaseMult sets e to g*k where g is the generator of the group and then returns e.

func (*G1) ScalarMult

func (e *G1) ScalarMult(a *G1, k *big.Int) *G1

ScalarMult sets e to a*k and then returns e.

func (*G1) Set

func (e *G1) Set(a *G1) *G1

Set sets e to a and then returns e.

func (*G1) String

func (e *G1) String() string

func (*G1) Unmarshal

func (e *G1) Unmarshal(m []byte) ([]byte, error)

Unmarshal sets e to the result of converting the output of Marshal back into a group element and then returns e.

type G2

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

G2 is an abstract cyclic group. The zero value is suitable for use as the output of an operation, but cannot be used as an input.

func RandomG2

func RandomG2(r io.Reader) (*big.Int, *G2, error)

RandomG2 returns x and g₂ˣ where x is a random, non-zero number read from r.

func (*G2) Add

func (e *G2) Add(a, b *G2) *G2

Add sets e to a+b and then returns e.

func (*G2) DecodeCompressed

func (e *G2) DecodeCompressed(encoding []byte) error

DecodeCompressed decodes a point in the compressed form Take a point P in G2 decoded (ie: written in affine form where each coordinate is MontDecoded) and encodes it by going back to Jacobian coordinates and montEncode all coordinates

func (*G2) DecodeUncompressed

func (e *G2) DecodeUncompressed(encoding []byte) error

DecodeUncompressed decodes a point in the uncompressed form Take a point P encoded (ie: written in affine form where each coordinate is MontDecoded) and encodes it by going back to Jacobian coordinates and montEncode all coordinates

func (*G2) EncodeCompressed

func (e *G2) EncodeCompressed() []byte

func (*G2) EncodeUncompressed

func (e *G2) EncodeUncompressed() []byte

EncodeUncompressed converts the compressed point e into bytes Take a point P in Jacobian form (where each coordinate is MontEncoded) and encodes it by going back to affine coordinates and montDecode all coordinates This function does not modify the point e (the variable `temp` is introduced to avoid to modify e)

func (*G2) IsHigherY

func (e *G2) IsHigherY() bool

func (*G2) Marshal

func (e *G2) Marshal() []byte

Marshal converts e into a byte slice.

func (*G2) Neg

func (e *G2) Neg(a *G2) *G2

Neg sets e to -a and then returns e.

func (*G2) ScalarBaseMult

func (e *G2) ScalarBaseMult(k *big.Int) *G2

ScalarBaseMult sets e to g*k where g is the generator of the group and then returns out.

func (*G2) ScalarMult

func (e *G2) ScalarMult(a *G2, k *big.Int) *G2

ScalarMult sets e to a*k and then returns e.

func (*G2) Set

func (e *G2) Set(a *G2) *G2

Set sets e to a and then returns e.

func (*G2) String

func (e *G2) String() string

func (*G2) Unmarshal

func (e *G2) Unmarshal(m []byte) ([]byte, error)

Unmarshal sets e to the result of converting the output of Marshal back into a group element and then returns e.

type GT

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

GT is an abstract cyclic group. The zero value is suitable for use as the output of an operation, but cannot be used as an input.

func Miller

func Miller(g1 *G1, g2 *G2) *GT

Miller applies Miller's algorithm, which is a bilinear function from the source groups to F_p^12. Miller(g1, g2).Finalize() is equivalent to Pair(g1, g2).

func Pair

func Pair(g1 *G1, g2 *G2) *GT

Pair calculates an Optimal Ate pairing.

func (*GT) Add

func (e *GT) Add(a, b *GT) *GT

Add sets e to a+b and then returns e.

func (*GT) Finalize

func (e *GT) Finalize() *GT

Finalize is a linear function from F_p^12 to GT.

func (*GT) Marshal

func (e *GT) Marshal() []byte

Marshal converts e into a byte slice.

func (*GT) Neg

func (e *GT) Neg(a *GT) *GT

Neg sets e to -a and then returns e.

func (*GT) ScalarMult

func (e *GT) ScalarMult(a *GT, k *big.Int) *GT

ScalarMult sets e to a*k and then returns e.

func (*GT) Set

func (e *GT) Set(a *GT) *GT

Set sets e to a and then returns e.

func (*GT) String

func (e *GT) String() string

func (*GT) Unmarshal

func (e *GT) Unmarshal(m []byte) ([]byte, error)

Unmarshal sets e to the result of converting the output of Marshal back into a group element and then returns e.

Directories

Path Synopsis
golang.org
x/crypto/hkdf
Package hkdf implements the HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as defined in RFC 5869.
Package hkdf implements the HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as defined in RFC 5869.
x/sys/cpu
Package cpu implements processor feature detection for various CPU architectures.
Package cpu implements processor feature detection for various CPU architectures.

Jump to

Keyboard shortcuts

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