Skip to content

Commit

Permalink
bindings/go: make it work with upcoming go1.24.
Browse files Browse the repository at this point in the history
In an unexpected turn of events go1.24 reclassified import "C" non-local,
which rendered C.blst_* type aliases defunct. The only working solution
appears to be to wrap them into structs. Since all the C.blst_* types
were opaque, the wrapping shouldn't affect applications. In the sense
that the shell struct won't obstruct anything, because nothing was visible.
  • Loading branch information
dot-asm committed Dec 20, 2024
1 parent bef14ca commit 325fe11
Show file tree
Hide file tree
Showing 9 changed files with 415 additions and 361 deletions.
446 changes: 240 additions & 206 deletions bindings/go/blst.go

Large diffs are not rendered by default.

78 changes: 43 additions & 35 deletions bindings/go/blst.tgo
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,15 @@ const BLST_P1_SERIALIZE_BYTES = BLST_FP_BYTES * 2
const BLST_P2_COMPRESS_BYTES = BLST_FP_BYTES * 2
const BLST_P2_SERIALIZE_BYTES = BLST_FP_BYTES * 4

type Scalar = C.blst_scalar
type Fp = C.blst_fp
type Fp2 = C.blst_fp2
type Scalar struct{ cgo C.blst_scalar }
type Fp struct{ cgo C.blst_fp }
type Fp2 struct{ cgo C.blst_fp2 }
type Fp6 = C.blst_fp6
type Fp12 = C.blst_fp12
type P1 = C.blst_p1
type P2 = C.blst_p2
type P1Affine = C.blst_p1_affine
type P2Affine = C.blst_p2_affine
type Fp12 struct{ cgo C.blst_fp12 }
type P1 struct{ cgo C.blst_p1 }
type P2 struct{ cgo C.blst_p2 }
type P1Affine struct{ cgo C.blst_p1_affine }
type P2Affine struct{ cgo C.blst_p2_affine }
type Message = []byte
type Pairing = []C.blst_pairing
type SecretKey = Scalar
Expand Down Expand Up @@ -219,9 +219,9 @@ func numThreads(maxThreads int) int {
}

var cgo_pairingSizeOf = C.blst_pairing_sizeof()
var cgo_p1Generator = *C.blst_p1_generator()
var cgo_p2Generator = *C.blst_p2_generator()
var cgo_fp12One = *C.blst_fp12_one()
var cgo_p1Generator = P1{*C.blst_p1_generator()}
var cgo_p2Generator = P2{*C.blst_p2_generator()}
var cgo_fp12One = Fp12{*C.blst_fp12_one()}

//
// Secret key
Expand All @@ -240,8 +240,8 @@ func KeyGen(ikm []byte, optional ...[]byte) *SecretKey {
if len(ikm) < 32 {
return nil
}
C.blst_keygen(&sk, (*C.byte)(&ikm[0]), C.size_t(len(ikm)),
ptrOrNil(info), C.size_t(len(info)))
C.blst_keygen(&sk.cgo, (*C.byte)(&ikm[0]), C.size_t(len(ikm)),
ptrOrNil(info), C.size_t(len(info)))
// Postponing secret key zeroing till garbage collection can be too
// late to be effective, but every little bit helps...
runtime.SetFinalizer(&sk, func(sk *SecretKey) { sk.Zeroize() })
Expand All @@ -257,8 +257,8 @@ func KeyGenV3(ikm []byte, optional ...[]byte) *SecretKey {
if len(optional) > 0 {
info = optional[0]
}
C.blst_keygen_v3(&sk, (*C.byte)(&ikm[0]), C.size_t(len(ikm)),
ptrOrNil(info), C.size_t(len(info)))
C.blst_keygen_v3(&sk.cgo, (*C.byte)(&ikm[0]), C.size_t(len(ikm)),
ptrOrNil(info), C.size_t(len(info)))
// Postponing secret key zeroing till garbage collection can be too
// late to be effective, but every little bit helps...
runtime.SetFinalizer(&sk, func(sk *SecretKey) { sk.Zeroize() })
Expand All @@ -274,9 +274,9 @@ func KeyGenV45(ikm []byte, salt []byte, optional ...[]byte) *SecretKey {
if len(optional) > 0 {
info = optional[0]
}
C.blst_keygen_v4_5(&sk, (*C.byte)(&ikm[0]), C.size_t(len(ikm)),
(*C.byte)(&salt[0]), C.size_t(len(salt)),
ptrOrNil(info), C.size_t(len(info)))
C.blst_keygen_v4_5(&sk.cgo, (*C.byte)(&ikm[0]), C.size_t(len(ikm)),
(*C.byte)(&salt[0]), C.size_t(len(salt)),
ptrOrNil(info), C.size_t(len(info)))
// Postponing secret key zeroing till garbage collection can be too
// late to be effective, but every little bit helps...
runtime.SetFinalizer(&sk, func(sk *SecretKey) { sk.Zeroize() })
Expand All @@ -292,9 +292,9 @@ func KeyGenV5(ikm []byte, salt []byte, optional ...[]byte) *SecretKey {
if len(optional) > 0 {
info = optional[0]
}
C.blst_keygen_v5(&sk, (*C.byte)(&ikm[0]), C.size_t(len(ikm)),
(*C.byte)(&salt[0]), C.size_t(len(salt)),
ptrOrNil(info), C.size_t(len(info)))
C.blst_keygen_v5(&sk.cgo, (*C.byte)(&ikm[0]), C.size_t(len(ikm)),
(*C.byte)(&salt[0]), C.size_t(len(salt)),
ptrOrNil(info), C.size_t(len(info)))
// Postponing secret key zeroing till garbage collection can be too
// late to be effective, but every little bit helps...
runtime.SetFinalizer(&sk, func(sk *SecretKey) { sk.Zeroize() })
Expand All @@ -306,7 +306,7 @@ func DeriveMasterEip2333(ikm []byte) *SecretKey {
return nil
}
var sk SecretKey
C.blst_derive_master_eip2333(&sk, (*C.byte)(&ikm[0]), C.size_t(len(ikm)))
C.blst_derive_master_eip2333(&sk.cgo, (*C.byte)(&ikm[0]), C.size_t(len(ikm)))
// Postponing secret key zeroing till garbage collection can be too
// late to be effective, but every little bit helps...
runtime.SetFinalizer(&sk, func(sk *SecretKey) { sk.Zeroize() })
Expand All @@ -315,7 +315,7 @@ func DeriveMasterEip2333(ikm []byte) *SecretKey {

func (master *SecretKey) DeriveChildEip2333(child_index uint32) *SecretKey {
var sk SecretKey
C.blst_derive_child_eip2333(&sk, master, C.uint(child_index))
C.blst_derive_child_eip2333(&sk.cgo, &master.cgo, C.uint(child_index))
// Postponing secret key zeroing till garbage collection can be too
// late to be effective, but every little bit helps...
runtime.SetFinalizer(&sk, func(sk *SecretKey) { sk.Zeroize() })
Expand Down Expand Up @@ -350,30 +350,38 @@ func PairingFinalVerify(ctx Pairing, optional ...*Fp12) bool {
if len(optional) > 0 {
gtsig = optional[0]
}
return bool(C.blst_pairing_finalverify(&ctx[0], gtsig))
return bool(C.blst_pairing_finalverify(&ctx[0], gtsig.asPtr()))
}

func PairingRawAggregate(ctx Pairing, q *P2Affine, p *P1Affine) {
C.blst_pairing_raw_aggregate(&ctx[0], q, p)
C.blst_pairing_raw_aggregate(&ctx[0], &q.cgo, &p.cgo)
}

func PairingAsFp12(ctx Pairing) *Fp12 {
var pt Fp12
C.go_pairing_as_fp12(&pt, &ctx[0])
C.go_pairing_as_fp12(&pt.cgo, &ctx[0])
return &pt
}

func (pt *Fp12) asPtr() *C.blst_fp12 {
if (pt != nil) {
return &pt.cgo
}

return nil
}

func Fp12One() Fp12 {
return cgo_fp12One
}

func Fp12FinalVerify(pt1 *Fp12, pt2 *Fp12) bool {
return bool(C.blst_fp12_finalverify(pt1, pt2))
return bool(C.blst_fp12_finalverify(&pt1.cgo, &pt2.cgo))
}

func Fp12MillerLoop(q *P2Affine, p *P1Affine) *Fp12 {
var pt Fp12
C.blst_miller_loop(&pt, q, p)
C.blst_miller_loop(&pt.cgo, &q.cgo, &p.cgo)
return &pt
}

Expand All @@ -387,7 +395,7 @@ func Fp12MillerLoopN(qs []P2Affine, ps []P1Affine) *Fp12 {

if nThreads == 1 || nElems == 1 {
var pt Fp12
C.go_miller_loop_n(&pt, &qs[0], &ps[0], C.size_t(nElems), false)
C.go_miller_loop_n(&pt.cgo, &qs[0].cgo, &ps[0].cgo, C.size_t(nElems), false)
return &pt
}

Expand Down Expand Up @@ -417,7 +425,7 @@ func Fp12MillerLoopN(qs []P2Affine, ps []P1Affine) *Fp12 {
if n > stride {
n = stride
}
C.go_miller_loop_n(&acc, &qs[work], &ps[work], C.size_t(n),
C.go_miller_loop_n(&acc.cgo, &qs[work].cgo, &ps[work].cgo, C.size_t(n),
C.bool(!first))
first = false
}
Expand All @@ -431,25 +439,25 @@ func Fp12MillerLoopN(qs []P2Affine, ps []P1Affine) *Fp12 {
}

var pt Fp12
C.go_fp12slice_mul(&pt, &ret[0], C.size_t(nThreads))
C.go_fp12slice_mul(&pt.cgo, &ret[0].cgo, C.size_t(nThreads))
return &pt
}

func (pt *Fp12) MulAssign(p *Fp12) {
C.blst_fp12_mul(pt, pt, p)
C.blst_fp12_mul(&pt.cgo, &pt.cgo, &p.cgo)
}

func (pt *Fp12) FinalExp() {
C.blst_final_exp(pt, pt)
C.blst_final_exp(&pt.cgo, &pt.cgo)
}

func (pt *Fp12) InGroup() bool {
return bool(C.blst_fp12_in_group(pt))
return bool(C.blst_fp12_in_group(&pt.cgo))
}

func (pt *Fp12) ToBendian() []byte {
var out [BLST_FP_BYTES*12]byte
C.blst_bendian_from_fp12((*C.byte)(&out[0]), pt)
C.blst_bendian_from_fp12((*C.byte)(&out[0]), &pt.cgo)
return out[:]
}

Expand Down
8 changes: 2 additions & 6 deletions bindings/go/blst_htoc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ func decodeP1(m map[string]interface{}) *P1Affine {
return nil
}
var p1 P1Affine
p1.x.FromBEndian(x)
p1.y.FromBEndian(y)
p1.Deserialize(append(x, y...))
return &p1
}

Expand Down Expand Up @@ -131,10 +130,7 @@ func decodeP2(m map[string]interface{}) *P2Affine {
return nil
}
var p2 P2Affine
p2.x.fp[0].FromBEndian(x0)
p2.x.fp[1].FromBEndian(x1)
p2.y.fp[0].FromBEndian(y0)
p2.y.fp[1].FromBEndian(y1)
p2.Deserialize(append(x1, append(x0, append(y1, y0...)...)...))
return &p2
}

Expand Down
36 changes: 22 additions & 14 deletions bindings/go/blst_minpk.tgo
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,29 @@ import (
// PublicKey
//

func (pt *P1Affine) asPtr() *C.blst_p1_affine {
if (pt != nil) {
return &pt.cgo
}

return nil
}

func (pk *P1Affine) From(s *Scalar) *P1Affine {
C.blst_sk_to_pk2_in_g1(nil, pk, s)
C.blst_sk_to_pk2_in_g1(nil, &pk.cgo, &s.cgo)
return pk
}

func (pk *P1Affine) KeyValidate() bool {
return bool(C.go_p1_affine_validate(pk, true))
return bool(C.go_p1_affine_validate(&pk.cgo, true))
}

// sigInfcheck, check for infinity, is a way to avoid going
// into resource-consuming verification. Passing 'false' is
// always cryptographically safe, but application might want
// to guard against obviously bogus individual[!] signatures.
func (sig *P2Affine) SigValidate(sigInfcheck bool) bool {
return bool(C.go_p2_affine_validate(sig, C.bool(sigInfcheck)))
return bool(C.go_p2_affine_validate(&sig.cgo, C.bool(sigInfcheck)))
}

//
Expand All @@ -43,7 +51,7 @@ func (sig *P2Affine) Sign(sk *SecretKey, msg []byte, dst []byte,
} else {
q = EncodeToG2(msg, dst, augSingle)
}
C.blst_sign_pk2_in_g1(nil, sig, q, sk)
C.blst_sign_pk2_in_g1(nil, &sig.cgo, &q.cgo, &sk.cgo)
return sig
}

Expand Down Expand Up @@ -247,7 +255,7 @@ func coreAggregateVerifyPkInG1(sigFn sigGetterP2, sigGroupcheck bool,
atomic.StoreInt32(&valid, 0)
}
if atomic.LoadInt32(&valid) > 0 {
C.blst_aggregated_in_g2(&gtsig, sig)
C.blst_aggregated_in_g2(&gtsig.cgo, &sig.cgo)
}
mutex.Unlock()

Expand Down Expand Up @@ -295,7 +303,7 @@ func CoreVerifyPkInG1(pk *P1Affine, sig *P2Affine, hash_or_encode bool,
return C.BLST_SUCCESS
}

return int(C.blst_core_verify_pk_in_g1(pk, sig, C.bool(hash_or_encode),
return int(C.blst_core_verify_pk_in_g1(&pk.cgo, &sig.cgo, C.bool(hash_or_encode),
ptrOrNil(msg), C.size_t(len(msg)),
ptrOrNil(dst), C.size_t(len(dst)),
ptrOrNil(aug), C.size_t(len(aug))))
Expand Down Expand Up @@ -489,19 +497,19 @@ func (agg *P2Aggregate) AddAggregate(other *P2Aggregate) {
} else if agg.v == nil {
agg.v = other.v
} else {
C.blst_p2_add_or_double(agg.v, agg.v, other.v)
C.blst_p2_add_or_double(&agg.v.cgo, &agg.v.cgo, &other.v.cgo)
}
}

func (agg *P2Aggregate) Add(elmt *P2Affine, groupcheck bool) bool {
if groupcheck && !bool(C.blst_p2_affine_in_g2(elmt)) {
if groupcheck && !bool(C.blst_p2_affine_in_g2(&elmt.cgo)) {
return false
}
if agg.v == nil {
agg.v = new(P2)
C.blst_p2_from_affine(agg.v, elmt)
C.blst_p2_from_affine(&agg.v.cgo, &elmt.cgo)
} else {
C.blst_p2_add_or_double_affine(agg.v, agg.v, elmt)
C.blst_p2_add_or_double_affine(&agg.v.cgo, &agg.v.cgo, &elmt.cgo)
}
return true
}
Expand Down Expand Up @@ -551,15 +559,15 @@ func (agg *P2Aggregate) coreAggregate(getter aggGetterP2, groupcheck bool,
atomic.StoreInt32(&valid, 0)
break
}
if groupcheck && !bool(C.blst_p2_affine_in_g2(curElmt)) {
if groupcheck && !bool(C.blst_p2_affine_in_g2(&curElmt.cgo)) {
atomic.StoreInt32(&valid, 0)
break
}
if first {
C.blst_p2_from_affine(&agg, curElmt)
C.blst_p2_from_affine(&agg.cgo, &curElmt.cgo)
first = false
} else {
C.blst_p2_add_or_double_affine(&agg, &agg, curElmt)
C.blst_p2_add_or_double_affine(&agg.cgo, &agg.cgo, &curElmt.cgo)
}
// application might have some async work to do
runtime.Gosched()
Expand Down Expand Up @@ -590,7 +598,7 @@ func (agg *P2Aggregate) coreAggregate(getter aggGetterP2, groupcheck bool,
agg.v = msg.agg
first = false
} else {
C.blst_p2_add_or_double(agg.v, agg.v, msg.agg)
C.blst_p2_add_or_double(&agg.v.cgo, &agg.v.cgo, &msg.agg.cgo)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion bindings/go/blst_minpk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestSerdesMinPk(t *testing.T) {
}

// Negative test equals
sk.b[0]++
sk.cgo.b[0]++
if sk.Equals(sk2) {
t.Error("sk2 == sk")
}
Expand Down
2 changes: 1 addition & 1 deletion bindings/go/blst_minsig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func TestSerdesMinSig(t *testing.T) {
}

// Negative test equals
sk.b[0]++
sk.cgo.b[0]++
if sk.Equals(sk2) {
t.Error("sk2 == sk")
}
Expand Down
Loading

0 comments on commit 325fe11

Please sign in to comment.