pbc

package module
v0.0.0-...-4846b84 Latest Latest
Warning

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

Go to latest
Published: Aug 8, 2022 License: GPL-3.0 Imports: 12 Imported by: 0

README

The PBC Go Wrapper Build Status GoDoc

Package pbc provides structures for building pairing-based cryptosystems. It is a wrapper around the Pairing-Based Cryptography (PBC) Library authored by Ben Lynn (https://crypto.stanford.edu/pbc/).

This wrapper provides access to all PBC functions. It supports generation of various types of elliptic curves and pairings, element initialization, I/O, and arithmetic. These features can be used to quickly build pairing-based or conventional cryptosystems.

The PBC library is designed to be extremely fast. Internally, it uses GMP for arbitrary-precision arithmetic. It also includes a wide variety of optimizations that make pairing-based cryptography highly efficient. To improve performance, PBC does not perform type checking to ensure that operations actually make sense. The Go wrapper provides the ability to add compatibility checks to most operations, or to use unchecked elements to maximize performance.

Since this library provides low-level access to pairing primitives, it is very easy to accidentally construct insecure systems. This library is intended to be used by cryptographers or to implement well-analyzed cryptosystems.

Features

  • 5 different pairing types
  • Pairing generation
  • Parameter export and import
  • Element type checking
  • Fast element arithmetic and pairing
  • Element randomization
  • Element export and import
  • Automatic garbage collection
  • Integration with fmt
  • Integration with math/big

Dependencies

This package must be compiled using cgo. It also requires the installation of GMP and PBC. During the build process, this package will attempt to include gmp.h and pbc/pbc.h, and then dynamically link to GMP and PBC. Installation on Windows requires the use of MinGW.

Documentation

For additional installation instructions and documentation, see https://godoc.org/github.com/Nik-U/pbc

Documentation

Overview

Package pbc provides structures for building pairing-based cryptosystems. It is a wrapper around the Pairing-Based Cryptography (PBC) Library authored by Ben Lynn (https://crypto.stanford.edu/pbc/).

This wrapper provides access to all PBC functions. It supports generation of various types of elliptic curves and pairings, element initialization, I/O, and arithmetic. These features can be used to quickly build pairing-based or conventional cryptosystems.

The PBC library is designed to be extremely fast. Internally, it uses GMP for arbitrary-precision arithmetic. It also includes a wide variety of optimizations that make pairing-based cryptography highly efficient. To improve performance, PBC does not perform type checking to ensure that operations actually make sense. The Go wrapper provides the ability to add compatibility checks to most operations, or to use unchecked elements to maximize performance.

Since this library provides low-level access to pairing primitives, it is very easy to accidentally construct insecure systems. This library is intended to be used by cryptographers or to implement well-analyzed cryptosystems.

Pairings

Cryptographic pairings are defined over three mathematical groups: G1, G2, and GT, where each group is typically of the same order r. Additionally, a bilinear map e maps a pair of elements — one from G1 and another from G2 — to an element in GT. This map e has the following additional property:

For some generator g in G1, generator h in G2, and x and y in Zr:
e(gˣ, hʸ) = e(g,h)ˣʸ

If G1 == G2, then a pairing is said to be symmetric. Otherwise, it is asymmetric. Pairings can be used to construct a variety of efficient cryptosystems.

Supported Pairings

The PBC library currently supports 5 different types of pairings, each with configurable parameters. These types are designated alphabetically, roughly in chronological order of introduction. Type A, D, E, F, and G pairings are implemented in the library. Each type has different time and space requirements. For more information about the types, see the documentation for the corresponding generator calls, or the PBC manual page at https://crypto.stanford.edu/pbc/manual/ch05s01.html.

Dependencies

This package must be compiled using cgo. It also requires the installation of GMP and PBC. During the build process, this package will attempt to include <gmp.h> and <pbc/pbc.h>, and then dynamically link to GMP and PBC.

Most systems include a package for GMP. To install GMP in Debian / Ubuntu:

sudo apt-get install libgmp-dev

For an RPM installation with YUM:

sudo yum install gmp-devel

For installation with Fink (http://www.finkproject.org/) on Mac OS X:

sudo fink install gmp gmp-shlibs

For more information or to compile from source, visit https://gmplib.org/

To install the PBC library, download the appropriate files for your system from https://crypto.stanford.edu/pbc/download.html. PBC has three dependencies: the gcc compiler, flex (http://flex.sourceforge.net/), and bison (https://www.gnu.org/software/bison/). See the respective sites for installation instructions. Most distributions include packages for these libraries. For example, in Debian / Ubuntu:

sudo apt-get install build-essential flex bison

The PBC source can be compiled and installed using the usual GNU Build System:

./configure
make
sudo make install

After installing, you may need to rebuild the search path for libraries:

sudo ldconfig

It is possible to install the package on Windows through the use of MinGW and MSYS. MSYS is required for installing PBC, while GMP can be installed through a package. Based on your MinGW installation, you may need to add "-I/usr/local/include" to CPPFLAGS and "-L/usr/local/lib" to LDFLAGS when building PBC. Likewise, you may need to add these options to CGO_CPPFLAGS and CGO_LDFLAGS when installing this package.

License

This package is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

For additional details, see the COPYING and COPYING.LESSER files.

Example

This example generates a pairing and some random group elements, then applies the pairing operation.

// In a real application, generate this once and publish it
params := pbc.GenerateA(160, 512)

pairing := params.NewPairing()

// Initialize group elements. pbc automatically handles garbage collection.
g := pairing.NewG1()
h := pairing.NewG2()
x := pairing.NewGT()

// Generate random group elements and pair them
g.Rand()
h.Rand()
fmt.Printf("g = %s\n", g)
fmt.Printf("h = %s\n", h)
x.Pair(g, h)
fmt.Printf("e(g,h) = %s\n", x)
Output:

Example (SignBLS)

This example computes and verifies a Boneh-Lynn-Shacham signature in a simulated conversation between Alice and Bob.

package main

import (
	"crypto/sha256"
	"fmt"
)

// messageData represents a signed message sent over the network
type messageData struct {
	message   string
	signature []byte
}

// This example computes and verifies a Boneh-Lynn-Shacham signature in a
// simulated conversation between Alice and Bob.
func main() {
	// The authority generates system parameters
	params := pbc.GenerateA(160, 512)
	pairing := params.NewPairing()
	g := pairing.NewG2().Rand()

	// The authority distributes params and g to Alice and Bob
	sharedParams := params.String()
	sharedG := g.Bytes()

	// Channel for messages. Normally this would be a network connection.
	messageChannel := make(chan *messageData)

	// Channel for public key distribution. This might be a secure out-of-band
	// channel or something like a web of trust. The public key only needs to
	// be transmitted and verified once. The best way to do this is beyond the
	// scope of this example.
	keyChannel := make(chan []byte)

	// Channel to wait until both simulations are done
	finished := make(chan bool)

	// Simulate the conversation participants
	go alice(sharedParams, sharedG, messageChannel, keyChannel, finished)
	go bob(sharedParams, sharedG, messageChannel, keyChannel, finished)

	// Wait for the communication to finish
	<-finished
	<-finished

}

// Alice generates a keypair and signs a message
func alice(sharedParams string, sharedG []byte, messageChannel chan *messageData, keyChannel chan []byte, finished chan bool) {
	// Alice loads the system parameters
	pairing, _ := pbc.NewPairingFromString(sharedParams)
	g := pairing.NewG2().SetBytes(sharedG)

	// Generate keypair (x, g^x)
	privKey := pairing.NewZr().Rand()
	pubKey := pairing.NewG2().PowZn(g, privKey)

	// Send public key to Bob
	keyChannel <- pubKey.Bytes()

	// Some time later, sign a message, hashed to h, as h^x
	message := "some text to sign"
	h := pairing.NewG1().SetFromStringHash(message, sha256.New())
	signature := pairing.NewG2().PowZn(h, privKey)

	// Send the message and signature to Bob
	messageChannel <- &messageData{message: message, signature: signature.Bytes()}

	finished <- true
}

// Bob verifies a message received from Alice
func bob(sharedParams string, sharedG []byte, messageChannel chan *messageData, keyChannel chan []byte, finished chan bool) {
	// Bob loads the system parameters
	pairing, _ := pbc.NewPairingFromString(sharedParams)
	g := pairing.NewG2().SetBytes(sharedG)

	// Bob receives Alice's public key (and presumably verifies it manually)
	pubKey := pairing.NewG2().SetBytes(<-keyChannel)

	// Some time later, Bob receives a message to verify
	data := <-messageChannel
	signature := pairing.NewG1().SetBytes(data.signature)

	// To verify, Bob checks that e(h,g^x)=e(sig,g)
	h := pairing.NewG1().SetFromStringHash(data.message, sha256.New())
	temp1 := pairing.NewGT().Pair(h, pubKey)
	temp2 := pairing.NewGT().Pair(signature, g)
	if !temp1.Equals(temp2) {
		fmt.Println("*BUG* Signature check failed *BUG*")
	} else {
		fmt.Println("Signature verified correctly")
	}

	finished <- true
}
Output:

Signature verified correctly

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidParamString = errors.New("invalid pairing parameters")
	ErrNoSuitableCurves   = errors.New("no suitable curves were found")
	ErrUnknownField       = errors.New("unchecked element initialized in unknown field")
	ErrIllegalOp          = errors.New("operation is illegal for elements of this type")
	ErrUncheckedOp        = errors.New("unchecked element passed to checked operation")
	ErrIncompatible       = errors.New("elements are from incompatible fields or pairings")
	ErrBadPairList        = errors.New("pairing product list is in an invalid format")
	ErrBadInput           = errors.New("invalid element format during scan")
	ErrBadVerb            = errors.New("invalid verb specified for scan")
	ErrIllegalNil         = errors.New("received nil when non-nil was expected")
	ErrOutOfRange         = errors.New("index out of range")
	ErrEntropyFailure     = errors.New("error while reading from entropy source")
	ErrHashFailure        = errors.New("error while hashing data")
	ErrInternal           = errors.New("a severe internal error has lead to possible memory corruption")
)

Functions

func Logging

func Logging() bool

Logging returns true if PBC will send status messages to stderr.

func SetCryptoRandom

func SetCryptoRandom()

SetCryptoRandom causes PBC to use the crypto/rand package with the globally shared rand.Reader as the source of random numbers.

func SetDefaultRandom

func SetDefaultRandom()

SetDefaultRandom causes PBC to use its internal source of random numbers. This is the default mode of operation. Internally, PBC will attempt to read from /dev/urandom if it exists, or from the Microsoft Crypto API on Windows. If neither of these sources is available, the library will fall back to an insecure PRNG.

func SetLogging

func SetLogging(log bool)

SetLogging enables or disables sending PBC status messages to stderr. Messages are hidden by default.

func SetRandRandom

func SetRandRandom(rand *rand.Rand)

SetRandRandom causes PBC to use the given source of random numbers.

func SetRandomProvider

func SetRandomProvider(provider RandomSource)

SetRandomProvider sets the random number source for use by PBC. If provider is nil, then PBC will use its internal random number generator, which is the default mode. If provider is non-nil, then requests for random numbers will be serviced by Go instead of the internal C functions. This is slower, but provides greater control. Several convenience functions are provided to set common sources of random numbers.

func SetReaderRandom

func SetReaderRandom(reader io.Reader)

SetReaderRandom causes PBC to use the crypto/rand package to generate random numbers using the given reader as an entropy source.

Types

type Element

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

Element represents an element in one of the algebraic structures associated with a pairing. Arithmetic operations can be performed on elements to complete computations. Elements can also be paired using the associated pairing's bilinear map. Elements can be exported or imported in a variety of formats.

The arithmetic methods for Elements generally follow the style of big.Int. A typical operation has a signature like this:

func (el *Element) Add(x, y *Element) *Element

This method stores x + y in el and returns el. Since these arithmetic operations return the targets, they can be used in method chaining:

x.Add(a, b).Mul(x, c).Square(x)

This assigns x = ((a+b)*c)^2. Whenever possible, the methods defined on Element use the same names as those in the math/big package.

This technique is useful because it allows the target of operations to be different than the operands. However, several convenience functions have been provided to improve the readability of chained calls. These functions are of the form Then*, and implicitly specify the target as the first operand. The above example can be rewritten as:

x.Add(a, b).ThenMul(c).ThenSquare()

For some applications, it is more readable to avoid method chaining:

x.Add(a, b)
x.Mul(x, c)
x.Square(x)

The addition and multiplication functions perform addition and multiplication operations in rings and fields. For groups of points on an elliptic curve, such as the G1 and G2 groups associated with pairings, both addition and multiplication represent the group operation (and similarly both 0 and 1 represent the identity element). It is recommended that programs choose one convention and stick with it to avoid confusion.

In contrast, the GT group is currently implemented as a subgroup of a finite field, so only multiplicative operations should be used for GT.

Not all operations are valid for all elements. For example, pairing operations require an element from G1, an element from G2, and a target from GT. As another example, elements in a ring cannot be inverted in general.

The PBC library does not attempt to detect invalid element operations. If an invalid operation is performed, several outcomes are possible. In the best case, the operation will be treated as a no-op. The target element might be set to a nonsensical value. In the worst case, the program may segfault.

The pbc wrapper provides some protection against invalid operations. When elements are initialized by a Pairing, they can either be created as checked or unchecked. Unchecked elements do not perform any sanity checks; calls are passed directly to the C library, with the possible consequences mentioned above. Checked elements attempt to catch a variety of errors, such as when invalid operations are performed on elements from mismatched algebraic structures or pairings. If an error is detected, the operation will panic with ErrIllegalOp, ErrUncheckedOp, ErrIncompatible, or a similar error.

The decision on whether or not to check operations is based solely on whether or not the target element is checked. Thus, if an unchecked element is passed a checked element as part of an operation, the operation will not be checked. Checked elements expect that all arguments to their methods are also checked, and will panic with ErrUncheckedOp if they are not.

Note that not all possible errors can be detected by checked elements; ultimately, it is the responsibility of the caller to ensure that the requested computations make sense.

func (*Element) Add

func (el *Element) Add(x, y *Element) *Element

Add sets el = x + y and returns el. For curve points, + denotes the group operation.

Requirements: el, x, and y must be from the same algebraic structure.

func (*Element) BigInt

func (el *Element) BigInt() *big.Int

BigInt converts the Element to a big.Int if such an operation makes sense. Note that elliptic curve points cannot be converted using this method, even though this is possible in the original PBC library. If callers wish to convert the first coordinate into an integer, they should explicitly call X().

Requirements: el is expressible as an integer (e.g., an element of Zn, but not a point).

func (*Element) BruteForceDL

func (el *Element) BruteForceDL(g, h *Element) *Element

BruteForceDL sets el such that g^el = h using brute force.

Requirements: g and h must be from the same algebraic structure; and el must be an element of an integer mod ring (e.g., Zn for some n, typically the order of the algebraic structure that g lies in).

func (*Element) Bytes

func (el *Element) Bytes() []byte

Bytes exports el as a byte sequence.

func (*Element) BytesLen

func (el *Element) BytesLen() int

BytesLen returns the number of bytes needed to represent el.

func (*Element) CompressedBytes

func (el *Element) CompressedBytes() []byte

CompressedBytes exports el in a compressed form as a byte sequence.

Requirements: el must be a point on an elliptic curve.

func (*Element) CompressedBytesLen

func (el *Element) CompressedBytesLen() int

CompressedBytesLen returns the number of bytes needed to represent a compressed form of el.

Requirements: el must be a point on an elliptic curve.

func (*Element) Div

func (el *Element) Div(x, y *Element) *Element

Div sets el = x / y and returns el. More precisely, el = x * (1/y). For curve points, * denotes the group operation.

Requirements: el, x, and y must be from the same algebraic structure.

func (*Element) Double

func (el *Element) Double(x *Element) *Element

Double sets el = x + x and returns el.

Requirements: el and x must be from the same algebraic structure.

func (*Element) Equals

func (el *Element) Equals(x *Element) bool

Equals returns true if el == x.

Requirements: el and x must be from the same algebraic structure.

func (*Element) Format

func (el *Element) Format(f fmt.State, c rune)

Format is a support routine for fmt.Formatter. It accepts many formats. The 'v' (value) and 's' (string) verbs will format the Element using the PBC library's internal formatting routines. These verbs accept variable widths to specify the base of the integers. Valid values are 2 to 36, inclusive.

If the 'v' verb is used with the '#' (alternate format) flag, the output is metadata about the element in a pseudo-Go syntax. Checked elements will print more information than unchecked elements in this mode.

If the 'd', 'b', 'o', 'x', or 'X' verbs are used, then the element is formatted within Go. The syntax approximates the PBC library's formatting, but integers are converted to big.Int for formatting. All of the verbs and flags that can be used in math/big will be used to format the elements.

Example

This example displays an element in a variety of formats.

var element *pbc.Element

// ...populate element...

fmt.Printf("%v", element)    // Print in PBC format
fmt.Printf("%s", element)    // Same as above
fmt.Printf("%36v", element)  // Print in PBC format, base 36
fmt.Printf("%#v", element)   // Print metadata about element
fmt.Printf("%d", element)    // Print with Go
fmt.Printf("%010o", element) // Print with Go, zero-padded width-10 octal
Output:

func (*Element) Halve

func (el *Element) Halve(x *Element) *Element

Halve sets el = x / 2 and returns el.

Requirements: el and x must be from the same algebraic structure.

func (*Element) Invert

func (el *Element) Invert(x *Element) *Element

Invert sets el = 1/x and returns el.

Requirements: el and x must be from the same algebraic structure.

func (*Element) Is0

func (el *Element) Is0() bool

Is0 returns true if el is zero (or the identity element for curves).

func (*Element) Is1

func (el *Element) Is1() bool

Is1 returns true if el is one (or the identity element for curves).

func (*Element) IsSquare

func (el *Element) IsSquare() bool

IsSquare returns true if el is a perfect square (quadratic residue).

func (*Element) Item

func (el *Element) Item(i int) *Element

Item returns the specified sub-element. For points, this returns a coordinate. For polynomials, it returns a coefficient. For other elements, this operation is invalid. i must be greater than or equal to 0 and less than el.Len(). Bounds checking is only performed for checked elements.

func (*Element) Len

func (el *Element) Len() int

Len returns the length of this element. For points, this is the number of coordinates. For polynomials, it is the number of coefficients. For infinite points, it is zero. For all other values, it is zero.

func (*Element) Mul

func (el *Element) Mul(x, y *Element) *Element

Mul sets el = x * y and returns el. For curve points, * denotes the group operation.

Requirements: el, x, and y must be from the same algebraic structure.

func (*Element) MulBig

func (el *Element) MulBig(x *Element, i *big.Int) *Element

MulBig sets el = i * x and returns el. More precisely, el = x + x + ... + x where there are i x's. For curve points, + denotes the group operation.

Requirements: el and x must be from the same algebraic structure.

func (*Element) MulInt32

func (el *Element) MulInt32(x *Element, i int32) *Element

MulInt32 sets el = i * x and returns el. More precisely, el = x + x + ... + x where there are i x's. For curve points, + denotes the group operation.

Requirements: el and x must be from the same algebraic structure.

func (*Element) MulZn

func (el *Element) MulZn(x, i *Element) *Element

MulZn sets el = i * x and returns el. More precisely, el = x + x + ... + x where there are i x's. For curve points, + denotes the group operation.

Requirements: el and x must be from the same algebraic structure; and i must be an element of an integer mod ring (e.g., Zn for some n).

func (*Element) Neg

func (el *Element) Neg(x *Element) *Element

Neg sets el = -x and returns el.

Requirements: el and x must be from the same algebraic structure.

func (*Element) NewFieldElement

func (el *Element) NewFieldElement() *Element

NewFieldElement creates a new element in the same field as el. The new element will be unchecked if and only if el is unchecked.

func (*Element) Pair

func (el *Element) Pair(x, y *Element) *Element

Pair sets el = e(x,y) where e denotes the pairing operation, and returns el.

Requirements: el, x, and y must belong to the same pairing; el must belong to the pairing's GT group; x must belong to the pairing's G1 group (or G2 for symmetric pairings); and y must belong to the pairing's G2 group (or G1 for symmetric pairings).

func (*Element) PairerPair

func (el *Element) PairerPair(pairer *Pairer, y *Element) *Element

PairerPair sets el = e(s,y) and returns el, where e denotes the pairing operation, and s was the source Element for the Pairer. It is equivalent to pairer.Pair(el, y).

Requirements: el, s, and y must belong to the same pairing; el must belong to the pairing's GT group; s must belong to the pairing's G1 group (or G2 for symmetric pairings); and y must belong to the pairing's G2 group (or G1 for symmetric pairings).

func (*Element) Pairing

func (el *Element) Pairing() *Pairing

Pairing returns the pairing associated with this element.

func (*Element) PollardRhoDL

func (el *Element) PollardRhoDL(g, h *Element) *Element

PollardRhoDL sets el such that g^el = h using Pollard rho method.

Requirements: g and h must be from the same algebraic structure; and el must be an element of an integer mod ring (e.g., Zn for some n, typically the order of the algebraic structure that g lies in).

func (*Element) Pow2Big

func (el *Element) Pow2Big(x *Element, i *big.Int, y *Element, j *big.Int) *Element

Pow2Big sets el = x^i * y^j and returns el. This is generally faster than performing separate exponentiations.

Requirements: el, x, and y must be from the same algebraic structure.

func (*Element) Pow2Zn

func (el *Element) Pow2Zn(x, i, y, j *Element) *Element

Pow2Zn sets el = x^i * y^j and returns el. This is generally faster than performing separate exponentiations.

Requirements: el, x, and y must be from the same algebraic structure; and i and j must be elements of integer mod rings (e.g., Zn for some n, typically the order of the algebraic structures that x and y lie in).

func (*Element) Pow3Big

func (el *Element) Pow3Big(x *Element, i *big.Int, y *Element, j *big.Int, z *Element, k *big.Int) *Element

Pow3Big sets el = x^i * y^j * z^k and returns el. This is generally faster than performing separate exponentiations.

Requirements: el, x, y, and z must be from the same algebraic structure.

func (*Element) Pow3Zn

func (el *Element) Pow3Zn(x, i, y, j, z, k *Element) *Element

Pow3Zn sets el = x^i * y^j * z^k and returns el. This is generally faster than performing separate exponentiations.

Requirements: el, x, y, and z must be from the same algebraic structure; and i, j, and k must be elements of integer mod rings (e.g., Zn for some n, typically the order of the algebraic structures that x, y, and z lie in).

func (*Element) PowBig

func (el *Element) PowBig(x *Element, i *big.Int) *Element

PowBig sets el = x^i and returns el. More precisely, el = x * x * ... * x where there are i x's. For curve points, * denotes the group operation.

Requirements: el and x must be from the same algebraic structure.

func (*Element) PowZn

func (el *Element) PowZn(x, i *Element) *Element

PowZn sets el = x^i and returns el. More precisely, el = x * x * ... * x where there are i x's. For curve points, * denotes the group operation.

Requirements: el and x must be from the same algebraic structure; and i must be an element of an integer mod ring (e.g., Zn for some n, typically the order of the algebraic structure that x lies in).

func (*Element) PowerBig

func (el *Element) PowerBig(power *Power, i *big.Int) *Element

PowerBig sets el = s^i where s was the source Element for the Power, and returns el. It is equivalent to power.PowBig(el, i).

Requirements: el and s must be from the same algebraic structure.

func (*Element) PowerZn

func (el *Element) PowerZn(power *Power, i *Element) *Element

PowerZn sets el = s^i where s was the source Element for the Power, and returns el. It is equivalent to power.PowZn(el, i).

Requirements: el and s must be from the same algebraic structure; and i must be an element of an integer mod ring (e.g., Zn for some n, typically the order of the algebraic structure that s lies in).

func (*Element) PreparePairer

func (el *Element) PreparePairer() *Pairer

PreparePairer generates pre-processing data for repeatedly pairing el. The returned Pairer can be used to pair el several times, and is generally faster than repeatedly calling Pair on el.

Requirements: el must belong to the pairing's G1 group (or G2 for symmetric pairings).

func (*Element) PreparePower

func (el *Element) PreparePower() *Power

PreparePower generates pre-processing data for repeatedly exponentiating el. The returned Power can be used to raise el to a power several times, and is generally faster than repeatedly calling the standard Pow methods on el.

func (*Element) ProdPair

func (el *Element) ProdPair(elements ...*Element) *Element

ProdPair sets el to the product of several pairings, and returns el. The elements are paired in groups of two.

For example:

el.ProdPair(a,b,c,d,e,f)

will set el = e(a,b) * e(c,d) * e(e,f).

Requirements: all elements must belong to the same pairing; el must belong to the pairing's GT group; there must be an even number of parameters; odd numbered parameters must belong to the pairing's G1 group (or G2 for symmetric pairings); and even numbered parameters must belong to the pairing's G2 group (or G1 for symmetric pairings).

func (*Element) ProdPairSlice

func (el *Element) ProdPairSlice(x, y []*Element) *Element

ProdPairSlice sets el to the product of several pairings, and returns el. Elements from x will be paired with elements in y having the same index.

For example:

el.ProdPairSlice([]*Element{a,b,c}, []*Element{d,e,f})

will set el = e(a,d) * e(b,e) * e(c,f).

Requirements: all elements must belong to the same pairing; el must belong to the pairing's GT group; the slices must have the same number of elements; elements in x must belong to the pairing's G1 group (or G2 for symmetric pairings); and elements in y must belong to the pairing's G2 group (or G1 for symmetric pairings).

func (*Element) Rand

func (el *Element) Rand() *Element

Rand sets el to a random value and returns el. For algebraic structures where this does not make sense, this is equivalent to Set0.

func (*Element) Scan

func (el *Element) Scan(state fmt.ScanState, verb rune) error

Scan is a support routine for fmt.Scanner. It accepts the verbs 's' and 'v' only; only strings produced in PBC library format can be scanned. The width is used to denote the base of integers in the data.

func (*Element) Set

func (el *Element) Set(src *Element) *Element

Set sets the value of el to be the same as src.

Requirements: el and src must be from the same algebraic structure.

func (*Element) Set0

func (el *Element) Set0() *Element

Set0 sets el to zero and returns el. For curves, this sets the element to the infinite point (identity element).

func (*Element) Set1

func (el *Element) Set1() *Element

Set1 sets el to one and returns el. For curves, this sets the element to the infinite point (identity element).

func (*Element) SetBig

func (el *Element) SetBig(i *big.Int) *Element

SetBig sets the value of el to the integer i. This operation is only valid for elements in integer fields (e.g., Zr for a pairing).

Requirements: el must be an element of an integer mod ring (e.g., Zn for some n).

func (*Element) SetBytes

func (el *Element) SetBytes(buf []byte) *Element

SetBytes imports a sequence exported by Bytes() and sets the value of el.

func (*Element) SetCompressedBytes

func (el *Element) SetCompressedBytes(buf []byte) *Element

SetCompressedBytes imports a sequence exported by CompressedBytes() and sets the value of el.

Requirements: el must be a point on an elliptic curve.

func (*Element) SetFromHash

func (el *Element) SetFromHash(hash []byte) *Element

SetFromHash generates el deterministically from the bytes in hash.

func (*Element) SetFromStringHash

func (el *Element) SetFromStringHash(s string, h hash.Hash) *Element

SetFromStringHash hashes s with h and then calls SetFromHash. h may or may not be a cryptographic hash, depending on the higher level protocol.

func (*Element) SetInt32

func (el *Element) SetInt32(i int32) *Element

SetInt32 sets the value of el to the integer i. This operation is only valid for elements in integer fields (e.g., Zr for a pairing).

Requirements: el must be an element of an integer mod ring (e.g., Zn for some n).

func (*Element) SetString

func (el *Element) SetString(s string, base int) (*Element, bool)

SetString sets el to the value contained in s. Returns (el, true) if successful, and (nil, false) if an error occurs. s is expected to be in the same format produced by String().

func (*Element) SetXBytes

func (el *Element) SetXBytes(buf []byte) *Element

SetXBytes imports a sequence exported by XBytes() and sets el to be a point on the curve with the given X coordinate. In general, this point is not unique. For each X coordinate, there exist two different points (for the pairings in PBC), and they are inverses of each other. An application can deal with this by either exporting the sign of the element along with the X coordinate, or by testing the value to see if it makes sense in the higher level protocol (and inverting it if it does not).

Requirements: el must be a point on an elliptic curve.

func (*Element) Sign

func (el *Element) Sign() int

Sign returns 0 if el is 0. If el is not 0, the behavior depends on the algebraic structure, but has the property that el.Sign() == -neg.Sign() where neg is the negation of el.

func (*Element) Square

func (el *Element) Square(x *Element) *Element

Square sets el = x * x and returns el.

Requirements: el and x must be from the same algebraic structure.

func (*Element) String

func (el *Element) String() string

String converts el to a string using the default PBC library format.

func (*Element) Sub

func (el *Element) Sub(x, y *Element) *Element

Sub sets el = x - y and returns el. More precisely, el = x + (-y). For curve points, + denotes the group operation.

Requirements: el, x, and y must be from the same algebraic structure.

func (*Element) ThenAdd

func (el *Element) ThenAdd(y *Element) *Element

ThenAdd is an alias for el.Add(el, y).

Requirements: el and y must be from the same algebraic structure.

func (*Element) ThenDiv

func (el *Element) ThenDiv(y *Element) *Element

ThenDiv is an alias for el.Div(el, y).

Requirements: el and y must be from the same algebraic structure.

func (*Element) ThenDouble

func (el *Element) ThenDouble() *Element

ThenDouble is an alias for el.Double(el).

func (*Element) ThenHalve

func (el *Element) ThenHalve() *Element

ThenHalve is an alias for el.Halve(el).

func (*Element) ThenInvert

func (el *Element) ThenInvert() *Element

ThenInvert is an alias for el.Invert(el).

func (*Element) ThenMul

func (el *Element) ThenMul(y *Element) *Element

ThenMul is an alias for el.Mul(el, y).

Requirements: el and y must be from the same algebraic structure.

func (*Element) ThenMulBig

func (el *Element) ThenMulBig(i *big.Int) *Element

ThenMulBig is an alias for el.MulBig(el, i).

func (*Element) ThenMulInt32

func (el *Element) ThenMulInt32(i int32) *Element

ThenMulInt32 is an alias for el.MulInt32(el, i).

func (*Element) ThenMulZn

func (el *Element) ThenMulZn(i *Element) *Element

ThenMulZn is an alias for el.MulZn(el, i).

Requirements: i must be an element of an integer mod ring (e.g., Zn for some n).

func (*Element) ThenNeg

func (el *Element) ThenNeg() *Element

ThenNeg is an alias for el.Neg(el).

func (*Element) ThenPowBig

func (el *Element) ThenPowBig(i *big.Int) *Element

ThenPowBig is an alias for el.PowBig(el, i).

func (*Element) ThenPowZn

func (el *Element) ThenPowZn(i *Element) *Element

ThenPowZn is an alias for el.PowZn(el, i).

Requirements: i must be an element of an integer mod ring (e.g., Zn for some n, typically the order of the algebraic structure that el lies in).

func (*Element) ThenSquare

func (el *Element) ThenSquare() *Element

ThenSquare is an alias for el.Square(el).

func (*Element) ThenSub

func (el *Element) ThenSub(y *Element) *Element

ThenSub is an alias for el.Sub(el, y).

Requirements: el and y must be from the same algebraic structure.

func (*Element) X

func (el *Element) X() *big.Int

X returns the X coordinate of el. Equivalent to el.Item(0).BigInt().

Requirements: el must be a point on an elliptic curve.

func (*Element) XBytes

func (el *Element) XBytes() []byte

XBytes exports el's X coordinate as a byte sequence.

Requirements: el must be a point on an elliptic curve.

func (*Element) XBytesLen

func (el *Element) XBytesLen() int

XBytesLen returns the number of bytes needed to represent el's X coordinate.

Requirements: el must be a point on an elliptic curve.

func (*Element) Y

func (el *Element) Y() *big.Int

Y returns the Y coordinate of el. Equivalent to el.Item(1).BigInt().

Requirements: el must be a point on an elliptic curve.

type Field

type Field int

Field denotes the various possible algebraic structures associated with a pairing. G1, G2, and GT are the groups involved in the pairing operation. Zr is the field of integers with order r, where r is the order of G1, G2, and GT.

const (
	G1 Field = iota
	G2 Field = iota
	GT Field = iota
	Zr Field = iota
)

type Pairer

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

Pairer stores pre-processed information to quickly pair an element. A Pairer can be generated for Element x by calling x.PreparePairer(). When Pair is called with Elements target and y, the result of e(x,y) will be stored in target. Once a Pairer has been generated, the original element can be changed without affecting the pre-processed data.

func (*Pairer) Pair

func (pairer *Pairer) Pair(target *Element, y *Element) *Element

Pair sets target = e(s,y) and returns target, where e denotes the pairing operation, and s was the source Element for the Pairer. It is equivalent to target.PairerPair(pairer, y).

Requirements: target, s, and y must belong to the same pairing; target must belong to the pairing's GT group; s must belong to the pairing's G1 group (or G2 for symmetric pairings); and y must belong to the pairing's G2 group (or G1 for symmetric pairings).

func (*Pairer) Source

func (pairer *Pairer) Source() *Element

Source returns the Element for which the pre-processed data was generated.

type Pairing

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

Pairing represents a pairing and its associated groups. The primary use of a pairing object is the initialization of group elements. Elements can be created in G1, G2, GT, or Zr. Additionally, elements can be checked or unchecked. See the Element type for more details.

func NewPairing

func NewPairing(params *Params) *Pairing

NewPairing instantiates a pairing from a set of parameters.

func NewPairingFromReader

func NewPairingFromReader(params io.Reader) (*Pairing, error)

NewPairingFromReader loads pairing parameters from a Reader and instantiates a pairing.

func NewPairingFromString

func NewPairingFromString(params string) (*Pairing, error)

NewPairingFromString loads pairing parameters from a string and instantiates a pairing.

func (*Pairing) G1CompressedLength

func (pairing *Pairing) G1CompressedLength() uint

G1CompressedLength returns the size of compressed elements in G1, in bytes.

func (*Pairing) G1Length

func (pairing *Pairing) G1Length() uint

G1Length returns the size of elements in G1, in bytes.

func (*Pairing) G1XLength

func (pairing *Pairing) G1XLength() uint

G1XLength returns the size of X coordinates of elements in G1, in bytes.

func (*Pairing) G2CompressedLength

func (pairing *Pairing) G2CompressedLength() uint

G2CompressedLength returns the size of compressed elements in G2, in bytes.

func (*Pairing) G2Length

func (pairing *Pairing) G2Length() uint

G2Length returns the size of elements in G2, in bytes.

func (*Pairing) G2XLength

func (pairing *Pairing) G2XLength() uint

G2XLength returns the size of X coordinates of elements in G2, in bytes.

func (*Pairing) GTLength

func (pairing *Pairing) GTLength() uint

GTLength returns the size of elements in GT, in bytes.

func (*Pairing) IsSymmetric

func (pairing *Pairing) IsSymmetric() bool

IsSymmetric returns true if G1 == G2 for this pairing.

func (*Pairing) NewG1

func (pairing *Pairing) NewG1() *Element

NewG1 creates a new checked element in G1.

func (*Pairing) NewG2

func (pairing *Pairing) NewG2() *Element

NewG2 creates a new checked element in G2.

func (*Pairing) NewGT

func (pairing *Pairing) NewGT() *Element

NewGT creates a new checked element in GT.

func (*Pairing) NewUncheckedElement

func (pairing *Pairing) NewUncheckedElement(field Field) *Element

NewUncheckedElement creates a new unchecked element in the target field. Unchecked elements are dangerous; see the Element documentation before deciding to use this method. It is safer to create elements using the NewG1, NewG2, NewGT, or NewZr methods.

func (*Pairing) NewZr

func (pairing *Pairing) NewZr() *Element

NewZr creates a new checked element in Zr.

func (*Pairing) ZrLength

func (pairing *Pairing) ZrLength() uint

ZrLength returns the size of elements in Zr, in bytes.

type Params

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

Params represents the parameters required for creating a pairing. Parameters can be generated using the generation functions or read from a Reader. Normally, parameters are generated once using a generation program and then distributed with the final application. Parameters can be exported for this purpose using the WriteTo or String methods.

For applications requiring fast computation, type A pairings are preferred. Applications requiring small message sizes should consider type D pairings. If speed is not a concern, type F pairings yield the smallest messages at the cost of additional computation. Applications requiring symmetric pairings should use type A. If a specific group order must be used (e.g., for composite orders), then type A1 pairings are required.

func GenerateA

func GenerateA(rbits uint32, qbits uint32) *Params

GenerateA generates a pairing on the curve y^2 = x^3 + x over the field F_q for some prime q = 3 mod 4. Type A pairings are symmetric (i.e., G1 == G2). Type A pairings are best used when speed of computation is the primary concern.

To be secure, generic discrete log algorithms must be infeasible in groups of order r, and finite field discrete log algorithms must be infeasible in groups of order q^2.

For example:

params := pbc.GenerateA(160, 512)

More details: https://crypto.stanford.edu/pbc/manual/ch08s03.html

func GenerateA1

func GenerateA1(r *big.Int) *Params

GenerateA1 generates a type A pairing given a fixed order for G1, G2, and GT. This form of pairing can be used to produce groups of composite order, where r is the product of two large primes. In this case, r should infeasible to factor. Each prime should be at least 512 bits (causing r to be 1024 bits in general), but preferably 1024 bits or more.

More details: https://crypto.stanford.edu/pbc/manual/ch08s03.html

func GenerateD

func GenerateD(d uint32, rbits uint32, qbits uint32, bitlimit uint32) (*Params, error)

GenerateD generates a pairing on a curve with embedding degree 6 whose order is h * r where r is prime and h is a small constant. Type D pairings are asymmetric, but have small group elements. This makes them well-suited for applications where message size is the primary concern, but speed is also important.

Parameters are generated using the constant multiplication (CM) method for a given fundamental discriminant D. It is required that D > 0, no square of an odd prime divides D, and D = 0 or 3 mod 4. The bitlimit parameter sets a cap on the number of bits in the group order. It is possible that for some values of D, no suitable curves can be found. In this case, GenerateD returns nil and ErrNoSuitableCurves.

The rbits and qbits parameters set minimum sizes for group orders. To be secure, generic discrete log algorithms must be infeasible in groups of order r, and finite field discrete log algorithms must be infeasible in groups of order q^6.

For example:

params, err := pbc.GenerateD(9563, 160, 171, 500)

More details: https://crypto.stanford.edu/pbc/manual/ch08s06.html

func GenerateE

func GenerateE(rbits uint32, qbits uint32) *Params

GenerateE generates a pairing entirely within a order r subgroup of an order q field. These pairings are symmetric, but serve little purpose beyond being mathematically interesting. Use of these pairings is not recommended unless new algorithms are discovered for solving discrete logs in elliptic curves as easily as for finite fields.

For security, generic discrete log algorithms must be infeasible in groups of order r, and finite field discrete log algorithms must be infeasible in finite fields of order q.

For example:

params, err := pbc.GenerateE(160, 1024)

More details: https://crypto.stanford.edu/pbc/manual/ch08s07.html

func GenerateF

func GenerateF(bits uint32) *Params

GenerateF generates an asymmetric pairing with extremely small group elements. This is the best pairing to use when space is an overriding priority. However, type F pairings are slow compared to the other types. Type D pairings provide a more balanced alternative.

The bits parameter specifies the approximate number of bits in the group order, r, and the order of the base field, q. For security, generic discrete log algorithms must be infeasible in groups of order r, and finite field discrete log algorithms must be infeasible in finite fields of order q^12.

For example:

params, err := pbc.GenerateF(160)

More details: https://crypto.stanford.edu/pbc/manual/ch08s08.html

func GenerateG

func GenerateG(d uint32, rbits uint32, qbits uint32, bitlimit uint32) (*Params, error)

GenerateG generates a pairing on a curve with embedding degree 10 whose order is h * r where r is prime and h is a small constant. Type G pairings are asymmetric, but have extremely small group elements. However, these pairings are even slower than type F pairings, making type F a better choice.

Like type D pairings, parameters are generated using the constant multiplication (CM) method. See the GenerateD function for a description of the parameters.

For example:

params, err := pbc.GenerateG(9563, 160, 171, 500)

More details: https://crypto.stanford.edu/pbc/manual/ch08s09.html

func NewParams

func NewParams(r io.Reader) (*Params, error)

NewParams loads pairing parameters from a Reader.

func NewParamsFromString

func NewParamsFromString(s string) (*Params, error)

NewParamsFromString loads pairing parameters from a string.

func (*Params) NewPairing

func (params *Params) NewPairing() *Pairing

NewPairing creates a Pairing using these parameters.

func (*Params) String

func (params *Params) String() string

String returns a string representation of the pairing parameters.

func (*Params) WriteTo

func (params *Params) WriteTo(w io.Writer) (n int64, err error)

WriteTo writes the pairing parameters to a Writer.

type Power

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

Power stores pre-processed information to quickly exponentiate an element. A Power can be generated for Element x by calling x.PreparePower(). When PowBig or PowZn is called with Element target and integer i, the result of x^i will be stored in target. Once a Power has been generated, the original element can be changed without affecting the pre-processed data.

func (*Power) PowBig

func (power *Power) PowBig(target *Element, i *big.Int) *Element

PowBig sets target = s^i where s was the source Element for the Power, and returns target. It is equivalent to target.PowerBig(power, i).

Requirements: target and s must be from the same algebraic structure.

func (*Power) PowZn

func (power *Power) PowZn(target *Element, i *Element) *Element

PowZn sets target = s^i where s was the source Element for the Power, and returns target. It is equivalent to target.PowerZn(power, i).

Requirements: target and s must be from the same algebraic structure.

func (*Power) Source

func (power *Power) Source() *Element

Source returns the Element for which the pre-processed data was generated.

type RandomSource

type RandomSource interface {
	Rand(limit *big.Int) *big.Int
}

RandomSource generates random numbers for consumption by PBC. Rand returns a random integer in [0,limit).

func RandomProvider

func RandomProvider() RandomSource

RandomProvider returns the current random number source for use by PBC.

Jump to

Keyboard shortcuts

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