diff --git a/ffi/go/mcl/mcl.go b/ffi/go/mcl/mcl.go index c13d3f9..4134d8f 100644 --- a/ffi/go/mcl/mcl.go +++ b/ffi/go/mcl/mcl.go @@ -53,6 +53,26 @@ func GetOpUnitSize() int { return int(C.mclBn_getOpUnitSize()) } +// GetFrByteSize -- the serialized size of Fr +func GetFrByteSize() int { + return int(C.mclBn_getFrByteSize()) +} + +// GetFpByteSize -- the serialized size of Fp +func GetFpByteSize() int { + return int(C.mclBn_getFpByteSize()) +} + +// GetG1ByteSize -- the serialized size of G1 +func GetG1ByteSize() int { + return GetFpByteSize() +} + +// GetG2ByteSize -- the serialized size of G2 +func GetG2ByteSize() int { + return GetFpByteSize() * 2 +} + // GetCurveOrder -- // return the order of G1 func GetCurveOrder() string { @@ -77,16 +97,30 @@ func GetFieldOrder() string { return string(buf[:n]) } -// SetETHserialization -- -func SetETHserialization(enable bool) { - var v C.int - if enable { - v = 1 +func bool2Cint(b bool) C.int { + if b { + return 1 } else { - v = 0 + return 0 } +} + +// VerifyOrderG1 -- verify order if SetString/Deserialize are called +func VerifyOrderG1(doVerify bool) { // #nosec - C.mclBn_setETHserialization(v) + C.mclBn_verifyOrderG1(bool2Cint(doVerify)) +} + +// VerifyOrderG2 -- verify order if SetString/Deserialize are called +func VerifyOrderG2(doVerify bool) { + // #nosec + C.mclBn_verifyOrderG2(bool2Cint(doVerify)) +} + +// SetETHserialization -- +func SetETHserialization(enable bool) { + // #nosec + C.mclBn_setETHserialization(bool2Cint(enable)) } // Fr -- @@ -562,6 +596,26 @@ func (x *G1) Deserialize(buf []byte) error { return nil } +// DeserializeUncompressed -- x.Deserialize() + y.Deserialize() +func (x *G1) DeserializeUncompressed(buf []byte) error { + // #nosec + var n = C.mclBnFp_deserialize(x.X.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) + if n == 0 { + return fmt.Errorf("err UncompressedDeserialize X %x", buf) + } + buf = buf[n:] + // #nosec + n = C.mclBnFp_deserialize(x.Y.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) + if n == 0 { + return fmt.Errorf("err UncompressedDeserialize Y %x", buf) + } + x.Z.SetInt64(1) + if !x.IsValid() { + return fmt.Errorf("err invalid point") + } + return nil +} + // IsEqual -- func (x *G1) IsEqual(rhs *G1) bool { return C.mclBnG1_isEqual(x.getPointer(), rhs.getPointer()) == 1 @@ -577,6 +631,11 @@ func (x *G1) IsValid() bool { return C.mclBnG1_isValid(x.getPointer()) == 1 } +// IsValidOrder -- +func (x *G1) IsValidOrder() bool { + return C.mclBnG1_isValidOrder(x.getPointer()) == 1 +} + // HashAndMapTo -- func (x *G1) HashAndMapTo(buf []byte) error { // #nosec @@ -600,13 +659,33 @@ func (x *G1) GetString(base int) string { // Serialize -- func (x *G1) Serialize() []byte { - buf := make([]byte, 2048) + buf := make([]byte, GetG1ByteSize()) // #nosec n := C.mclBnG1_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), x.getPointer()) if n == 0 { panic("err mclBnG1_serialize") } - return buf[:n] + return buf +} + +// SerializeUncompressed -- all zero array if x.IsZero() +func (x *G1) SerializeUncompressed() []byte { + buf := make([]byte, GetG1ByteSize()*2) + if x.IsZero() { + return buf + } + var nx G1 + G1Normalize(&nx, x) + // #nosec + var n = C.mclBnFp_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), nx.X.getPointer()) + if n == 0 { + panic("err mclBnFp_serialize X") + } + n = C.mclBnFp_serialize(unsafe.Pointer(&buf[n]), C.size_t(len(buf))-n, nx.Y.getPointer()) + if n == 0 { + panic("err mclBnFp_serialize Y") + } + return buf } // G1Normalize -- @@ -692,6 +771,27 @@ func (x *G2) Deserialize(buf []byte) error { return nil } +// DeserializeUncompressed -- x.Deserialize() + y.Deserialize() +func (x *G2) DeserializeUncompressed(buf []byte) error { + // #nosec + var n = C.mclBnFp2_deserialize(x.X.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) + if n == 0 { + return fmt.Errorf("err UncompressedDeserialize X %x", buf) + } + buf = buf[n:] + // #nosec + n = C.mclBnFp2_deserialize(x.Y.getPointer(), unsafe.Pointer(&buf[0]), C.size_t(len(buf))) + if n == 0 { + return fmt.Errorf("err UncompressedDeserialize Y %x", buf) + } + x.Z.D[0].SetInt64(1) + x.Z.D[1].Clear() + if !x.IsValid() { + return fmt.Errorf("err invalid point") + } + return nil +} + // IsEqual -- func (x *G2) IsEqual(rhs *G2) bool { return C.mclBnG2_isEqual(x.getPointer(), rhs.getPointer()) == 1 @@ -707,6 +807,11 @@ func (x *G2) IsValid() bool { return C.mclBnG2_isValid(x.getPointer()) == 1 } +// IsValidOrder -- +func (x *G2) IsValidOrder() bool { + return C.mclBnG2_isValidOrder(x.getPointer()) == 1 +} + // HashAndMapTo -- func (x *G2) HashAndMapTo(buf []byte) error { // #nosec @@ -739,6 +844,26 @@ func (x *G2) Serialize() []byte { return buf[:n] } +// SerializeUncompressed -- all zero array if x.IsZero() +func (x *G2) SerializeUncompressed() []byte { + buf := make([]byte, GetG2ByteSize()*2) + if x.IsZero() { + return buf + } + var nx G2 + G2Normalize(&nx, x) + // #nosec + var n = C.mclBnFp2_serialize(unsafe.Pointer(&buf[0]), C.size_t(len(buf)), nx.X.getPointer()) + if n == 0 { + panic("err mclBnFp2_serialize X") + } + n = C.mclBnFp2_serialize(unsafe.Pointer(&buf[n]), C.size_t(len(buf))-n, nx.Y.getPointer()) + if n == 0 { + panic("err mclBnFp2_serialize Y") + } + return buf +} + // G2Normalize -- func G2Normalize(out *G2, x *G2) { C.mclBnG2_normalize(out.getPointer(), x.getPointer()) diff --git a/ffi/go/mcl/mcl_test.go b/ffi/go/mcl/mcl_test.go index 7146a79..51b147e 100644 --- a/ffi/go/mcl/mcl_test.go +++ b/ffi/go/mcl/mcl_test.go @@ -195,6 +195,44 @@ func testPairing(t *testing.T) { } } +func testSerialize(t *testing.T) { + var x, xx Fr + var y, yy Fp + var P, PP G1 + var Q, QQ G2 + var e, ee GT + x.SetByCSPRNG() + y.SetByCSPRNG() + P.HashAndMapTo([]byte("abc")) + G1Dbl(&P, &P) + Q.HashAndMapTo([]byte("abc")) + G2Dbl(&Q, &Q) + Pairing(&e, &P, &Q) + if xx.Deserialize(x.Serialize()) != nil || !x.IsEqual(&xx) { + t.Error("Serialize Fr") + } + if yy.Deserialize(y.Serialize()) != nil || !y.IsEqual(&yy) { + t.Error("Serialize Fp") + } + if PP.Deserialize(P.Serialize()) != nil || !P.IsEqual(&PP) { + t.Error("Serialize G1") + } + if QQ.Deserialize(Q.Serialize()) != nil || !Q.IsEqual(&QQ) { + t.Error("Serialize G2") + } + if ee.Deserialize(e.Serialize()) != nil || !e.IsEqual(&ee) { + t.Error("Serialize GT") + } + G1Dbl(&PP, &PP) + if PP.DeserializeUncompressed(P.SerializeUncompressed()) != nil || !P.IsEqual(&PP) { + t.Error("SerializeUncompressed G1") + } + G2Dbl(&QQ, &QQ) + if QQ.DeserializeUncompressed(Q.SerializeUncompressed()) != nil || !Q.IsEqual(&QQ) { + t.Error("SerializeUncompressed G2") + } +} + func testMcl(t *testing.T, c int) { err := Init(c) if err != nil { @@ -206,6 +244,7 @@ func testMcl(t *testing.T, c int) { testVec(t) testGT(t) testBadPointOfG2(t) + testSerialize(t) } func TestMclMain(t *testing.T) {