package bls
/*
#cgo CFLAGS:-I../../include -DBLS_MAX_OP_UNIT_SIZE=6
#cgo bn256 CFLAGS:-UBLS_MAX_OP_UNIT_SIZE -DBLS_MAX_OP_UNIT_SIZE=4
#cgo bn384 CFLAGS:-UBLS_MAX_OP_UNIT_SIZE -DBLS_MAX_OP_UNIT_SIZE=6
#cgo LDFLAGS:-lbls -lbls_if -lmcl -lgmp -lgmpxx -L../lib -L../../lib -L../../../mcl/lib -L../../mcl/lib -lstdc++ -lcrypto
#include "bls_if.h"
*/
import "C"
import "fmt"
import "unsafe"
import "encoding/hex"
// CurveFp254BNb -- 254 bit curve
const CurveFp254BNb = 0
// CurveFp382_1 -- 382 bit curve 1
const CurveFp382_1 = 1
// CurveFp382_2 -- 382 bit curve 2
const CurveFp382_2 = 2
// Init --
// call this function before calling all the other operations
// this function is not thread safe
func Init(curve int) {
C.blsInit(C.int(curve), C.BLS_MAX_OP_UNIT_SIZE)
}
// GetMaxOpUnitSize --
func GetMaxOpUnitSize() int {
return int(C.BLS_MAX_OP_UNIT_SIZE)
}
// GetOpUnitSize --
func GetOpUnitSize() int {
return int(C.blsGetOpUnitSize())
}
// GetCurveOrder --
func GetCurveOrder() string {
buf := make([]byte, 1024)
// #nosec
n := C.blsGetCurveOrder((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)))
if n == 0 {
panic("implementation err. size of buf is small")
}
return string(buf[:n])
}
// GetFieldOrder --
func GetFieldOrder() string {
buf := make([]byte, 1024)
// #nosec
n := C.blsGetFieldOrder((*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)))
if n == 0 {
panic("implementation err. size of buf is small")
}
return string(buf[:n])
}
// ID --
type ID struct {
v [C.BLS_MAX_OP_UNIT_SIZE]C.uint64_t
}
// getPointer --
func (id *ID) getPointer() (p *C.blsId) {
// #nosec
return (*C.blsId)(unsafe.Pointer(&id.v[0]))
}
// GetByte
func (id *ID) GetByte(ioMode int) []byte {
buf := make([]byte, 1024)
// #nosec
n := C.blsIdGetStr(id.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), C.int(ioMode))
if n == 0 {
panic("implementation err. size of buf is small")
}
return buf[:n]
}
// SetByte --
func (id *ID) SetByte(buf []byte, ioMode int) error {
// #nosec
err := C.blsIdSetStr(id.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), C.int(ioMode))
if err > 0 {
return fmt.Errorf("bad byte:%x", buf)
}
return nil
}
// Serialize
func (id *ID) Serialize() []byte {
return id.GetByte(C.BlsIoEcComp)
}
// Deserialize
func (id *ID) Deserialize(b []byte) error {
return id.SetByte(b, C.BlsIoEcComp)
}
// GetHexString
func (id *ID) GetHexString() string {
return string(id.GetByte(16))
}
// GetDecString
func (id *ID) GetDecString() string {
return string(id.GetByte(10))
}
// SetHexString
func (id *ID) SetHexString(s string) error {
return id.SetByte([]byte(s), 16)
}
// SetDecString
func (id *ID) SetDecString(s string) error {
return id.SetByte([]byte(s), 10)
}
// IsSame --
func (id *ID) IsSame(rhs *ID) bool {
return C.blsIdIsSame(id.getPointer(), rhs.getPointer()) == 1
}
// Set --
func (id *ID) Set(v []uint64) {
expect := GetOpUnitSize()
if len(v) != expect {
panic(fmt.Errorf("bad size (%d), expected size %d", len(v), expect))
}
// #nosec
C.blsIdSet(id.getPointer(), (*C.uint64_t)(unsafe.Pointer(&v[0])))
}
// SecretKey --
type SecretKey struct {
v [C.BLS_MAX_OP_UNIT_SIZE]C.uint64_t
}
// getPointer --
func (sec *SecretKey) getPointer() (p *C.blsSecretKey) {
// #nosec
return (*C.blsSecretKey)(unsafe.Pointer(&sec.v[0]))
}
// GetByte
func (sec *SecretKey) GetByte(ioMode int) []byte {
buf := make([]byte, 1024)
// #nosec
n := C.blsSecretKeyGetStr(sec.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), C.int(ioMode))
if n == 0 {
panic("implementation err. size of buf is small")
}
return buf[:n]
}
// SetByte --
func (sec *SecretKey) SetByte(buf []byte, ioMode int) error {
// #nosec
err := C.blsSecretKeySetStr(sec.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), C.int(ioMode))
if err > 0 {
return fmt.Errorf("bad byte:%x", buf)
}
return nil
}
// Serialize
func (sec *SecretKey) Serialize() []byte {
return sec.GetByte(C.BlsIoEcComp)
}
// Deserialize
func (sec *SecretKey) Deserialize(b []byte) error {
return sec.SetByte(b, C.BlsIoEcComp)
}
// GetHexString
func (sec *SecretKey) GetHexString() string {
return string(sec.GetByte(16))
}
// GetDecString
func (sec *SecretKey) GetDecString() string {
return string(sec.GetByte(10))
}
// SetHexString
func (sec *SecretKey) SetHexString(s string) error {
return sec.SetByte([]byte(s), 16)
}
// SetDecString
func (sec *SecretKey) SetDecString(s string) error {
return sec.SetByte([]byte(s), 10)
}
// IsSame --
func (sec *SecretKey) IsSame(rhs *SecretKey) bool {
return C.blsSecretKeyIsSame(sec.getPointer(), rhs.getPointer()) == 1
}
// SetArray --
func (sec *SecretKey) SetArray(v []uint64) {
expect := GetOpUnitSize()
if len(v) != expect {
panic(fmt.Errorf("bad size (%d), expected size %d", len(v), expect))
}
// #nosec
C.blsSecretKeySetArray(sec.getPointer(), (*C.uint64_t)(unsafe.Pointer(&v[0])))
}
// Init --
func (sec *SecretKey) Init() {
C.blsSecretKeyInit(sec.getPointer())
}
// Add --
func (sec *SecretKey) Add(rhs *SecretKey) {
C.blsSecretKeyAdd(sec.getPointer(), rhs.getPointer())
}
// GetMasterSecretKey --
func (sec *SecretKey) GetMasterSecretKey(k int) (msk []SecretKey) {
msk = make([]SecretKey, k)
msk[0] = *sec
for i := 1; i < k; i++ {
msk[i].Init()
}
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) {
C.blsSecretKeySet(sec.getPointer(), msk[0].getPointer(), C.size_t(len(msk)), id.getPointer())
}
// Recover --
func (sec *SecretKey) Recover(secVec []SecretKey, idVec []ID) {
C.blsSecretKeyRecover(sec.getPointer(), secVec[0].getPointer(), idVec[0].getPointer(), C.size_t(len(secVec)))
}
// GetPop --
func (sec *SecretKey) GetPop() (sign *Sign) {
sign = new(Sign)
C.blsSecretKeyGetPop(sec.getPointer(), sign.getPointer())
return sign
}
// PublicKey --
type PublicKey struct {
v [C.BLS_MAX_OP_UNIT_SIZE * 2 * 3]C.uint64_t
}
// getPointer --
func (pub *PublicKey) getPointer() (p *C.blsPublicKey) {
// #nosec
return (*C.blsPublicKey)(unsafe.Pointer(&pub.v[0]))
}
// GetByte
func (pub *PublicKey) GetByte(ioMode int) []byte {
buf := make([]byte, 1024)
// #nopub
n := C.blsPublicKeyGetStr(pub.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), C.int(ioMode))
if n == 0 {
panic("implementation err. size of buf is small")
}
return buf[:n]
}
// SetByte --
func (pub *PublicKey) SetByte(buf []byte, ioMode int) error {
// #nopub
err := C.blsPublicKeySetStr(pub.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), C.int(ioMode))
if err > 0 {
return fmt.Errorf("bad byte:%x", buf)
}
return nil
}
// Serialize
func (pub *PublicKey) Serialize() []byte {
return pub.GetByte(C.BlsIoEcComp)
}
// Deserialize
func (pub *PublicKey) Deserialize(b []byte) error {
return pub.SetByte(b, C.BlsIoEcComp)
}
// GetHexString
func (pub *PublicKey) GetHexString() string {
return fmt.Sprintf("%x", pub.Serialize())
}
// SetStr
func (pub *PublicKey) SetStr(s string) error {
b, err := hex.DecodeString(s)
if err != nil {
return err
}
return pub.Deserialize(b)
}
// IsSame --
func (pub *PublicKey) IsSame(rhs *PublicKey) bool {
return C.blsPublicKeyIsSame(pub.getPointer(), rhs.getPointer()) == 1
}
// Add --
func (pub *PublicKey) Add(rhs *PublicKey) {
C.blsPublicKeyAdd(pub.getPointer(), rhs.getPointer())
}
// Set --
func (pub *PublicKey) Set(mpk []PublicKey, id *ID) {
C.blsPublicKeySet(pub.getPointer(), mpk[0].getPointer(), C.size_t(len(mpk)), id.getPointer())
}
// Recover --
func (pub *PublicKey) Recover(pubVec []PublicKey, idVec []ID) {
C.blsPublicKeyRecover(pub.getPointer(), pubVec[0].getPointer(), idVec[0].getPointer(), C.size_t(len(pubVec)))
}
// Sign --
type Sign struct {
v [C.BLS_MAX_OP_UNIT_SIZE * 3]C.uint64_t
}
// getPointer --
func (sign *Sign) getPointer() (p *C.blsSign) {
// #nosec
return (*C.blsSign)(unsafe.Pointer(&sign.v[0]))
}
// GetByte
func (sign *Sign) GetByte(ioMode int) []byte {
buf := make([]byte, 1024)
// #nosign
n := C.blsSignGetStr(sign.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), C.int(ioMode))
if n == 0 {
panic("implementation err. size of buf is small")
}
return buf[:n]
}
// SetByte --
func (sign *Sign) SetByte(buf []byte, ioMode int) error {
// #nosign
err := C.blsSignSetStr(sign.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)), C.int(ioMode))
if err > 0 {
return fmt.Errorf("bad byte:%x", buf)
}
return nil
}
// Serialize
func (sign *Sign) Serialize() []byte {
return sign.GetByte(C.BlsIoEcComp)
}
// Deserialize
func (sign *Sign) Deserialize(b []byte) error {
return sign.SetByte(b, C.BlsIoEcComp)
}
// GetHexString
func (sign *Sign) GetHexString() string {
return fmt.Sprintf("%x", sign.Serialize())
}
// SetStr
func (sign *Sign) SetStr(s string) error {
b, err := hex.DecodeString(s)
if err != nil {
return err
}
return sign.Deserialize(b)
}
// IsSame --
func (sign *Sign) IsSame(rhs *Sign) bool {
return C.blsSignIsSame(sign.getPointer(), rhs.getPointer()) == 1
}
// GetPublicKey --
func (sec *SecretKey) GetPublicKey() (pub *PublicKey) {
pub = new(PublicKey)
C.blsSecretKeyGetPublicKey(sec.getPointer(), pub.getPointer())
return pub
}
// Sign -- Constant Time version
func (sec *SecretKey) Sign(m string) (sign *Sign) {
sign = new(Sign)
buf := []byte(m)
// #nosec
C.blsSecretKeySign(sec.getPointer(), sign.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf)))
return sign
}
// Add --
func (sign *Sign) Add(rhs *Sign) {
C.blsSignAdd(sign.getPointer(), rhs.getPointer())
}
// Recover --
func (sign *Sign) Recover(signVec []Sign, idVec []ID) {
C.blsSignRecover(sign.getPointer(), signVec[0].getPointer(), idVec[0].getPointer(), C.size_t(len(signVec)))
}
// Verify --
func (sign *Sign) Verify(pub *PublicKey, m string) bool {
buf := []byte(m)
// #nosec
return C.blsSignVerify(sign.getPointer(), pub.getPointer(), (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))) == 1
}
// VerifyPop --
func (sign *Sign) VerifyPop(pub *PublicKey) bool {
return C.blsSignVerifyPop(sign.getPointer(), pub.getPointer()) == 1
}