diff --git a/c.go b/c.go
new file mode 100644
index 0000000000000000000000000000000000000000..91972e05701104803ddbb6d49558cbb32a31837c
--- /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 5f2aae58bbba236b139c17f03e8809e58e0b441e..b00ea72d5f0d589b941c389897056dabac05e4a5 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 34e9f6eb8153d9ca14c1399d17fb65d2dcdab4d0..cb8f223cab2bd57a909a572d4904962bf1e73f94 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 89c32d8f6a4b542491127d39ae0fb46c3276a1d4..8587e2e30416320b357010027891cc6880ebfba4 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 347f7e9dad1eb7f8093c40cecfdb47b649868742..3c8c88c44c385bc36b69bce5a05b402fddb08197 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 368013593e602940b58c2245d79d2dc98f593765..a818935c6516f7f9debd9a6f19b62c87996fc784 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 1f8baadc6dde6806d04bf0289e60f4d90296788e..7b5561770d45ce54b54449a47fadc8c3db0817da 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 4b60eb04c3336a6509af713c89edd321463b290d..00455e654c70ee1edbf21b9ec37894be23fbb1a8 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 c1a9e6dc32b826ef1c0e1bc6bf9437266302497a..6f6b6e59a99b9224105cb4345d162bd81f8991a7 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) {