From eea1e71bf32639d545b707d36936dc9dbd84d780 Mon Sep 17 00:00:00 2001 From: Nik <njunger@uwaterloo.ca> Date: Thu, 29 Jan 2015 15:42:29 -0500 Subject: [PATCH] Restructured CGO flags. Dynamic linking. Fixed LF --- c.go | 7 + element.go | 427 +++++++++++++------------ element_checked.go | 737 +++++++++++++++++++++---------------------- element_fmt.go | 379 +++++++++++----------- element_unchecked.go | 681 ++++++++++++++++++++------------------- generation.go | 18 +- gmp_big.go | 2 - pairing.go | 1 - params.go | 1 - 9 files changed, 1123 insertions(+), 1130 deletions(-) create mode 100644 c.go diff --git a/c.go b/c.go new file mode 100644 index 0000000..91972e0 --- /dev/null +++ b/c.go @@ -0,0 +1,7 @@ +package pbc + +/* +#cgo CFLAGS: -std=gnu99 +#cgo LDFLAGS: -lpbc -lgmp +*/ +import "C" diff --git a/element.go b/element.go index 5f2aae5..b00ea72 100644 --- a/element.go +++ b/element.go @@ -1,214 +1,213 @@ -package pbc - -/* -#cgo LDFLAGS: /usr/local/lib/libpbc.a -lgmp -#include <pbc/pbc.h> -*/ -import "C" - -import ( - "errors" - "fmt" - "math/big" - "runtime" -) - -var ErrUnknownField = errors.New("unchecked element initialized in unknown field") - -type Element interface { - NewFieldElement() Element - - Set0() Element - Set1() Element - SetInt32(int32) Element - SetBig(*big.Int) Element - Set(Element) Element - - SetFromHash([]byte) Element - SetBytes([]byte) Element - SetXBytes([]byte) Element - SetCompressedBytes([]byte) Element - - SetString(s string, base int) (Element, bool) - - Format(fmt.State, rune) - Scan(fmt.ScanState, rune) error - - BigInt() *big.Int - String() string - - BytesLen() int - Bytes() []byte - XBytesLen() int - XBytes() []byte - CompressedBytesLen() int - CompressedBytes() []byte - - Len() int - Item(int) Element - X() *big.Int - Y() *big.Int - - Is0() bool - Is1() bool - IsSquare() bool - Sign() int - - Cmp(x Element) int - - Add(x, y Element) Element - Sub(x, y Element) Element - Mul(x, y Element) Element - MulBig(x Element, i *big.Int) Element - MulInt32(x Element, i int32) Element - MulZn(x, y Element) Element - Div(x, y Element) Element - Double(x Element) Element - Halve(x Element) Element - Square(x Element) Element - Neg(x Element) Element - Invert(x Element) Element - - PowBig(x Element, i *big.Int) Element - PowZn(x, i Element) Element - Pow2Big(x Element, i *big.Int, y Element, j *big.Int) Element - Pow2Zn(x, i, y, j Element) Element - Pow3Big(x Element, i *big.Int, y Element, j *big.Int, z Element, k *big.Int) Element - Pow3Zn(x, i, y, j, z, k Element) Element - - PreparePower() Power - PowerBig(Power, *big.Int) Element - PowerZn(Power, Element) Element - - BruteForceDL(g, h Element) Element - PollardRhoDL(g, h Element) Element - - Rand() Element - - Pair(x, y Element) Element - ProdPair(elements ...Element) Element - ProdPairSlice(x, y []Element) Element - - PreparePairer() Pairer - PairerPair(Pairer, Element) Element - - impl() *elementImpl -} - -type elementImpl struct { - pairing *pairingImpl - data *C.struct_element_s -} - -type checkedElement struct { - unchecked elementImpl - fieldPtr *C.struct_field_s - isInteger bool -} - -func (pairing *pairingImpl) NewG1() Element { return makeChecked(pairing, G1, pairing.data.G1) } -func (pairing *pairingImpl) NewG2() Element { return makeChecked(pairing, G2, pairing.data.G2) } -func (pairing *pairingImpl) NewGT() Element { return makeChecked(pairing, GT, &pairing.data.GT[0]) } -func (pairing *pairingImpl) NewZr() Element { return makeChecked(pairing, Zr, &pairing.data.Zr[0]) } -func (pairing *pairingImpl) NewElement(field Field) Element { return makeElement(pairing, field) } - -func clearElement(element *elementImpl) { - println("clearelement") - C.element_clear(element.data) -} - -func initElement(element *elementImpl, pairing *pairingImpl, initialize bool, field Field) { - element.data = &C.struct_element_s{} - element.pairing = pairing - if initialize { - switch field { - case G1: - C.element_init_G1(element.data, pairing.data) - case G2: - C.element_init_G2(element.data, pairing.data) - case GT: - C.element_init_GT(element.data, pairing.data) - case Zr: - C.element_init_Zr(element.data, pairing.data) - default: - panic(ErrUnknownField) - } - } - runtime.SetFinalizer(element, clearElement) -} - -func makeElement(pairing *pairingImpl, field Field) *elementImpl { - element := &elementImpl{} - initElement(element, pairing, true, field) - return element -} - -func makeChecked(pairing *pairingImpl, field Field, fieldPtr *C.struct_field_s) *checkedElement { - element := &checkedElement{ - fieldPtr: fieldPtr, - isInteger: field == Zr, - } - initElement(&element.unchecked, pairing, true, field) - return element -} - -type Power interface { - PowBig(i *big.Int) Element - PowZn(i Element) Element -} - -type powerImpl struct { - target Element - data *C.struct_element_pp_s -} - -func (power *powerImpl) PowBig(i *big.Int) Element { - return power.target.PowerBig(power, i) -} - -func (power *powerImpl) PowZn(i Element) Element { - return power.target.PowerZn(power, i) -} - -func clearPower(power *powerImpl) { - println("clearpower") - C.element_pp_clear(power.data) -} - -func initPower(target Element) Power { - power := &powerImpl{ - target: target, - data: &C.struct_element_pp_s{}, - } - C.element_pp_init(power.data, target.impl().data) - runtime.SetFinalizer(power, clearPower) - return power -} - -type Pairer interface { - Pair(target Element, x Element) Element -} - -type pairerImpl struct { - source Element - data *C.struct_pairing_pp_s -} - -func (pairer *pairerImpl) Pair(target Element, x Element) Element { - return target.PairerPair(pairer, x) -} - -func clearPairer(pairer *pairerImpl) { - println("clearpairer") - C.pairing_pp_clear(pairer.data) -} - -func initPairer(source Element) Pairer { - pairer := &pairerImpl{ - source: source, - data: &C.struct_pairing_pp_s{}, - } - C.pairing_pp_init(pairer.data, source.impl().data, source.impl().pairing.data) - runtime.SetFinalizer(pairer, clearPairer) - return pairer -} +package pbc + +/* +#include <pbc/pbc.h> +*/ +import "C" + +import ( + "errors" + "fmt" + "math/big" + "runtime" +) + +var ErrUnknownField = errors.New("unchecked element initialized in unknown field") + +type Element interface { + NewFieldElement() Element + + Set0() Element + Set1() Element + SetInt32(int32) Element + SetBig(*big.Int) Element + Set(Element) Element + + SetFromHash([]byte) Element + SetBytes([]byte) Element + SetXBytes([]byte) Element + SetCompressedBytes([]byte) Element + + SetString(s string, base int) (Element, bool) + + Format(fmt.State, rune) + Scan(fmt.ScanState, rune) error + + BigInt() *big.Int + String() string + + BytesLen() int + Bytes() []byte + XBytesLen() int + XBytes() []byte + CompressedBytesLen() int + CompressedBytes() []byte + + Len() int + Item(int) Element + X() *big.Int + Y() *big.Int + + Is0() bool + Is1() bool + IsSquare() bool + Sign() int + + Cmp(x Element) int + + Add(x, y Element) Element + Sub(x, y Element) Element + Mul(x, y Element) Element + MulBig(x Element, i *big.Int) Element + MulInt32(x Element, i int32) Element + MulZn(x, y Element) Element + Div(x, y Element) Element + Double(x Element) Element + Halve(x Element) Element + Square(x Element) Element + Neg(x Element) Element + Invert(x Element) Element + + PowBig(x Element, i *big.Int) Element + PowZn(x, i Element) Element + Pow2Big(x Element, i *big.Int, y Element, j *big.Int) Element + Pow2Zn(x, i, y, j Element) Element + Pow3Big(x Element, i *big.Int, y Element, j *big.Int, z Element, k *big.Int) Element + Pow3Zn(x, i, y, j, z, k Element) Element + + PreparePower() Power + PowerBig(Power, *big.Int) Element + PowerZn(Power, Element) Element + + BruteForceDL(g, h Element) Element + PollardRhoDL(g, h Element) Element + + Rand() Element + + Pair(x, y Element) Element + ProdPair(elements ...Element) Element + ProdPairSlice(x, y []Element) Element + + PreparePairer() Pairer + PairerPair(Pairer, Element) Element + + impl() *elementImpl +} + +type elementImpl struct { + pairing *pairingImpl + data *C.struct_element_s +} + +type checkedElement struct { + unchecked elementImpl + fieldPtr *C.struct_field_s + isInteger bool +} + +func (pairing *pairingImpl) NewG1() Element { return makeChecked(pairing, G1, pairing.data.G1) } +func (pairing *pairingImpl) NewG2() Element { return makeChecked(pairing, G2, pairing.data.G2) } +func (pairing *pairingImpl) NewGT() Element { return makeChecked(pairing, GT, &pairing.data.GT[0]) } +func (pairing *pairingImpl) NewZr() Element { return makeChecked(pairing, Zr, &pairing.data.Zr[0]) } +func (pairing *pairingImpl) NewElement(field Field) Element { return makeElement(pairing, field) } + +func clearElement(element *elementImpl) { + println("clearelement") + C.element_clear(element.data) +} + +func initElement(element *elementImpl, pairing *pairingImpl, initialize bool, field Field) { + element.data = &C.struct_element_s{} + element.pairing = pairing + if initialize { + switch field { + case G1: + C.element_init_G1(element.data, pairing.data) + case G2: + C.element_init_G2(element.data, pairing.data) + case GT: + C.element_init_GT(element.data, pairing.data) + case Zr: + C.element_init_Zr(element.data, pairing.data) + default: + panic(ErrUnknownField) + } + } + runtime.SetFinalizer(element, clearElement) +} + +func makeElement(pairing *pairingImpl, field Field) *elementImpl { + element := &elementImpl{} + initElement(element, pairing, true, field) + return element +} + +func makeChecked(pairing *pairingImpl, field Field, fieldPtr *C.struct_field_s) *checkedElement { + element := &checkedElement{ + fieldPtr: fieldPtr, + isInteger: field == Zr, + } + initElement(&element.unchecked, pairing, true, field) + return element +} + +type Power interface { + PowBig(i *big.Int) Element + PowZn(i Element) Element +} + +type powerImpl struct { + target Element + data *C.struct_element_pp_s +} + +func (power *powerImpl) PowBig(i *big.Int) Element { + return power.target.PowerBig(power, i) +} + +func (power *powerImpl) PowZn(i Element) Element { + return power.target.PowerZn(power, i) +} + +func clearPower(power *powerImpl) { + println("clearpower") + C.element_pp_clear(power.data) +} + +func initPower(target Element) Power { + power := &powerImpl{ + target: target, + data: &C.struct_element_pp_s{}, + } + C.element_pp_init(power.data, target.impl().data) + runtime.SetFinalizer(power, clearPower) + return power +} + +type Pairer interface { + Pair(target Element, x Element) Element +} + +type pairerImpl struct { + source Element + data *C.struct_pairing_pp_s +} + +func (pairer *pairerImpl) Pair(target Element, x Element) Element { + return target.PairerPair(pairer, x) +} + +func clearPairer(pairer *pairerImpl) { + println("clearpairer") + C.pairing_pp_clear(pairer.data) +} + +func initPairer(source Element) Pairer { + pairer := &pairerImpl{ + source: source, + data: &C.struct_pairing_pp_s{}, + } + C.pairing_pp_init(pairer.data, source.impl().data, source.impl().pairing.data) + runtime.SetFinalizer(pairer, clearPairer) + return pairer +} diff --git a/element_checked.go b/element_checked.go index 34e9f6e..cb8f223 100644 --- a/element_checked.go +++ b/element_checked.go @@ -1,369 +1,368 @@ -package pbc - -/* -#cgo LDFLAGS: /usr/local/lib/libpbc.a -lgmp -#include <pbc/pbc.h> -*/ -import "C" - -import ( - "errors" - "math/big" -) - -var ( - 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") - ErrOutOfRange = errors.New("index out of range") - ErrInternal = errors.New("a severe internal error has lead to possible memory corruption") -) - -func (el *checkedElement) impl() *elementImpl { return &el.unchecked } - -func element2Checked(x Element) *checkedElement { - checked, ok := x.(*checkedElement) - if !ok { - panic(ErrUncheckedOp) - } - return checked -} - -func checkFieldsMatch(f1, f2 *C.struct_field_s) { - if f1 != f2 { - panic(ErrIncompatible) - } -} - -func (el *checkedElement) checkCompatible(other Element) { - otherChecked := element2Checked(other) - checkFieldsMatch(el.fieldPtr, otherChecked.fieldPtr) -} - -func (el *checkedElement) checkAllCompatible(elements ...Element) { - for _, other := range elements { - el.checkCompatible(other) - } -} - -func (el *checkedElement) checkInteger() { - if !el.isInteger { - panic(ErrIllegalOp) - } -} - -func (el *checkedElement) NewFieldElement() Element { - newElement := &checkedElement{} - *newElement = *el - initElement(&newElement.unchecked, el.unchecked.pairing, false, G1) - C.element_init_same_as(newElement.unchecked.data, el.unchecked.data) - return newElement -} - -func (el *checkedElement) Set0() Element { - el.unchecked.Set0() - return el -} - -func (el *checkedElement) Set1() Element { - el.unchecked.Set1() - return el -} - -func (el *checkedElement) SetInt32(i int32) Element { - el.checkInteger() - el.unchecked.SetInt32(i) - return el -} - -func (el *checkedElement) SetBig(i *big.Int) Element { - el.checkInteger() - el.unchecked.SetBig(i) - return el -} - -func (el *checkedElement) Set(src Element) Element { - el.checkCompatible(src) - el.unchecked.Set(src) - return el -} - -func (el *checkedElement) SetFromHash(hash []byte) Element { - el.unchecked.SetFromHash(hash) - return el -} - -func (el *checkedElement) SetBytes(buf []byte) Element { - el.unchecked.SetBytes(buf) - return el -} - -func (el *checkedElement) SetXBytes(buf []byte) Element { - el.unchecked.SetXBytes(buf) - return el -} - -func (el *checkedElement) SetCompressedBytes(buf []byte) Element { - el.unchecked.SetCompressedBytes(buf) - return el -} - -func (el *checkedElement) SetString(s string, base int) (Element, bool) { - _, ok := el.unchecked.SetString(s, base) - return el, ok -} - -func (el *checkedElement) BigInt() *big.Int { - el.checkInteger() - return el.unchecked.BigInt() -} - -func (el *checkedElement) BytesLen() int { return el.unchecked.BytesLen() } -func (el *checkedElement) XBytesLen() int { return el.unchecked.XBytesLen() } -func (el *checkedElement) CompressedBytesLen() int { return el.unchecked.CompressedBytesLen() } - -func checkedWrite(bytesWritten C.int, buffer []byte) []byte { - if int64(bytesWritten) > int64(len(buffer)) { - panic(ErrInternal) - } - return buffer -} - -func (el *checkedElement) Bytes() []byte { - buf := make([]byte, el.BytesLen()) - return checkedWrite(el.unchecked.writeBytes(buf), buf) -} - -func (el *checkedElement) XBytes() []byte { - buf := make([]byte, el.XBytesLen()) - return checkedWrite(el.unchecked.writeXBytes(buf), buf) -} - -func (el *checkedElement) CompressedBytes() []byte { - buf := make([]byte, el.CompressedBytesLen()) - return checkedWrite(el.unchecked.writeCompressedBytes(buf), buf) -} - -func (el *checkedElement) Len() int { return el.unchecked.Len() } - -func (el *checkedElement) Item(i int) Element { - if i >= el.Len() { - panic(ErrOutOfRange) - } - uncheckedData := el.unchecked.Item(i).(*elementImpl) - item := &checkedElement{ - fieldPtr: uncheckedData.data.field, - isInteger: uncheckedData.Len() == 0, - } - item.unchecked = *uncheckedData - return item -} - -func (el *checkedElement) X() *big.Int { return el.unchecked.X() } -func (el *checkedElement) Y() *big.Int { return el.unchecked.Y() } -func (el *checkedElement) Is0() bool { return el.unchecked.Is0() } -func (el *checkedElement) Is1() bool { return el.unchecked.Is1() } -func (el *checkedElement) IsSquare() bool { return el.unchecked.IsSquare() } -func (el *checkedElement) Sign() int { return el.unchecked.Sign() } - -func (el *checkedElement) Cmp(x Element) int { - el.checkCompatible(x) - return el.unchecked.Cmp(x) -} - -func (el *checkedElement) Add(x Element, y Element) Element { - el.checkAllCompatible(x, y) - el.unchecked.Add(x, y) - return el -} - -func (el *checkedElement) Sub(x, y Element) Element { - el.checkAllCompatible(x, y) - el.unchecked.Sub(x, y) - return el -} - -func (el *checkedElement) Mul(x, y Element) Element { - el.checkAllCompatible(x, y) - el.unchecked.Mul(x, y) - return el -} - -func (el *checkedElement) MulBig(x Element, i *big.Int) Element { - el.checkCompatible(x) - el.unchecked.MulBig(x, i) - return el -} - -func (el *checkedElement) MulInt32(x Element, i int32) Element { - el.checkCompatible(x) - el.unchecked.MulInt32(x, i) - return el -} - -func (el *checkedElement) MulZn(x, y Element) Element { - el.checkCompatible(x) - element2Checked(y).checkInteger() - el.unchecked.MulZn(x, y) - return el -} - -func (el *checkedElement) Div(x, y Element) Element { - el.checkAllCompatible(x, y) - el.unchecked.Div(x, y) - return el -} - -func (el *checkedElement) Double(x Element) Element { - el.checkCompatible(x) - el.unchecked.Double(x) - return el -} - -func (el *checkedElement) Halve(x Element) Element { - el.checkCompatible(x) - el.unchecked.Halve(x) - return el -} - -func (el *checkedElement) Square(x Element) Element { - el.checkCompatible(x) - el.unchecked.Square(x) - return el -} - -func (el *checkedElement) Neg(x Element) Element { - el.checkCompatible(x) - el.unchecked.Neg(x) - return el -} - -func (el *checkedElement) Invert(x Element) Element { - el.checkCompatible(x) - el.unchecked.Invert(x) - return el -} - -func (el *checkedElement) PowBig(x Element, i *big.Int) Element { - el.checkCompatible(x) - el.unchecked.PowBig(x, i) - return el -} - -func (el *checkedElement) PowZn(x, i Element) Element { - el.checkCompatible(x) - element2Checked(i).checkInteger() - el.unchecked.PowZn(x, i) - return el -} - -func (el *checkedElement) Pow2Big(x Element, i *big.Int, y Element, j *big.Int) Element { - el.checkAllCompatible(x, y) - el.unchecked.Pow2Big(x, i, y, j) - return el -} - -func (el *checkedElement) Pow2Zn(x, i, y, j Element) Element { - el.checkAllCompatible(x, y) - element2Checked(i).checkInteger() - element2Checked(j).checkInteger() - el.unchecked.Pow2Zn(x, i, y, j) - return el -} - -func (el *checkedElement) Pow3Big(x Element, i *big.Int, y Element, j *big.Int, z Element, k *big.Int) Element { - el.checkAllCompatible(x, y, z) - el.unchecked.Pow3Big(x, i, y, j, z, k) - return el -} - -func (el *checkedElement) Pow3Zn(x, i, y, j, z, k Element) Element { - el.checkAllCompatible(x, y, z) - element2Checked(i).checkInteger() - element2Checked(j).checkInteger() - element2Checked(k).checkInteger() - el.unchecked.Pow3Zn(x, i, y, j, z, k) - return el -} - -func (el *checkedElement) PreparePower() Power { return initPower(el) } - -func (el *checkedElement) PowerBig(power Power, i *big.Int) Element { - el.unchecked.PowerBig(power, i) - return el -} - -func (el *checkedElement) PowerZn(power Power, i Element) Element { - element2Checked(i).checkInteger() - el.unchecked.PowerZn(power, i) - return el -} - -func (el *checkedElement) Pair(x, y Element) Element { - pairing := el.unchecked.pairing.data - checkFieldsMatch(el.fieldPtr, &pairing.GT[0]) - checkFieldsMatch(element2Checked(x).fieldPtr, pairing.G1) - checkFieldsMatch(element2Checked(y).fieldPtr, pairing.G2) - el.unchecked.Pair(x, y) - return el -} - -func (el *checkedElement) ProdPair(elements ...Element) Element { - pairing := el.unchecked.pairing.data - checkFieldsMatch(el.fieldPtr, &pairing.GT[0]) - n := len(elements) - for i := 1; i < n; i += 2 { - checkFieldsMatch(element2Checked(elements[i-1]).fieldPtr, pairing.G1) - checkFieldsMatch(element2Checked(elements[i]).fieldPtr, pairing.G2) - } - el.unchecked.ProdPair(elements...) - return el -} - -func (el *checkedElement) ProdPairSlice(x, y []Element) Element { - pairing := el.unchecked.pairing.data - checkFieldsMatch(el.fieldPtr, &pairing.GT[0]) - n := len(x) - for i := 1; i < n; i++ { - checkFieldsMatch(element2Checked(x[i]).fieldPtr, pairing.G1) - } - n = len(y) - for i := 1; i < n; i++ { - checkFieldsMatch(element2Checked(y[i]).fieldPtr, pairing.G2) - - } - el.unchecked.ProdPairSlice(x, y) - return el -} - -func (el *checkedElement) PreparePairer() Pairer { return initPairer(el) } - -func (el *checkedElement) PairerPair(pairer Pairer, x Element) Element { - in1 := element2Checked(pairer.(*pairerImpl).source) - in2 := element2Checked(x) - pairing := el.unchecked.pairing.data - checkFieldsMatch(in1.fieldPtr, pairing.G1) - checkFieldsMatch(in2.fieldPtr, pairing.G2) - checkFieldsMatch(el.fieldPtr, &pairing.GT[0]) - el.unchecked.PairerPair(pairer, x) - return el -} - -func (el *checkedElement) BruteForceDL(g, h Element) Element { - el.checkInteger() - element2Checked(g).checkCompatible(h) - el.unchecked.BruteForceDL(g, h) - return el -} - -func (el *checkedElement) PollardRhoDL(g, h Element) Element { - el.checkInteger() - element2Checked(g).checkCompatible(h) - el.unchecked.PollardRhoDL(g, h) - return el -} - -func (el *checkedElement) Rand() Element { - el.unchecked.Rand() - return el -} +package pbc + +/* +#include <pbc/pbc.h> +*/ +import "C" + +import ( + "errors" + "math/big" +) + +var ( + 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") + ErrOutOfRange = errors.New("index out of range") + ErrInternal = errors.New("a severe internal error has lead to possible memory corruption") +) + +func (el *checkedElement) impl() *elementImpl { return &el.unchecked } + +func element2Checked(x Element) *checkedElement { + checked, ok := x.(*checkedElement) + if !ok { + panic(ErrUncheckedOp) + } + return checked +} + +func checkFieldsMatch(f1, f2 *C.struct_field_s) { + if f1 != f2 { + panic(ErrIncompatible) + } +} + +func (el *checkedElement) checkCompatible(other Element) { + otherChecked := element2Checked(other) + checkFieldsMatch(el.fieldPtr, otherChecked.fieldPtr) +} + +func (el *checkedElement) checkAllCompatible(elements ...Element) { + for _, other := range elements { + el.checkCompatible(other) + } +} + +func (el *checkedElement) checkInteger() { + if !el.isInteger { + panic(ErrIllegalOp) + } +} + +func (el *checkedElement) NewFieldElement() Element { + newElement := &checkedElement{} + *newElement = *el + initElement(&newElement.unchecked, el.unchecked.pairing, false, G1) + C.element_init_same_as(newElement.unchecked.data, el.unchecked.data) + return newElement +} + +func (el *checkedElement) Set0() Element { + el.unchecked.Set0() + return el +} + +func (el *checkedElement) Set1() Element { + el.unchecked.Set1() + return el +} + +func (el *checkedElement) SetInt32(i int32) Element { + el.checkInteger() + el.unchecked.SetInt32(i) + return el +} + +func (el *checkedElement) SetBig(i *big.Int) Element { + el.checkInteger() + el.unchecked.SetBig(i) + return el +} + +func (el *checkedElement) Set(src Element) Element { + el.checkCompatible(src) + el.unchecked.Set(src) + return el +} + +func (el *checkedElement) SetFromHash(hash []byte) Element { + el.unchecked.SetFromHash(hash) + return el +} + +func (el *checkedElement) SetBytes(buf []byte) Element { + el.unchecked.SetBytes(buf) + return el +} + +func (el *checkedElement) SetXBytes(buf []byte) Element { + el.unchecked.SetXBytes(buf) + return el +} + +func (el *checkedElement) SetCompressedBytes(buf []byte) Element { + el.unchecked.SetCompressedBytes(buf) + return el +} + +func (el *checkedElement) SetString(s string, base int) (Element, bool) { + _, ok := el.unchecked.SetString(s, base) + return el, ok +} + +func (el *checkedElement) BigInt() *big.Int { + el.checkInteger() + return el.unchecked.BigInt() +} + +func (el *checkedElement) BytesLen() int { return el.unchecked.BytesLen() } +func (el *checkedElement) XBytesLen() int { return el.unchecked.XBytesLen() } +func (el *checkedElement) CompressedBytesLen() int { return el.unchecked.CompressedBytesLen() } + +func checkedWrite(bytesWritten C.int, buffer []byte) []byte { + if int64(bytesWritten) > int64(len(buffer)) { + panic(ErrInternal) + } + return buffer +} + +func (el *checkedElement) Bytes() []byte { + buf := make([]byte, el.BytesLen()) + return checkedWrite(el.unchecked.writeBytes(buf), buf) +} + +func (el *checkedElement) XBytes() []byte { + buf := make([]byte, el.XBytesLen()) + return checkedWrite(el.unchecked.writeXBytes(buf), buf) +} + +func (el *checkedElement) CompressedBytes() []byte { + buf := make([]byte, el.CompressedBytesLen()) + return checkedWrite(el.unchecked.writeCompressedBytes(buf), buf) +} + +func (el *checkedElement) Len() int { return el.unchecked.Len() } + +func (el *checkedElement) Item(i int) Element { + if i >= el.Len() { + panic(ErrOutOfRange) + } + uncheckedData := el.unchecked.Item(i).(*elementImpl) + item := &checkedElement{ + fieldPtr: uncheckedData.data.field, + isInteger: uncheckedData.Len() == 0, + } + item.unchecked = *uncheckedData + return item +} + +func (el *checkedElement) X() *big.Int { return el.unchecked.X() } +func (el *checkedElement) Y() *big.Int { return el.unchecked.Y() } +func (el *checkedElement) Is0() bool { return el.unchecked.Is0() } +func (el *checkedElement) Is1() bool { return el.unchecked.Is1() } +func (el *checkedElement) IsSquare() bool { return el.unchecked.IsSquare() } +func (el *checkedElement) Sign() int { return el.unchecked.Sign() } + +func (el *checkedElement) Cmp(x Element) int { + el.checkCompatible(x) + return el.unchecked.Cmp(x) +} + +func (el *checkedElement) Add(x Element, y Element) Element { + el.checkAllCompatible(x, y) + el.unchecked.Add(x, y) + return el +} + +func (el *checkedElement) Sub(x, y Element) Element { + el.checkAllCompatible(x, y) + el.unchecked.Sub(x, y) + return el +} + +func (el *checkedElement) Mul(x, y Element) Element { + el.checkAllCompatible(x, y) + el.unchecked.Mul(x, y) + return el +} + +func (el *checkedElement) MulBig(x Element, i *big.Int) Element { + el.checkCompatible(x) + el.unchecked.MulBig(x, i) + return el +} + +func (el *checkedElement) MulInt32(x Element, i int32) Element { + el.checkCompatible(x) + el.unchecked.MulInt32(x, i) + return el +} + +func (el *checkedElement) MulZn(x, y Element) Element { + el.checkCompatible(x) + element2Checked(y).checkInteger() + el.unchecked.MulZn(x, y) + return el +} + +func (el *checkedElement) Div(x, y Element) Element { + el.checkAllCompatible(x, y) + el.unchecked.Div(x, y) + return el +} + +func (el *checkedElement) Double(x Element) Element { + el.checkCompatible(x) + el.unchecked.Double(x) + return el +} + +func (el *checkedElement) Halve(x Element) Element { + el.checkCompatible(x) + el.unchecked.Halve(x) + return el +} + +func (el *checkedElement) Square(x Element) Element { + el.checkCompatible(x) + el.unchecked.Square(x) + return el +} + +func (el *checkedElement) Neg(x Element) Element { + el.checkCompatible(x) + el.unchecked.Neg(x) + return el +} + +func (el *checkedElement) Invert(x Element) Element { + el.checkCompatible(x) + el.unchecked.Invert(x) + return el +} + +func (el *checkedElement) PowBig(x Element, i *big.Int) Element { + el.checkCompatible(x) + el.unchecked.PowBig(x, i) + return el +} + +func (el *checkedElement) PowZn(x, i Element) Element { + el.checkCompatible(x) + element2Checked(i).checkInteger() + el.unchecked.PowZn(x, i) + return el +} + +func (el *checkedElement) Pow2Big(x Element, i *big.Int, y Element, j *big.Int) Element { + el.checkAllCompatible(x, y) + el.unchecked.Pow2Big(x, i, y, j) + return el +} + +func (el *checkedElement) Pow2Zn(x, i, y, j Element) Element { + el.checkAllCompatible(x, y) + element2Checked(i).checkInteger() + element2Checked(j).checkInteger() + el.unchecked.Pow2Zn(x, i, y, j) + return el +} + +func (el *checkedElement) Pow3Big(x Element, i *big.Int, y Element, j *big.Int, z Element, k *big.Int) Element { + el.checkAllCompatible(x, y, z) + el.unchecked.Pow3Big(x, i, y, j, z, k) + return el +} + +func (el *checkedElement) Pow3Zn(x, i, y, j, z, k Element) Element { + el.checkAllCompatible(x, y, z) + element2Checked(i).checkInteger() + element2Checked(j).checkInteger() + element2Checked(k).checkInteger() + el.unchecked.Pow3Zn(x, i, y, j, z, k) + return el +} + +func (el *checkedElement) PreparePower() Power { return initPower(el) } + +func (el *checkedElement) PowerBig(power Power, i *big.Int) Element { + el.unchecked.PowerBig(power, i) + return el +} + +func (el *checkedElement) PowerZn(power Power, i Element) Element { + element2Checked(i).checkInteger() + el.unchecked.PowerZn(power, i) + return el +} + +func (el *checkedElement) Pair(x, y Element) Element { + pairing := el.unchecked.pairing.data + checkFieldsMatch(el.fieldPtr, &pairing.GT[0]) + checkFieldsMatch(element2Checked(x).fieldPtr, pairing.G1) + checkFieldsMatch(element2Checked(y).fieldPtr, pairing.G2) + el.unchecked.Pair(x, y) + return el +} + +func (el *checkedElement) ProdPair(elements ...Element) Element { + pairing := el.unchecked.pairing.data + checkFieldsMatch(el.fieldPtr, &pairing.GT[0]) + n := len(elements) + for i := 1; i < n; i += 2 { + checkFieldsMatch(element2Checked(elements[i-1]).fieldPtr, pairing.G1) + checkFieldsMatch(element2Checked(elements[i]).fieldPtr, pairing.G2) + } + el.unchecked.ProdPair(elements...) + return el +} + +func (el *checkedElement) ProdPairSlice(x, y []Element) Element { + pairing := el.unchecked.pairing.data + checkFieldsMatch(el.fieldPtr, &pairing.GT[0]) + n := len(x) + for i := 1; i < n; i++ { + checkFieldsMatch(element2Checked(x[i]).fieldPtr, pairing.G1) + } + n = len(y) + for i := 1; i < n; i++ { + checkFieldsMatch(element2Checked(y[i]).fieldPtr, pairing.G2) + + } + el.unchecked.ProdPairSlice(x, y) + return el +} + +func (el *checkedElement) PreparePairer() Pairer { return initPairer(el) } + +func (el *checkedElement) PairerPair(pairer Pairer, x Element) Element { + in1 := element2Checked(pairer.(*pairerImpl).source) + in2 := element2Checked(x) + pairing := el.unchecked.pairing.data + checkFieldsMatch(in1.fieldPtr, pairing.G1) + checkFieldsMatch(in2.fieldPtr, pairing.G2) + checkFieldsMatch(el.fieldPtr, &pairing.GT[0]) + el.unchecked.PairerPair(pairer, x) + return el +} + +func (el *checkedElement) BruteForceDL(g, h Element) Element { + el.checkInteger() + element2Checked(g).checkCompatible(h) + el.unchecked.BruteForceDL(g, h) + return el +} + +func (el *checkedElement) PollardRhoDL(g, h Element) Element { + el.checkInteger() + element2Checked(g).checkCompatible(h) + el.unchecked.PollardRhoDL(g, h) + return el +} + +func (el *checkedElement) Rand() Element { + el.unchecked.Rand() + return el +} diff --git a/element_fmt.go b/element_fmt.go index 89c32d8..8587e2e 100644 --- a/element_fmt.go +++ b/element_fmt.go @@ -1,190 +1,189 @@ -package pbc - -/* -#cgo LDFLAGS: /usr/local/lib/libpbc.a -lgmp -#include <pbc/pbc.h> - -int element_out_str_wrapper(char** bufp, size_t* sizep, int base, element_t e) { - FILE* handle = open_memstream(bufp, sizep); - if (!handle) return 0; - element_out_str(handle, base, e); - fclose(handle); - return 1; -} -*/ -import "C" - -import ( - "bytes" - "errors" - "fmt" - "io" - "unsafe" -) - -var ( - ErrBadInput = errors.New("invalid element format during scan") - ErrBadVerb = errors.New("invalid verb specified for scan") -) - -func (el *elementImpl) errorFormat(f fmt.State, c rune, err string) { - fmt.Fprintf(f, "%%!%c(%s pbc.Element)", c, err) -} - -func (el *elementImpl) nativeFormat(f fmt.State, c rune) { - base := 10 - if width, ok := f.Width(); ok { - if width < 2 || width > 36 { - el.errorFormat(f, c, "BADBASE") - return - } - base = width - } - var buf *C.char - var bufLen C.size_t - if C.element_out_str_wrapper(&buf, &bufLen, C.int(base), el.data) == 0 { - el.errorFormat(f, c, "INTERNALERROR") - return - } - str := C.GoStringN(buf, C.int(bufLen)) - C.free(unsafe.Pointer(buf)) - fmt.Fprintf(f, "%s", str) -} - -func (el *elementImpl) customFormat(f fmt.State, c rune) { - count := el.Len() - if count == 0 { - el.BigInt().Format(f, c) - } else { - fmt.Fprintf(f, "[") - for i := 0; i < count; i++ { - el.Item(i).impl().customFormat(f, c) - if i+1 < count { - fmt.Fprintf(f, ", ") - } - } - fmt.Fprintf(f, "]") - } -} - -func (el *elementImpl) Format(f fmt.State, c rune) { - switch c { - case 'v': - if f.Flag('#') { - fmt.Fprintf(f, "pbc.Element{Checked: false, Pairing: %p, Addr: %p}", el.pairing, el) - break - } - fallthrough - case 's': - el.nativeFormat(f, c) - case 'd', 'b', 'o', 'x', 'X': - el.customFormat(f, c) - default: - el.errorFormat(f, c, "BADVERB") - } -} - -func (el *checkedElement) Format(f fmt.State, c rune) { - if c == 'v' && f.Flag('#') { - fmt.Fprintf(f, "pbc.Element{Checked: true, Integer: %t, Field: %p, Pairing: %p, Addr: %p}", el.isInteger, el.fieldPtr, el.unchecked.pairing, el) - } else { - el.unchecked.Format(f, c) - } -} - -func (el *elementImpl) String() string { - return fmt.Sprintf("%s", el) -} - -func (el *checkedElement) String() string { return el.unchecked.String() } - -func (el *elementImpl) Scan(state fmt.ScanState, verb rune) error { - if verb != 's' && verb != 'v' { - return ErrBadVerb - } - base, ok := state.Width() - if !ok { - base = 10 - } else if base < 2 || base > 36 { - return ErrBadVerb - } - maxDigit := '9' - maxAlpha := 'z' - if base < 10 { - maxDigit = rune('0' + (base - 1)) - } - if base < 36 { - maxAlpha = rune('a' + (base - 11)) - } - - state.SkipSpace() - - tokensFound := make([]uint, 0, 5) - inToken := false - justDescended := false - expectTokenDone := false - var buf bytes.Buffer - -ReadLoop: - for { - r, _, err := state.ReadRune() - if err != nil { - if err == io.EOF { - if len(tokensFound) == 0 { - break ReadLoop - } - return ErrBadInput - } - return err - } - buf.WriteRune(r) - - if expectTokenDone && r != ',' && r != ']' { - return ErrBadInput - } - expectTokenDone = false - - switch r { - case '[': - if inToken { - return ErrBadInput - } - tokensFound = append(tokensFound, 0) - case ']': - if !inToken || len(tokensFound) == 0 || tokensFound[len(tokensFound)-1] == 0 { - return ErrBadInput - } - tokensFound = tokensFound[:len(tokensFound)-1] - if len(tokensFound) == 0 { - break ReadLoop - } - case ',': - if len(tokensFound) == 0 || (!inToken && !justDescended) { - return ErrBadInput - } - tokensFound[len(tokensFound)-1]++ - inToken = false - state.SkipSpace() - case 'O': - if inToken { - return ErrBadInput - } - expectTokenDone = true - inToken = true - default: - if (r < '0' || r > maxDigit) && (r < 'a' || r > maxAlpha) { - return ErrBadInput - } - inToken = true - } - justDescended = (r == ']') - } - if _, ok := el.SetString(buf.String(), base); !ok { - return ErrBadInput - } - return nil -} - -func (el *checkedElement) Scan(state fmt.ScanState, verb rune) error { - return el.unchecked.Scan(state, verb) -} +package pbc + +/* +#include <pbc/pbc.h> + +int element_out_str_wrapper(char** bufp, size_t* sizep, int base, element_t e) { + FILE* handle = open_memstream(bufp, sizep); + if (!handle) return 0; + element_out_str(handle, base, e); + fclose(handle); + return 1; +} +*/ +import "C" + +import ( + "bytes" + "errors" + "fmt" + "io" + "unsafe" +) + +var ( + ErrBadInput = errors.New("invalid element format during scan") + ErrBadVerb = errors.New("invalid verb specified for scan") +) + +func (el *elementImpl) errorFormat(f fmt.State, c rune, err string) { + fmt.Fprintf(f, "%%!%c(%s pbc.Element)", c, err) +} + +func (el *elementImpl) nativeFormat(f fmt.State, c rune) { + base := 10 + if width, ok := f.Width(); ok { + if width < 2 || width > 36 { + el.errorFormat(f, c, "BADBASE") + return + } + base = width + } + var buf *C.char + var bufLen C.size_t + if C.element_out_str_wrapper(&buf, &bufLen, C.int(base), el.data) == 0 { + el.errorFormat(f, c, "INTERNALERROR") + return + } + str := C.GoStringN(buf, C.int(bufLen)) + C.free(unsafe.Pointer(buf)) + fmt.Fprintf(f, "%s", str) +} + +func (el *elementImpl) customFormat(f fmt.State, c rune) { + count := el.Len() + if count == 0 { + el.BigInt().Format(f, c) + } else { + fmt.Fprintf(f, "[") + for i := 0; i < count; i++ { + el.Item(i).impl().customFormat(f, c) + if i+1 < count { + fmt.Fprintf(f, ", ") + } + } + fmt.Fprintf(f, "]") + } +} + +func (el *elementImpl) Format(f fmt.State, c rune) { + switch c { + case 'v': + if f.Flag('#') { + fmt.Fprintf(f, "pbc.Element{Checked: false, Pairing: %p, Addr: %p}", el.pairing, el) + break + } + fallthrough + case 's': + el.nativeFormat(f, c) + case 'd', 'b', 'o', 'x', 'X': + el.customFormat(f, c) + default: + el.errorFormat(f, c, "BADVERB") + } +} + +func (el *checkedElement) Format(f fmt.State, c rune) { + if c == 'v' && f.Flag('#') { + fmt.Fprintf(f, "pbc.Element{Checked: true, Integer: %t, Field: %p, Pairing: %p, Addr: %p}", el.isInteger, el.fieldPtr, el.unchecked.pairing, el) + } else { + el.unchecked.Format(f, c) + } +} + +func (el *elementImpl) String() string { + return fmt.Sprintf("%s", el) +} + +func (el *checkedElement) String() string { return el.unchecked.String() } + +func (el *elementImpl) Scan(state fmt.ScanState, verb rune) error { + if verb != 's' && verb != 'v' { + return ErrBadVerb + } + base, ok := state.Width() + if !ok { + base = 10 + } else if base < 2 || base > 36 { + return ErrBadVerb + } + maxDigit := '9' + maxAlpha := 'z' + if base < 10 { + maxDigit = rune('0' + (base - 1)) + } + if base < 36 { + maxAlpha = rune('a' + (base - 11)) + } + + state.SkipSpace() + + tokensFound := make([]uint, 0, 5) + inToken := false + justDescended := false + expectTokenDone := false + var buf bytes.Buffer + +ReadLoop: + for { + r, _, err := state.ReadRune() + if err != nil { + if err == io.EOF { + if len(tokensFound) == 0 { + break ReadLoop + } + return ErrBadInput + } + return err + } + buf.WriteRune(r) + + if expectTokenDone && r != ',' && r != ']' { + return ErrBadInput + } + expectTokenDone = false + + switch r { + case '[': + if inToken { + return ErrBadInput + } + tokensFound = append(tokensFound, 0) + case ']': + if !inToken || len(tokensFound) == 0 || tokensFound[len(tokensFound)-1] == 0 { + return ErrBadInput + } + tokensFound = tokensFound[:len(tokensFound)-1] + if len(tokensFound) == 0 { + break ReadLoop + } + case ',': + if len(tokensFound) == 0 || (!inToken && !justDescended) { + return ErrBadInput + } + tokensFound[len(tokensFound)-1]++ + inToken = false + state.SkipSpace() + case 'O': + if inToken { + return ErrBadInput + } + expectTokenDone = true + inToken = true + default: + if (r < '0' || r > maxDigit) && (r < 'a' || r > maxAlpha) { + return ErrBadInput + } + inToken = true + } + justDescended = (r == ']') + } + if _, ok := el.SetString(buf.String(), base); !ok { + return ErrBadInput + } + return nil +} + +func (el *checkedElement) Scan(state fmt.ScanState, verb rune) error { + return el.unchecked.Scan(state, verb) +} diff --git a/element_unchecked.go b/element_unchecked.go index 347f7e9..3c8c88c 100644 --- a/element_unchecked.go +++ b/element_unchecked.go @@ -1,341 +1,340 @@ -package pbc - -/* -#cgo LDFLAGS: /usr/local/lib/libpbc.a -lgmp -#include <pbc/pbc.h> -*/ -import "C" - -import ( - "errors" - "math/big" - "unsafe" -) - -var ErrBadPairList = errors.New("pairing product list is in an invalid format") - -func (el *elementImpl) impl() *elementImpl { return el } - -func (el *elementImpl) NewFieldElement() Element { - newElement := &elementImpl{} - initElement(newElement, el.pairing, false, G1) - C.element_init_same_as(newElement.data, el.data) - return newElement -} - -func (el *elementImpl) Set0() Element { - C.element_set0(el.data) - return el -} - -func (el *elementImpl) Set1() Element { - C.element_set1(el.data) - return el -} - -func (el *elementImpl) SetInt32(i int32) Element { - C.element_set_si(el.data, C.long(i)) - return el -} - -func (el *elementImpl) SetBig(i *big.Int) Element { - C.element_set_mpz(el.data, &big2mpz(i)[0]) - return el -} - -func (el *elementImpl) Set(src Element) Element { - C.element_set(el.data, src.impl().data) - return el -} - -func (el *elementImpl) SetFromHash(hash []byte) Element { - C.element_from_hash(el.data, unsafe.Pointer(&hash[0]), C.int(len(hash))) - return el -} - -func (el *elementImpl) SetBytes(buf []byte) Element { - C.element_from_bytes(el.data, (*C.uchar)(unsafe.Pointer(&buf[0]))) - return el -} - -func (el *elementImpl) SetXBytes(buf []byte) Element { - C.element_from_bytes_x_only(el.data, (*C.uchar)(unsafe.Pointer(&buf[0]))) - return el -} - -func (el *elementImpl) SetCompressedBytes(buf []byte) Element { - C.element_from_bytes_compressed(el.data, (*C.uchar)(unsafe.Pointer(&buf[0]))) - return el -} - -func (el *elementImpl) SetString(s string, base int) (Element, bool) { - cstr := C.CString(s) - defer C.free(unsafe.Pointer(cstr)) - - if ok := C.element_set_str(el.data, cstr, C.int(base)); ok == 0 { - return nil, false - } - return el, true -} - -func (el *elementImpl) BigInt() *big.Int { - mpz := newmpz() - C.element_to_mpz(&mpz[0], el.data) - return mpz2big(mpz) -} - -func (el *elementImpl) BytesLen() int { - return int(C.element_length_in_bytes(el.data)) -} - -func (el *elementImpl) writeBytes(buf []byte) C.int { - return C.element_to_bytes((*C.uchar)(unsafe.Pointer(&buf[0])), el.data) -} - -func (el *elementImpl) Bytes() []byte { - buf := make([]byte, el.BytesLen()) - el.writeBytes(buf) - return buf -} - -func (el *elementImpl) XBytesLen() int { - return int(C.element_length_in_bytes_x_only(el.data)) -} - -func (el *elementImpl) writeXBytes(buf []byte) C.int { - return C.element_to_bytes_x_only((*C.uchar)(unsafe.Pointer(&buf[0])), el.data) -} - -func (el *elementImpl) XBytes() []byte { - buf := make([]byte, el.XBytesLen()) - el.writeXBytes(buf) - return buf -} - -func (el *elementImpl) CompressedBytesLen() int { - return int(C.element_length_in_bytes_compressed(el.data)) -} - -func (el *elementImpl) writeCompressedBytes(buf []byte) C.int { - return C.element_to_bytes_compressed((*C.uchar)(unsafe.Pointer(&buf[0])), el.data) -} - -func (el *elementImpl) CompressedBytes() []byte { - buf := make([]byte, el.CompressedBytesLen()) - el.writeCompressedBytes(buf) - return buf -} - -func (el *elementImpl) Len() int { - return int(C.element_item_count(el.data)) -} - -func (el *elementImpl) Item(i int) Element { - return &elementImpl{ - pairing: el.pairing, - data: C.element_item(el.data, C.int(i)), - } -} - -func (el *elementImpl) X() *big.Int { - return el.Item(0).BigInt() -} - -func (el *elementImpl) Y() *big.Int { - return el.Item(1).BigInt() -} - -func (el *elementImpl) Is0() bool { - return C.element_is0(el.data) != 0 -} - -func (el *elementImpl) Is1() bool { - return C.element_is1(el.data) != 0 -} - -func (el *elementImpl) IsSquare() bool { - return C.element_is_sqr(el.data) != 0 -} - -func normalizeSign(sign int64) int { - if sign > 0 { - return 1 - } - if sign < 0 { - return -1 - } - return 0 -} - -func (el *elementImpl) Sign() int { - return normalizeSign(int64(C.element_sign(el.data))) -} - -func (el *elementImpl) Cmp(x Element) int { - return normalizeSign(int64(C.element_cmp(el.data, x.impl().data))) -} - -func (el *elementImpl) Add(x, y Element) Element { - C.element_add(el.data, x.impl().data, y.impl().data) - return el -} - -func (el *elementImpl) Sub(x, y Element) Element { - C.element_sub(el.data, x.impl().data, y.impl().data) - return el -} - -func (el *elementImpl) Mul(x, y Element) Element { - C.element_mul(el.data, x.impl().data, y.impl().data) - return el -} - -func (el *elementImpl) MulBig(x Element, i *big.Int) Element { - C.element_mul_mpz(el.data, x.impl().data, &big2mpz(i)[0]) - return el -} - -func (el *elementImpl) MulInt32(x Element, i int32) Element { - C.element_mul_si(el.data, x.impl().data, C.long(i)) - return el -} - -func (el *elementImpl) MulZn(x, y Element) Element { - C.element_mul_zn(el.data, x.impl().data, y.impl().data) - return el -} - -func (el *elementImpl) Div(x, y Element) Element { - C.element_div(el.data, x.impl().data, y.impl().data) - return el -} - -func (el *elementImpl) Double(x Element) Element { - C.element_double(el.data, x.impl().data) - return el -} - -func (el *elementImpl) Halve(x Element) Element { - C.element_halve(el.data, x.impl().data) - return el -} - -func (el *elementImpl) Square(x Element) Element { - C.element_square(el.data, x.impl().data) - return el -} - -func (el *elementImpl) Neg(x Element) Element { - C.element_neg(el.data, x.impl().data) - return el -} - -func (el *elementImpl) Invert(x Element) Element { - C.element_invert(el.data, x.impl().data) - return el -} - -func (el *elementImpl) PowBig(x Element, i *big.Int) Element { - C.element_pow_mpz(el.data, x.impl().data, &big2mpz(i)[0]) - return el -} - -func (el *elementImpl) PowZn(x, i Element) Element { - C.element_pow_zn(el.data, x.impl().data, i.impl().data) - return el -} - -func (el *elementImpl) Pow2Big(x Element, i *big.Int, y Element, j *big.Int) Element { - C.element_pow2_mpz(el.data, x.impl().data, &big2mpz(i)[0], y.impl().data, &big2mpz(j)[0]) - return el -} - -func (el *elementImpl) Pow2Zn(x, i, y, j Element) Element { - C.element_pow2_zn(el.data, x.impl().data, i.impl().data, y.impl().data, j.impl().data) - return el -} - -func (el *elementImpl) Pow3Big(x Element, i *big.Int, y Element, j *big.Int, z Element, k *big.Int) Element { - C.element_pow3_mpz(el.data, x.impl().data, &big2mpz(i)[0], y.impl().data, &big2mpz(j)[0], z.impl().data, &big2mpz(k)[0]) - return el -} - -func (el *elementImpl) Pow3Zn(x, i, y, j, z, k Element) Element { - C.element_pow3_zn(el.data, x.impl().data, i.impl().data, y.impl().data, j.impl().data, z.impl().data, k.impl().data) - return el -} - -func (el *elementImpl) PreparePower() Power { return initPower(el) } - -func (el *elementImpl) PowerBig(power Power, i *big.Int) Element { - C.element_pp_pow(el.data, &big2mpz(i)[0], power.(*powerImpl).data) - return el -} - -func (el *elementImpl) PowerZn(power Power, i Element) Element { - C.element_pp_pow_zn(el.data, i.impl().data, power.(*powerImpl).data) - return el -} - -func (el *elementImpl) Pair(x, y Element) Element { - C.element_pairing(el.data, x.impl().data, y.impl().data) - return el -} - -func (el *elementImpl) doProdPair(in1, in2 []C.struct_element_s) Element { - x := (*C.element_t)(unsafe.Pointer(&in1[0])) - y := (*C.element_t)(unsafe.Pointer(&in2[0])) - C.element_prod_pairing(el.data, x, y, C.int(len(in1))) - return el -} - -func (el *elementImpl) ProdPair(elements ...Element) Element { - n := len(elements) - if n%2 != 0 { - panic(ErrBadPairList) - } - half := n / 2 - in1 := make([]C.struct_element_s, half) - in2 := make([]C.struct_element_s, half) - for i, j := 0, 0; j < n; i, j = i+1, j+2 { - in1[i] = *elements[j].impl().data - in2[i] = *elements[j+1].impl().data - } - return el.doProdPair(in1, in2) -} - -func (el *elementImpl) ProdPairSlice(x, y []Element) Element { - n := len(x) - if n != len(y) { - panic(ErrBadPairList) - } - in1 := make([]C.struct_element_s, n) - in2 := make([]C.struct_element_s, n) - for i := 0; i < n; i++ { - in1[i] = *x[i].impl().data - in2[i] = *y[i].impl().data - } - return el.doProdPair(in1, in2) -} - -func (el *elementImpl) PreparePairer() Pairer { return initPairer(el) } - -func (el *elementImpl) PairerPair(pairer Pairer, x Element) Element { - C.pairing_pp_apply(el.data, x.impl().data, pairer.(*pairerImpl).data) - return el -} - -func (el *elementImpl) BruteForceDL(g, h Element) Element { - C.element_dlog_brute_force(el.data, g.impl().data, h.impl().data) - return el -} - -func (el *elementImpl) PollardRhoDL(g, h Element) Element { - C.element_dlog_pollard_rho(el.data, g.impl().data, h.impl().data) - return el -} - -func (el *elementImpl) Rand() Element { - C.element_random(el.data) - return el -} +package pbc + +/* +#include <pbc/pbc.h> +*/ +import "C" + +import ( + "errors" + "math/big" + "unsafe" +) + +var ErrBadPairList = errors.New("pairing product list is in an invalid format") + +func (el *elementImpl) impl() *elementImpl { return el } + +func (el *elementImpl) NewFieldElement() Element { + newElement := &elementImpl{} + initElement(newElement, el.pairing, false, G1) + C.element_init_same_as(newElement.data, el.data) + return newElement +} + +func (el *elementImpl) Set0() Element { + C.element_set0(el.data) + return el +} + +func (el *elementImpl) Set1() Element { + C.element_set1(el.data) + return el +} + +func (el *elementImpl) SetInt32(i int32) Element { + C.element_set_si(el.data, C.long(i)) + return el +} + +func (el *elementImpl) SetBig(i *big.Int) Element { + C.element_set_mpz(el.data, &big2mpz(i)[0]) + return el +} + +func (el *elementImpl) Set(src Element) Element { + C.element_set(el.data, src.impl().data) + return el +} + +func (el *elementImpl) SetFromHash(hash []byte) Element { + C.element_from_hash(el.data, unsafe.Pointer(&hash[0]), C.int(len(hash))) + return el +} + +func (el *elementImpl) SetBytes(buf []byte) Element { + C.element_from_bytes(el.data, (*C.uchar)(unsafe.Pointer(&buf[0]))) + return el +} + +func (el *elementImpl) SetXBytes(buf []byte) Element { + C.element_from_bytes_x_only(el.data, (*C.uchar)(unsafe.Pointer(&buf[0]))) + return el +} + +func (el *elementImpl) SetCompressedBytes(buf []byte) Element { + C.element_from_bytes_compressed(el.data, (*C.uchar)(unsafe.Pointer(&buf[0]))) + return el +} + +func (el *elementImpl) SetString(s string, base int) (Element, bool) { + cstr := C.CString(s) + defer C.free(unsafe.Pointer(cstr)) + + if ok := C.element_set_str(el.data, cstr, C.int(base)); ok == 0 { + return nil, false + } + return el, true +} + +func (el *elementImpl) BigInt() *big.Int { + mpz := newmpz() + C.element_to_mpz(&mpz[0], el.data) + return mpz2big(mpz) +} + +func (el *elementImpl) BytesLen() int { + return int(C.element_length_in_bytes(el.data)) +} + +func (el *elementImpl) writeBytes(buf []byte) C.int { + return C.element_to_bytes((*C.uchar)(unsafe.Pointer(&buf[0])), el.data) +} + +func (el *elementImpl) Bytes() []byte { + buf := make([]byte, el.BytesLen()) + el.writeBytes(buf) + return buf +} + +func (el *elementImpl) XBytesLen() int { + return int(C.element_length_in_bytes_x_only(el.data)) +} + +func (el *elementImpl) writeXBytes(buf []byte) C.int { + return C.element_to_bytes_x_only((*C.uchar)(unsafe.Pointer(&buf[0])), el.data) +} + +func (el *elementImpl) XBytes() []byte { + buf := make([]byte, el.XBytesLen()) + el.writeXBytes(buf) + return buf +} + +func (el *elementImpl) CompressedBytesLen() int { + return int(C.element_length_in_bytes_compressed(el.data)) +} + +func (el *elementImpl) writeCompressedBytes(buf []byte) C.int { + return C.element_to_bytes_compressed((*C.uchar)(unsafe.Pointer(&buf[0])), el.data) +} + +func (el *elementImpl) CompressedBytes() []byte { + buf := make([]byte, el.CompressedBytesLen()) + el.writeCompressedBytes(buf) + return buf +} + +func (el *elementImpl) Len() int { + return int(C.element_item_count(el.data)) +} + +func (el *elementImpl) Item(i int) Element { + return &elementImpl{ + pairing: el.pairing, + data: C.element_item(el.data, C.int(i)), + } +} + +func (el *elementImpl) X() *big.Int { + return el.Item(0).BigInt() +} + +func (el *elementImpl) Y() *big.Int { + return el.Item(1).BigInt() +} + +func (el *elementImpl) Is0() bool { + return C.element_is0(el.data) != 0 +} + +func (el *elementImpl) Is1() bool { + return C.element_is1(el.data) != 0 +} + +func (el *elementImpl) IsSquare() bool { + return C.element_is_sqr(el.data) != 0 +} + +func normalizeSign(sign int64) int { + if sign > 0 { + return 1 + } + if sign < 0 { + return -1 + } + return 0 +} + +func (el *elementImpl) Sign() int { + return normalizeSign(int64(C.element_sign(el.data))) +} + +func (el *elementImpl) Cmp(x Element) int { + return normalizeSign(int64(C.element_cmp(el.data, x.impl().data))) +} + +func (el *elementImpl) Add(x, y Element) Element { + C.element_add(el.data, x.impl().data, y.impl().data) + return el +} + +func (el *elementImpl) Sub(x, y Element) Element { + C.element_sub(el.data, x.impl().data, y.impl().data) + return el +} + +func (el *elementImpl) Mul(x, y Element) Element { + C.element_mul(el.data, x.impl().data, y.impl().data) + return el +} + +func (el *elementImpl) MulBig(x Element, i *big.Int) Element { + C.element_mul_mpz(el.data, x.impl().data, &big2mpz(i)[0]) + return el +} + +func (el *elementImpl) MulInt32(x Element, i int32) Element { + C.element_mul_si(el.data, x.impl().data, C.long(i)) + return el +} + +func (el *elementImpl) MulZn(x, y Element) Element { + C.element_mul_zn(el.data, x.impl().data, y.impl().data) + return el +} + +func (el *elementImpl) Div(x, y Element) Element { + C.element_div(el.data, x.impl().data, y.impl().data) + return el +} + +func (el *elementImpl) Double(x Element) Element { + C.element_double(el.data, x.impl().data) + return el +} + +func (el *elementImpl) Halve(x Element) Element { + C.element_halve(el.data, x.impl().data) + return el +} + +func (el *elementImpl) Square(x Element) Element { + C.element_square(el.data, x.impl().data) + return el +} + +func (el *elementImpl) Neg(x Element) Element { + C.element_neg(el.data, x.impl().data) + return el +} + +func (el *elementImpl) Invert(x Element) Element { + C.element_invert(el.data, x.impl().data) + return el +} + +func (el *elementImpl) PowBig(x Element, i *big.Int) Element { + C.element_pow_mpz(el.data, x.impl().data, &big2mpz(i)[0]) + return el +} + +func (el *elementImpl) PowZn(x, i Element) Element { + C.element_pow_zn(el.data, x.impl().data, i.impl().data) + return el +} + +func (el *elementImpl) Pow2Big(x Element, i *big.Int, y Element, j *big.Int) Element { + C.element_pow2_mpz(el.data, x.impl().data, &big2mpz(i)[0], y.impl().data, &big2mpz(j)[0]) + return el +} + +func (el *elementImpl) Pow2Zn(x, i, y, j Element) Element { + C.element_pow2_zn(el.data, x.impl().data, i.impl().data, y.impl().data, j.impl().data) + return el +} + +func (el *elementImpl) Pow3Big(x Element, i *big.Int, y Element, j *big.Int, z Element, k *big.Int) Element { + C.element_pow3_mpz(el.data, x.impl().data, &big2mpz(i)[0], y.impl().data, &big2mpz(j)[0], z.impl().data, &big2mpz(k)[0]) + return el +} + +func (el *elementImpl) Pow3Zn(x, i, y, j, z, k Element) Element { + C.element_pow3_zn(el.data, x.impl().data, i.impl().data, y.impl().data, j.impl().data, z.impl().data, k.impl().data) + return el +} + +func (el *elementImpl) PreparePower() Power { return initPower(el) } + +func (el *elementImpl) PowerBig(power Power, i *big.Int) Element { + C.element_pp_pow(el.data, &big2mpz(i)[0], power.(*powerImpl).data) + return el +} + +func (el *elementImpl) PowerZn(power Power, i Element) Element { + C.element_pp_pow_zn(el.data, i.impl().data, power.(*powerImpl).data) + return el +} + +func (el *elementImpl) Pair(x, y Element) Element { + C.pairing_apply(el.data, x.impl().data, y.impl().data, el.pairing.data) + return el +} + +func (el *elementImpl) doProdPair(in1, in2 []C.struct_element_s) Element { + x := (*C.element_t)(unsafe.Pointer(&in1[0])) + y := (*C.element_t)(unsafe.Pointer(&in2[0])) + C.element_prod_pairing(el.data, x, y, C.int(len(in1))) + return el +} + +func (el *elementImpl) ProdPair(elements ...Element) Element { + n := len(elements) + if n%2 != 0 { + panic(ErrBadPairList) + } + half := n / 2 + in1 := make([]C.struct_element_s, half) + in2 := make([]C.struct_element_s, half) + for i, j := 0, 0; j < n; i, j = i+1, j+2 { + in1[i] = *elements[j].impl().data + in2[i] = *elements[j+1].impl().data + } + return el.doProdPair(in1, in2) +} + +func (el *elementImpl) ProdPairSlice(x, y []Element) Element { + n := len(x) + if n != len(y) { + panic(ErrBadPairList) + } + in1 := make([]C.struct_element_s, n) + in2 := make([]C.struct_element_s, n) + for i := 0; i < n; i++ { + in1[i] = *x[i].impl().data + in2[i] = *y[i].impl().data + } + return el.doProdPair(in1, in2) +} + +func (el *elementImpl) PreparePairer() Pairer { return initPairer(el) } + +func (el *elementImpl) PairerPair(pairer Pairer, x Element) Element { + C.pairing_pp_apply(el.data, x.impl().data, pairer.(*pairerImpl).data) + return el +} + +func (el *elementImpl) BruteForceDL(g, h Element) Element { + C.element_dlog_brute_force(el.data, g.impl().data, h.impl().data) + return el +} + +func (el *elementImpl) PollardRhoDL(g, h Element) Element { + C.element_dlog_pollard_rho(el.data, g.impl().data, h.impl().data) + return el +} + +func (el *elementImpl) Rand() Element { + C.element_random(el.data) + return el +} diff --git a/generation.go b/generation.go index 3680135..a818935 100644 --- a/generation.go +++ b/generation.go @@ -1,7 +1,6 @@ package pbc /* -#cgo LDFLAGS: /usr/local/lib/libpbc.a -lgmp #include <pbc/pbc.h> int acceptPairingD(pbc_cm_t cm, void* p) { @@ -13,18 +12,13 @@ int acceptPairingG(pbc_cm_t cm, void* p) { pbc_param_init_g_gen((pbc_param_ptr)p, cm); return 1; } - -void genPairingD(pbc_param_ptr p, unsigned int D, unsigned int bitlimit) { - pbc_cm_search_d(acceptPairingD, p, D, bitlimit); -} - -void genPairingG(pbc_param_ptr p, unsigned int D, unsigned int bitlimit) { - pbc_cm_search_g(acceptPairingG, p, D, bitlimit); -} */ import "C" -import "math/big" +import ( + "math/big" + "unsafe" +) func GenerateA(rbits uint32, qbits uint32) Params { params := makeParams() @@ -40,7 +34,7 @@ func GenerateA1(n *big.Int) Params { func GenerateD(d uint32, bitlimit uint32) Params { params := makeParams() - C.genPairingD(params, C.uint(d), C.uint(bitlimit)) + C.pbc_cm_search_d((*[0]byte)(C.acceptPairingD), unsafe.Pointer(params), C.uint(d), C.uint(bitlimit)) return params } @@ -58,6 +52,6 @@ func GenerateF(bits uint32) Params { func GenerateG(d uint32, bitlimit uint32) Params { params := makeParams() - C.genPairingG(params, C.uint(d), C.uint(bitlimit)) + C.pbc_cm_search_d((*[0]byte)(C.acceptPairingG), unsafe.Pointer(params), C.uint(d), C.uint(bitlimit)) return params } diff --git a/gmp_big.go b/gmp_big.go index 1f8baad..7b55617 100644 --- a/gmp_big.go +++ b/gmp_big.go @@ -1,8 +1,6 @@ package pbc /* -#cgo CFLAGS: -std=gnu99 -#cgo LDFLAGS: -lgmp #include <gmp.h> */ import "C" diff --git a/pairing.go b/pairing.go index 4b60eb0..00455e6 100644 --- a/pairing.go +++ b/pairing.go @@ -1,7 +1,6 @@ package pbc /* -#cgo LDFLAGS: /usr/local/lib/libpbc.a -lgmp #include <pbc/pbc.h> */ import "C" diff --git a/params.go b/params.go index c1a9e6d..6f6b6e5 100644 --- a/params.go +++ b/params.go @@ -1,7 +1,6 @@ package pbc /* -#cgo LDFLAGS: /usr/local/lib/libpbc.a -lgmp #include <pbc/pbc.h> int param_out_str_wrapper(char** bufp, size_t* sizep, pbc_param_t p) { -- GitLab