"x/lib": IBE plaintext and ciphtertext must be []byte

The IBE library interface currently has the plaintext
and ciphertext as a pointer to an array of bytes of lengths
32 and 160 respectively. This does not work well for callers
of this library who would commonly have ciphertext bytes in
the form of a byte slice. (Casting from a byte slice to a
byte array incurs a copy.)

Therefore, this CL changes the interface types for plaintext
and ciphertext to []byte. The encrypt and decrypte operations
have runtime checks to ensure that the slices are of the right
size.

MultiPart: 2/5

Change-Id: Icdb7f29db762a78869b29ecc537a9516c861d2d3
diff --git a/ibe/.api b/ibe/.api
index 7bbaf0c..d2dd141 100644
--- a/ibe/.api
+++ b/ibe/.api
@@ -1,14 +1,14 @@
+pkg ibe, const CiphertextSize ideal-int
+pkg ibe, const PlaintextSize ideal-int
 pkg ibe, func MarshalParams(Params) ([]byte, error)
 pkg ibe, func MarshalPrivateKey(PrivateKey) ([]byte, error)
 pkg ibe, func SetupBB1() (Master, error)
 pkg ibe, func UnmarshalParams([]byte) (Params, error)
 pkg ibe, func UnmarshalPrivateKey(Params, []byte) (PrivateKey, error)
-pkg ibe, type Ciphertext [160]byte
 pkg ibe, type Master interface { Extract, Params }
 pkg ibe, type Master interface, Extract(string) (PrivateKey, error)
 pkg ibe, type Master interface, Params() Params
 pkg ibe, type Params interface { Encrypt }
-pkg ibe, type Params interface, Encrypt(string, *Plaintext, *Ciphertext) error
-pkg ibe, type Plaintext [32]byte
+pkg ibe, type Params interface, Encrypt(string, []byte, []byte) error
 pkg ibe, type PrivateKey interface { Decrypt }
-pkg ibe, type PrivateKey interface, Decrypt(*Ciphertext, *Plaintext) error
+pkg ibe, type PrivateKey interface, Decrypt([]byte, []byte) error
diff --git a/ibe/bb1.go b/ibe/bb1.go
index 71e6937..2f1351a 100644
--- a/ibe/bb1.go
+++ b/ibe/bb1.go
@@ -110,7 +110,10 @@
 	v                 *bn256.GT
 }
 
-func (e *bb1params) Encrypt(id string, m *Plaintext, C *Ciphertext) error {
+func (e *bb1params) Encrypt(id string, m, C []byte) error {
+	if err := checkSizes(m, C); err != nil {
+		return err
+	}
 	s, err := random()
 	if err != nil {
 		return err
@@ -149,7 +152,10 @@
 	d0, d1 bn256.G2
 }
 
-func (k *bb1PrivateKey) Decrypt(C *Ciphertext, m *Plaintext) error {
+func (k *bb1PrivateKey) Decrypt(C, m []byte) error {
+	if err := checkSizes(m, C); err != nil {
+		return err
+	}
 	var (
 		A     = C[0:len(m)]
 		B, C1 bn256.G1
@@ -206,3 +212,10 @@
 	copy(dst, src)
 	return nil
 }
+
+func checkSizes(m, C []byte) error {
+	if msize, Csize := len(m), len(C); msize != PlaintextSize || Csize != CiphertextSize {
+		return fmt.Errorf("provided plaintext and ciphertext are of sizes (%d, %d), want (%d, %d)", msize, Csize, PlaintextSize, CiphertextSize)
+	}
+	return nil
+}
diff --git a/ibe/bb1_test.go b/ibe/bb1_test.go
index 8a8f4e8..b6218c0 100644
--- a/ibe/bb1_test.go
+++ b/ibe/bb1_test.go
@@ -37,35 +37,34 @@
 	}
 
 	// Encrypt
-	var (
-		m     Plaintext
-		C, C2 Ciphertext
-	)
-	if n := copy(m[:], []byte("AThirtyTwoBytePieceOfTextThisIs!")); n != len(m) {
-		t.Fatalf("Test string must be %d bytes, not %d", len(m), n)
+	m := []byte("AThirtyTwoBytePieceOfTextThisIs!")
+	C := make([]byte, CiphertextSize)
+	C2 := make([]byte, CiphertextSize)
+	if msize := len(m); msize != PlaintextSize {
+		t.Fatalf("Test string must be %d bytes, not %d", PlaintextSize, msize)
 	}
-	if err := master.Params().Encrypt(alice, &m, &C); err != nil {
+	if err := master.Params().Encrypt(alice, m, C); err != nil {
 		t.Fatal(err)
 	}
-	if err := master.Params().Encrypt(alice, &m, &C2); err != nil {
+	if err := master.Params().Encrypt(alice, m, C2); err != nil {
 		t.Fatal(err)
 	}
-	if bytes.Equal(C[:], C2[:]) {
+	if bytes.Equal(C, C2) {
 		t.Errorf("Repeated encryptions of the identical plaintext should not produce identical ciphertext")
 	}
 
 	// Decrypt
-	decrypt := func(sk PrivateKey) (*Plaintext, error) {
-		var ret Plaintext
-		if err := sk.Decrypt(&C, &ret); err != nil {
+	decrypt := func(sk PrivateKey) ([]byte, error) {
+		ret := make([]byte, PlaintextSize)
+		if err := sk.Decrypt(C, ret); err != nil {
 			return nil, err
 		}
-		return &ret, nil
+		return ret, nil
 	}
-	if decrypted, err := decrypt(aliceSK); err != nil || !bytes.Equal(decrypted[:], m[:]) {
+	if decrypted, err := decrypt(aliceSK); err != nil || !bytes.Equal(decrypted, m) {
 		t.Errorf("Got (%v, %v), want (%v, nil)", decrypted, err, m[:])
 	}
-	if decrypted, err := decrypt(aliceSK2); err != nil || !bytes.Equal(decrypted[:], m[:]) {
+	if decrypted, err := decrypt(aliceSK2); err != nil || !bytes.Equal(decrypted, m) {
 		t.Errorf("Got (%v, %v), want (%v, nil)", decrypted, err, m[:])
 	}
 	if decrypted, _ := decrypt(bobSK); bytes.Equal(decrypted[:], m[:]) {
@@ -74,10 +73,11 @@
 }
 
 var (
-	bb1        Master
-	bb1SK      PrivateKey
-	benchmarkm Plaintext
-	bb1C       Ciphertext
+	bb1   Master
+	bb1SK PrivateKey
+
+	benchmarkm = make([]byte, PlaintextSize)
+	bb1C       = make([]byte, CiphertextSize)
 )
 
 func TestBB1Marshaling(t *testing.T) {
@@ -90,30 +90,31 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	var m Plaintext
-	if n := copy(m[:], []byte("01234567899876543210123456789012")); n != len(m) {
-		t.Fatalf("%v vs. %v", n, len(m))
-	}
-	var C1, C2 Ciphertext
-	var m1, m2 Plaintext
+	m := []byte("01234567899876543210123456789012")
+	var (
+		C1 = make([]byte, CiphertextSize)
+		C2 = make([]byte, CiphertextSize)
+		m1 = make([]byte, PlaintextSize)
+		m2 = make([]byte, PlaintextSize)
+	)
 	// Encrypt with the original params, decrypt with the unmarshaled key.
-	if err := bb1P.Encrypt("alice", &m, &C1); err != nil {
+	if err := bb1P.Encrypt("alice", m, C1); err != nil {
 		t.Error(err)
 	} else if sk, err := UnmarshalPrivateKey(bb1P, skbytes); err != nil {
 		t.Error(err)
-	} else if err := sk.Decrypt(&C1, &m2); err != nil {
+	} else if err := sk.Decrypt(C1, m2); err != nil {
 		t.Error(err)
-	} else if !bytes.Equal(m[:], m2[:]) {
+	} else if !bytes.Equal(m, m2) {
 		t.Errorf("Got %q, want %q", m, m2)
 	}
 	// Encrypt with the unmarshaled params, decrypt with the original key.
 	if p, err := UnmarshalParams(pbytes); err != nil {
 		t.Error(err)
-	} else if err := p.Encrypt("alice", &m, &C2); err != nil {
+	} else if err := p.Encrypt("alice", m, C2); err != nil {
 		t.Error(err)
-	} else if err := bb1SK.Decrypt(&C2, &m1); err != nil {
+	} else if err := bb1SK.Decrypt(C2, m1); err != nil {
 		t.Error(err)
-	} else if !bytes.Equal(m[:], m1[:]) {
+	} else if !bytes.Equal(m, m1) {
 		t.Errorf("Got %q, want %q", m, m1)
 	}
 
@@ -157,7 +158,7 @@
 	if _, err := rand.Read(benchmarkm[:]); err != nil {
 		panic(err)
 	}
-	if err := bb1.Params().Encrypt("alice", &benchmarkm, &bb1C); err != nil {
+	if err := bb1.Params().Encrypt("alice", benchmarkm, bb1C); err != nil {
 		panic(err)
 	}
 }
@@ -172,18 +173,18 @@
 
 func BenchmarkEncryptBB(b *testing.B) {
 	p := bb1.Params()
-	var C Ciphertext
+	C := make([]byte, CiphertextSize)
 	for i := 0; i < b.N; i++ {
-		if err := p.Encrypt("alice", &benchmarkm, &C); err != nil {
+		if err := p.Encrypt("alice", benchmarkm, C); err != nil {
 			b.Fatal(err)
 		}
 	}
 }
 
 func BenchmarkDecryptBB(b *testing.B) {
-	var m Plaintext
+	m := make([]byte, PlaintextSize)
 	for i := 0; i < b.N; i++ {
-		if err := bb1SK.Decrypt(&bb1C, &m); err != nil {
+		if err := bb1SK.Decrypt(bb1C, m); err != nil {
 			b.Fatal(err)
 		}
 	}
diff --git a/ibe/ibe.go b/ibe/ibe.go
index 6045cb1..0d7c60e 100644
--- a/ibe/ibe.go
+++ b/ibe/ibe.go
@@ -32,14 +32,10 @@
 // systems (at the time of this writing, only for the Boneh-Boyen scheme).
 package ibe
 
-// Plaintext represents a plaintext message that can be encrypted.
-//
-// Typical use would be for plaintext to be a key used to encrypt arbitrary
-// messages.
-type Plaintext [32]byte
-
-// Ciphertext represents an encrypted plaintext.
-type Ciphertext [160]byte
+const (
+	PlaintextSize  = 32
+	CiphertextSize = 160
+)
 
 // Master is the interface used to extract private keys for arbitrary identities.
 type Master interface {
@@ -51,10 +47,17 @@
 // messages for a particular identity.
 type Params interface {
 	// Encrypt encrypts m into C for the identity id.
-	Encrypt(id string, m *Plaintext, C *Ciphertext) error
+	//
+	// The slices m and C must of PlaintextSize and CiphertextSize respectively,
+	// and must not overlap.
+	Encrypt(id string, m, C []byte) error
 }
 
 // PrivateKey is the interface used to decrypt encrypted messages.
 type PrivateKey interface {
-	Decrypt(C *Ciphertext, m *Plaintext) error
+	// Decrypt decrypts ciphertext C into m.
+	//
+	// The slices m and C must of PlaintextSize and CiphertextSize respectively,
+	// and must not overlap.
+	Decrypt(C, m []byte) error
 }