ibe: Avoid copies of bn256.{G1,G2,GT} objects

While the golang.org/x/crypto/bn256 implementation is amenable
to these object copies, other implementations such as
github.com/asimshankar/bn256 are not.

The motivation for this change was so that we experiment with switching
to the pairing implementation backed by
https://www.cryptojedi.org/crypto/#dclxvi

Without this patch, switching to github.com/asimshankar/bn256 causes
SIGSEGVs as copying the Go-objects might mess up the state in C.

For the curious: This change by itself shows no change in the
benchmarks, but switching to https://www.cryptojedi.org/crypto/#dclxvi
shows a considerable improvement on my amd64 machine:
BenchmarkExtractBB1-6  33ms   1ms (16x speedup)
BenchmarkEncryptBB-6   41ms   5ms (7x speedup)
BenchmarkDecryptBB-6   96ms   5ms (16x speedup)

Change-Id: I3409e2df62980c974f3917ef30e8422bfc4a8b37
diff --git a/ibe/bb1.go b/ibe/bb1.go
index 5e1c8d6..117b6c5 100644
--- a/ibe/bb1.go
+++ b/ibe/bb1.go
@@ -69,9 +69,9 @@
 // to encrypt the data under the symmetric key.
 func SetupBB1() (Master, error) {
 	var (
-		m     = &bb1master{params: new(bb1params)}
-		pk    = m.params   // shorthand
-		g0Hat = &(m.g0Hat) // shorthand
+		m     = &bb1master{params: newbb1params(), g0Hat: new(bn256.G2)}
+		pk    = m.params // shorthand
+		g0Hat = m.g0Hat  // shorthand
 	)
 
 	// Set generators
@@ -102,13 +102,13 @@
 	alphabeta := new(big.Int).Mul(alpha, beta)
 	g0Hat.ScalarBaseMult(alphabeta.Mod(alphabeta, bn256.Order)) // g0Hat = gHat^*(alpha*beta)
 
-	pk.v = bn256.Pair(&pk.g, g0Hat)
+	pk.v = bn256.Pair(pk.g, g0Hat)
 	return m, nil
 }
 
 type bb1master struct {
 	params *bb1params // Public params
-	g0Hat  bn256.G2   // Master key
+	g0Hat  *bn256.G2  // Master key
 }
 
 func (m *bb1master) Extract(id string) (PrivateKey, error) {
@@ -118,12 +118,16 @@
 	}
 
 	var (
-		ret = &bb1PrivateKey{params: m.params}
+		ret = &bb1PrivateKey{
+			params: m.params,
+			d0:     new(bn256.G2),
+			d1:     new(bn256.G2),
+		}
 		// A bunch of shorthands
-		d0    = new(bn256.G2)
-		g1Hat = &(m.params.g1Hat)
-		g0Hat = &(m.g0Hat)
-		hHat  = &(m.params.hHat)
+		d0    = ret.d0
+		g1Hat = m.params.g1Hat
+		g0Hat = m.g0Hat
+		hHat  = m.params.hHat
 		i     = val2bignum(idPrefix, []byte(id))
 	)
 	// ret.d0 = g0Hat * (g1Hat^i * hHat)^r
@@ -138,11 +142,23 @@
 func (m *bb1master) Params() Params { return m.params }
 
 type bb1params struct {
-	g, g1, h          bn256.G1
-	gHat, g1Hat, hHat bn256.G2
+	g, g1, h          *bn256.G1
+	gHat, g1Hat, hHat *bn256.G2
 	v                 *bn256.GT
 }
 
+func newbb1params() *bb1params {
+	return &bb1params{
+		g:     new(bn256.G1),
+		g1:    new(bn256.G1),
+		h:     new(bn256.G1),
+		gHat:  new(bn256.G2),
+		g1Hat: new(bn256.G2),
+		hHat:  new(bn256.G2),
+		v:     new(bn256.GT),
+	}
+}
+
 // Helper method that checks that the ciphertext slice for a given message has
 // the correct size: len(C) = len(m) + CiphertextOverhead()
 func (e *bb1params) checkSizes(m, C []byte) error {
@@ -163,8 +179,8 @@
 	}
 
 	var (
-		vs    bn256.GT
-		tmpG1 bn256.G1
+		vs    = new(bn256.GT)
+		tmpG1 = new(bn256.G1)
 		// Ciphertext C = (A, B, C1) - this method computes the first two components
 		A = C[0:encKeySize]
 		B = C[encKeySize : encKeySize+marshaledG1Size]
@@ -213,7 +229,7 @@
 		s      = computeKemRandomness(&sigma, m) // H_1(sigma, m)
 		symKey = computeDemKey(&sigma)           // H_2(sigma)
 
-		tmpG1 bn256.G1
+		tmpG1 = new(bn256.G1)
 		// Ciphertext C = (kem, dem)
 		kem = C[0:kemSize]
 		dem = C[kemSize:]
@@ -226,10 +242,10 @@
 	C1 := kem[encKeySize+marshaledG1Size:]
 
 	// C1 = (g1^H(id) h)^s
-	tmpG1.ScalarMult(&e.g1, val2bignum(idPrefix, []byte(id)))
-	tmpG1.Add(&tmpG1, &e.h)
-	tmpG1.ScalarMult(&tmpG1, s)
-	if err := marshalG1(C1, &tmpG1); err != nil {
+	tmpG1.ScalarMult(e.g1, val2bignum(idPrefix, []byte(id)))
+	tmpG1.Add(tmpG1, e.h)
+	tmpG1.ScalarMult(tmpG1, s)
+	if err := marshalG1(C1, tmpG1); err != nil {
 		return err
 	}
 
@@ -250,7 +266,7 @@
 
 type bb1PrivateKey struct {
 	params *bb1params // public parameters
-	d0, d1 bn256.G2
+	d0, d1 *bn256.G2
 }
 
 func (k *bb1PrivateKey) Decrypt(C, m []byte) error {
@@ -258,9 +274,10 @@
 		return err
 	}
 	var (
-		A     = C[0:encKeySize]
-		B, C1 bn256.G1
-		D     = C[kemSize:]
+		A  = C[0:encKeySize]
+		B  = new(bn256.G1)
+		C1 = new(bn256.G1)
+		D  = C[kemSize:]
 	)
 	if _, ok := B.Unmarshal(C[encKeySize : encKeySize+marshaledG1Size]); !ok {
 		return errBadCiphertext
@@ -270,8 +287,8 @@
 	}
 	// sigma = A ⊕ H(e(B, d0)/e(C1,d1))
 	var (
-		numerator   = bn256.Pair(&B, &k.d0)
-		denominator = bn256.Pair(&C1, &k.d1)
+		numerator   = bn256.Pair(B, k.d0)
+		denominator = bn256.Pair(C1, k.d1)
 		hash        = hashval(ibePrefix, numerator.Add(numerator, denominator.Neg(denominator)).Marshal())
 	)
 	var sigma [encKeySize]byte
diff --git a/ibe/marshal.go b/ibe/marshal.go
index ca6bae4..77859c7 100644
--- a/ibe/marshal.go
+++ b/ibe/marshal.go
@@ -85,7 +85,7 @@
 		if len(data) != marshaledBB1ParamsSize {
 			return nil, fmt.Errorf("invalid size")
 		}
-		p := &bb1params{v: new(bn256.GT)}
+		p := newbb1params()
 		one := big.NewInt(1)
 		p.g.ScalarBaseMult(one)
 		p.gHat.ScalarBaseMult(one)
@@ -145,7 +145,10 @@
 		if len(data) != marshaledBB1PrivateKeySize {
 			return nil, fmt.Errorf("invalid size")
 		}
-		k := new(bb1PrivateKey)
+		k := &bb1PrivateKey{
+			d0: new(bn256.G2),
+			d1: new(bn256.G2),
+		}
 		if _, ok := k.d0.Unmarshal(advance(marshaledG2Size)); !ok {
 			return nil, fmt.Errorf("failed to unmarshal d0")
 		}