func (mem *MemberKey) Sign(r io.Reader, digest []byte, hashFunc hash.Hash) ([]byte, error) {
	var rnds [7]*big.Int
	for i := range rnds {
		var err error
		rnds[i], err = randomZp(r)
		if err != nil {
			return nil, err
		}
	}
	alpha := rnds[0]
	beta := rnds[1]
	t1 := new(bn256.G1).ScalarMult(mem.u, alpha)
	t2 := new(bn256.G1).ScalarMult(mem.v, beta)
	tmp := new(big.Int).Add(alpha, beta)
	t3 := new(bn256.G1).ScalarMult(mem.h, tmp)
	t3.Add(t3, mem.a)
	delta1 := new(big.Int).Mul(mem.x, alpha)
	delta1.Mod(delta1, bn256.Order)
	delta2 := new(big.Int).Mul(mem.x, beta)
	delta2.Mod(delta2, bn256.Order)
	ralpha := rnds[2]
	rbeta := rnds[3]
	rx := rnds[4]
	rdelta1 := rnds[5]
	rdelta2 := rnds[6]
	r1 := new(bn256.G1).ScalarMult(mem.u, ralpha)
	r2 := new(bn256.G1).ScalarMult(mem.v, rbeta)
	r3 := bn256.Pair(t3, mem.g2)
	r3.ScalarMult(r3, rx)
	tmp.Neg(ralpha)
	tmp.Sub(tmp, rbeta)
	tmp.Mod(tmp, bn256.Order)
	tmpgt := new(bn256.GT).ScalarMult(mem.ehw, tmp)
	r3.Add(r3, tmpgt)
	tmp.Neg(rdelta1)
	tmp.Sub(tmp, rdelta2)
	tmp.Mod(tmp, bn256.Order)
	tmpgt.ScalarMult(mem.ehg2, tmp)
	r3.Add(r3, tmpgt)
	r4 := new(bn256.G1).ScalarMult(t1, rx)
	tmp.Neg(rdelta1)
	tmp.Add(tmp, bn256.Order)
	tmpg := new(bn256.G1).ScalarMult(mem.u, tmp)
	r4.Add(r4, tmpg)
	r5 := new(bn256.G1).ScalarMult(t2, rx)
	tmp.Neg(rdelta2)
	tmp.Add(tmp, bn256.Order)
	tmpg.ScalarMult(mem.v, tmp)
	r5.Add(r5, tmpg)
	t1Bytes := t1.Marshal()
	t2Bytes := t2.Marshal()
	t3Bytes := t3.Marshal()
	hashFunc.Reset()
	hashFunc.Write(digest)
	hashFunc.Write(t1Bytes)
	hashFunc.Write(t2Bytes)
	hashFunc.Write(t3Bytes)
	hashFunc.Write(r1.Marshal())
	hashFunc.Write(r2.Marshal())
	hashFunc.Write(r3.Marshal())
	hashFunc.Write(r4.Marshal())
	hashFunc.Write(r5.Marshal())
	c := new(big.Int).SetBytes(hashFunc.Sum(nil))
	c.Mod(c, bn256.Order)
	salpha := new(big.Int).Mul(c, alpha)
	salpha.Add(salpha, ralpha)
	salpha.Mod(salpha, bn256.Order)
	sbeta := new(big.Int).Mul(c, beta)
	sbeta.Add(sbeta, rbeta)
	sbeta.Mod(sbeta, bn256.Order)
	sx := new(big.Int).Mul(c, mem.x)
	sx.Add(sx, rx)
	sx.Mod(sx, bn256.Order)
	sdelta1 := new(big.Int).Mul(c, delta1)
	sdelta1.Add(sdelta1, rdelta1)
	sdelta1.Mod(sdelta1, bn256.Order)
	sdelta2 := new(big.Int).Mul(c, delta2)
	sdelta2.Add(sdelta2, rdelta2)
	sdelta2.Mod(sdelta2, bn256.Order)
	sig := make([]byte, 0, SignatureSize)
	sig = append(sig, t1Bytes...)
	sig = append(sig, t2Bytes...)
	sig = append(sig, t3Bytes...)
	sig = appendN(sig, c)
	sig = appendN(sig, salpha)
	sig = appendN(sig, sbeta)
	sig = appendN(sig, sx)
	sig = appendN(sig, sdelta1)
	sig = appendN(sig, sdelta2)
	return sig, nil
}
Sign computes a group signature of digest using the given hash function.
package bbssig
import (
	"crypto/rand"
	"hash"
	"io"
	"math/big"
	"golang.org/x/crypto/bn256"
)
const SignatureSize = 12 * 32
type Group struct {
	g1, h, u, v           *bn256.G1
	g2, w                 *bn256.G2
	ehw, ehg2, minusEg1g2 *bn256.GT
}
func (g *Group) Marshal() []byte {
	out := make([]byte, 0, 4*2*32+2*2*2*32)
	out = append(out, g.g1.Marshal()...)
	out = append(out, g.h.Marshal()...)
	out = append(out, g.u.Marshal()...)
	out = append(out, g.v.Marshal()...)
	out = append(out, g.g2.Marshal()...)
	out = append(out, g.w.Marshal()...)
	return out
}
func (g *Group) Unmarshal(b []byte) (*Group, bool) {
	if len(b) != 4*2*32+2*2*2*32 {
		return nil, false
	}
	var ok bool
	if g.g1, ok = new(bn256.G1).Unmarshal(b[0*2*32 : 1*2*32]); !ok {
		return nil, false
	}
	if g.h, ok = new(bn256.G1).Unmarshal(b[1*2*32 : 2*2*32]); !ok {
		return nil, false
	}
	if g.u, ok = new(bn256.G1).Unmarshal(b[2*2*32 : 3*2*32]); !ok {
		return nil, false
	}
	if g.v, ok = new(bn256.G1).Unmarshal(b[3*2*32 : 4*2*32]); !ok {
		return nil, false
	}
	b = b[4*2*32:]
	if g.g2, ok = new(bn256.G2).Unmarshal(b[0*2*2*32 : 1*2*2*32]); !ok {
		return nil, false
	}
	if g.w, ok = new(bn256.G2).Unmarshal(b[1*2*2*32 : 2*2*2*32]); !ok {
		return nil, false
	}
	g.precompute()
	return g, true
}
func (g *Group) precompute() {
	g.ehw = bn256.Pair(g.h, g.w)
	g.ehg2 = bn256.Pair(g.h, g.g2)
	t := bn256.Pair(g.g1, g.g2)
	g.minusEg1g2 = new(bn256.GT).Neg(t)
}
type PrivateKey struct {
	*Group
	xi1, xi2 *big.Int
	gamma    *big.Int
}
func (priv *PrivateKey) Marshal() []byte {
	out := make([]byte, 0, 3*32)
	out = appendN(out, priv.xi1)
	out = appendN(out, priv.xi2)
	out = appendN(out, priv.gamma)
	return out
}
func (priv *PrivateKey) Unmarshal(g *Group, b []byte) (*PrivateKey, bool) {
	if len(b) != 3*32 {
		return nil, false
	}
	priv.Group = g
	priv.xi1 = new(big.Int).SetBytes(b[0*32 : 1*32])
	priv.xi2 = new(big.Int).SetBytes(b[1*32 : 2*32])
	priv.gamma = new(big.Int).SetBytes(b[2*32 : 3*32])
	return priv, true
}
type MemberKey struct {
	*Group
	x *big.Int
	a *bn256.G1
}
func (mem *MemberKey) Tag() []byte {
	return mem.a.Marshal()
}
func (mem *MemberKey) Marshal() []byte {
	out := make([]byte, 0, 3*32)
	out = appendN(out, mem.x)
	out = append(out, mem.a.Marshal()...)
	return out
}
func (mem *MemberKey) Unmarshal(g *Group, b []byte) (*MemberKey, bool) {
	if len(b) != 3*32 {
		return nil, false
	}
	var ok bool
	mem.Group = g
	mem.x = new(big.Int).SetBytes(b[0*32 : 1*32])
	if mem.a, ok = new(bn256.G1).Unmarshal(b[1*32:]); !ok {
		return nil, false
	}
	return mem, true
}
func randomZp(r io.Reader) (*big.Int, error) {
	for {
		n, err := rand.Int(r, bn256.Order)
		if err != nil {
			return nil, err
		}
		if n.Sign() > 0 {
			return n, nil
		}
	}
	panic("unreachable")
}
func GenerateGroup(r io.Reader) (*PrivateKey, error) {
	priv := new(PrivateKey)
	priv.Group = new(Group)
	var err error
	if _, priv.g1, err = bn256.RandomG1(r); err != nil {
		return nil, err
	}
	if _, priv.g2, err = bn256.RandomG2(r); err != nil {
		return nil, err
	}
	if _, priv.h, err = bn256.RandomG1(r); err != nil {
		return nil, err
	}
	if priv.xi1, err = randomZp(r); err != nil {
		return nil, err
	}
	if priv.xi2, err = randomZp(r); err != nil {
		return nil, err
	}
	z0 := new(big.Int).ModInverse(priv.xi1, bn256.Order)
	priv.u = new(bn256.G1).ScalarMult(priv.h, z0)
	z0.ModInverse(priv.xi2, bn256.Order)
	priv.v = new(bn256.G1).ScalarMult(priv.h, z0)
	priv.gamma, err = randomZp(r)
	if err != nil {
		return nil, err
	}
	priv.w = new(bn256.G2).ScalarMult(priv.g2, priv.gamma)
	priv.precompute()
	return priv, nil
}
func (priv *PrivateKey) NewMember(r io.Reader) (*MemberKey, error) {
	mem := new(MemberKey)
	var err error
	mem.Group = priv.Group
	mem.x, err = randomZp(r)
	if err != nil {
		return nil, err
	}
	s := new(big.Int).Add(priv.gamma, mem.x)
	s.ModInverse(s, bn256.Order)
	mem.a = new(bn256.G1).ScalarMult(priv.g1, s)
	return mem, nil
}