package crypto import ( "crypto/rand" "encoding/hex" "errors" "fmt" blst "github.com/supranational/blst/bindings/go" ) type PublicKey = blst.P1Affine type Signature = blst.P2Affine type AggregateSignature = blst.P2Aggregate type AggregatePublicKey = blst.P1Aggregate func GenerateKeys() (*blst.SecretKey, *PublicKey) { var ikm [32]byte _, _ = rand.Read(ikm[:]) sk := blst.KeyGen(ikm[:]) pk := new(PublicKey).From(sk) // fmt.Printf("The public key is: 0x%s\n", hex.EncodeToString(pk.Compress())) // fmt.Printf("The private key is: 0x%s\n", hex.EncodeToString(sk.Serialize())) // sk.Print(private) return sk, pk } func ImportKeyFromHex(s string) (*blst.SecretKey, string) { bytesKey, err := hex.DecodeString(s[2:]) if err != nil { panic(err) } sk := new(blst.SecretKey).Deserialize(bytesKey) pk := new(PublicKey).From(sk) // fmt.Printf("The public key is: 0x%s\n", hex.EncodeToString(pk.Compress())) return sk, hex.EncodeToString(pk.Compress()) } func SignMessage(msg string, sk *blst.SecretKey) string { // var dst = []byte("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_") var dst = []byte("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_") sig := new(Signature).Sign(sk, []byte(msg), dst) return hex.EncodeToString(sig.Compress()) } func ValidateSignature(sigTxt string, pk *PublicKey, msg []byte) error { byteSig, err := hex.DecodeString(sigTxt) if err != nil { panic(err) } sig := new(Signature).Uncompress(byteSig) var dst = []byte("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_") if sig.Verify(false, pk, true, msg, dst) { return nil } else { return errors.New("invalid signature found") } } func POC() { var keys []*blst.SecretKey var pubs []*PublicKey var sigs []*Signature for i := 0; i < 20; i++ { var ikm [32]byte _, _ = rand.Read(ikm[:]) sk := blst.KeyGen(ikm[:]) keys = append(keys, sk) pk := new(PublicKey).From(sk) pubs = append(pubs, pk) var dst = []byte("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_") msg := []byte("testing bls signatures") sig := new(Signature).Sign(sk, msg, dst) if !sig.Verify(true, pk, true, msg, dst) { fmt.Println("ERROR: Invalid signature!") } else { sigs = append(sigs, sig) } } aggPk := new(AggregatePublicKey) aggPk.Aggregate(pubs, false) aggSig := new(AggregateSignature) aggSig.Aggregate(sigs, false) fmt.Printf("the pk: 0x%s\n", hex.EncodeToString(aggPk.ToAffine().Compress())) fmt.Printf("the sig: 0x%s\n", hex.EncodeToString(aggSig.ToAffine().Compress())) }