package bls
/*
#cgo CFLAGS:-I../../../include -I../../../../mcl/include/
#cgo LDFLAGS:-L../../../lib
#cgo CFLAGS:-DMCLBN_FP_UNIT_SIZE=6
#cgo LDFLAGS:-lbls384_dy -lcrypto -lgmp -lgmpxx -lstdc++
#include <bls/bls.h>
*/
import "C"
import "fmt"
import "unsafe"
// Init --
// call this function before calling all the other operations
// this function is not thread safe
func Init(curve int) error {
err := C.blsInit(C.int(curve), C.MCLBN_FP_UNIT_SIZE)
if err != 0 {
return fmt.Errorf("ERR Init curve=%d", curve)
}
return nil
}
// ID --
type ID struct {
v Fr
}
// getPointer --
func (id *ID) getPointer() (p *C.blsId) {
// #nosec
return (*C.blsId)(unsafe.Pointer(id))
}
// GetLittleEndian --
func (id *ID) GetLittleEndian() []byte {
return id.v.Serialize()
}
// SetLittleEndian --
func (id *ID) SetLittleEndian(buf []byte) error {
return id.v.SetLittleEndian(buf)
}
// GetHexString --
func (id *ID) GetHexString() string {
return id.v.GetString(16)
}
// GetDecString --
func (id *ID) GetDecString() string {
return id.v.GetString(10)
}
// SetHexString --
func (id *ID) SetHexString(s string) error {
return id.v.SetString(s, 16)
}
// SetDecString --
func (id *ID) SetDecString(s string) error {
return id.v.SetString(s, 10)
}
// IsEqual --
func (id *ID) IsEqual(rhs *ID) bool {
return id.v.IsEqual(&rhs.v)
}
// SecretKey --
type SecretKey struct {
v Fr
}
// getPointer --
func (sec *SecretKey) getPointer() (p *C.blsSecretKey) {
// #nosec
return (*C.blsSecretKey)(unsafe.Pointer(sec))
}
// GetLittleEndian --
func (sec *SecretKey) GetLittleEndian() []byte {
return sec.v.Serialize()
}
// SetLittleEndian --
func (sec *SecretKey) SetLittleEndian(buf []byte) error {
return sec.v.SetLittleEndian(buf)
}
// GetHexString --
func (sec *SecretKey) GetHexString() string {
return sec.v.GetString(16)
}
// GetDecString --
func (sec *SecretKey) GetDecString() string {
return sec.v.GetString(10)
}
// SetHexString --
func (sec *SecretKey) SetHexString(s string) error {
return sec.v.SetString(s, 16)
}
// SetDecString --
func (sec *SecretKey) SetDecString(s string) error {
return sec.v.SetString(s, 10)
}
// IsEqual --
func (sec *SecretKey) IsEqual(rhs *SecretKey) bool {
return sec.v.IsEqual(&rhs.v)
}
// SetByCSPRNG --
func (sec *SecretKey) SetByCSPRNG() {
sec.v.SetByCSPRNG()
}
// Add --
func (sec *SecretKey) Add(rhs *SecretKey) {
FrAdd(&sec.v, &sec.v, &rhs.v)
}
// GetMasterSecretKey --
func (sec *SecretKey) GetMasterSecretKey(k int) (msk []SecretKey) {
msk = make([]SecretKey, k)
msk[0] = *sec
for i := 1; i < k; i++ {
msk[i].SetByCSPRNG()
}
return msk
}
// GetMasterPublicKey --
func GetMasterPublicKey(msk []SecretKey) (mpk []PublicKey) {
n := len(msk)
mpk = make([]PublicKey, n)
for i := 0; i < n; i++ {
mpk[i] = *msk[i].GetPublicKey()
}
return mpk
}
// Set --
func (sec *SecretKey) Set(msk []SecretKey, id *ID) error {
// #nosec
return FrEvaluatePolynomial(&sec.v, *(*[]Fr)(unsafe.Pointer(&msk)), &id.v)
}
// Recover --
func (sec *SecretKey) Recover(secVec []SecretKey, idVec []ID) error {
// #nosec
return FrLagrangeInterpolation(&sec.v, *(*[]Fr)(unsafe.Pointer(&idVec)), *(*[]Fr)(unsafe.Pointer(&secVec)))
}
// GetPop --
func (sec *SecretKey) GetPop() (sign *Sign) {
sign = new(Sign)
C.blsGetPop(sign.getPointer(), sec.getPointer())
return sign
}
// PublicKey --
type PublicKey struct {
v G2
}
// getPointer --
func (pub *PublicKey) getPointer() (p *C.blsPublicKey) {
// #nosec
return (*C.blsPublicKey)(unsafe.Pointer(pub))
}
// Serialize --
func (pub *PublicKey) Serialize() []byte {
return pub.v.Serialize()
}
// Deserialize --
func (pub *PublicKey) Deserialize(buf []byte) error {
return pub.v.Deserialize(buf)
}
// GetHexString --
func (pub *PublicKey) GetHexString() string {
return pub.v.GetString(16)
}
// SetHexString --
func (pub *PublicKey) SetHexString(s string) error {
return pub.v.SetString(s, 16)
}
// IsEqual --
func (pub *PublicKey) IsEqual(rhs *PublicKey) bool {
return pub.v.IsEqual(&rhs.v)
}
// Add --
func (pub *PublicKey) Add(rhs *PublicKey) {
G2Add(&pub.v, &pub.v, &rhs.v)
}
// Set --
func (pub *PublicKey) Set(mpk []PublicKey, id *ID) error {
// #nosec
return G2EvaluatePolynomial(&pub.v, *(*[]G2)(unsafe.Pointer(&mpk)), &id.v)
}
// Recover --
func (pub *PublicKey) Recover(pubVec []PublicKey, idVec []ID) error {
// #nosec
return G2LagrangeInterpolation(&pub.v, *(*[]Fr)(unsafe.Pointer(&idVec)), *(*[]G2)(unsafe.Pointer(&pubVec)))
}
// Sign --
type Sign struct {
v G1
}
// getPointer --
func (sign *Sign) getPointer() (p *C.blsSignature) {
// #nosec
return (*C.blsSignature)(unsafe.Pointer(sign))
}
// Serialize --
func (sign *Sign) Serialize() []byte {
return sign.v.Serialize()
}
// Deserialize --
func (sign *Sign) Deserialize(buf []byte) error {
return sign.v.Deserialize(buf)
}
// GetHexString --
func (sign *Sign) GetHexString() string {
return sign.v.GetString(16)
}
// SetHexString --
func (sign *Sign) SetHexString(s string) error {
return sign.v.SetString(s, 16)
}
// IsEqual --
func (sign *Sign) IsEqual(rhs *Sign) bool {
return sign.v.IsEqual(&rhs.v)
}
// GetPublicKey --
func (sec *SecretKey) GetPublicKey() (pub *PublicKey) {
pub = new(PublicKey)
C.blsGetPublicKey(pub.getPointer(), sec.getPointer())
return pub
}
// Sign -- Constant Time version
func (sec *SecretKey) Sign(m string) (sign *Sign) {
sign = new(Sign)
buf := []byte(m)
// #nosec
C.blsSign(sign.getPointer(), sec.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf)))
return sign
}
// Add --
func (sign *Sign) Add(rhs *Sign) {
C.blsSignatureAdd(sign.getPointer(), rhs.getPointer())
}
// Recover --
func (sign *Sign) Recover(signVec []Sign, idVec []ID) error {
// #nosec
return G1LagrangeInterpolation(&sign.v, *(*[]Fr)(unsafe.Pointer(&idVec)), *(*[]G1)(unsafe.Pointer(&signVec)))
}
// Verify --
func (sign *Sign) Verify(pub *PublicKey, m string) bool {
buf := []byte(m)
// #nosec
return C.blsVerify(sign.getPointer(), pub.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) == 1
}
// VerifyPop --
func (sign *Sign) VerifyPop(pub *PublicKey) bool {
return C.blsVerifyPop(sign.getPointer(), pub.getPointer()) == 1
}
// DHKeyExchange --
func DHKeyExchange(sec *SecretKey, pub *PublicKey) (out PublicKey) {
C.blsDHKeyExchange(out.getPointer(), sec.getPointer(), pub.getPointer())
return out
}