Merge "ibe: Implementation of the Boneh-Boyen identity-based-encryption scheme."
diff --git a/ibe/.godepcop b/ibe/.godepcop
new file mode 100644
index 0000000..e1e57c2
--- /dev/null
+++ b/ibe/.godepcop
@@ -0,0 +1,3 @@
+<godepcop>
+  <pkg allow="golang.org/x/crypto/bn256"/>
+</godepcop>
diff --git a/ibe/bb1.go b/ibe/bb1.go
new file mode 100644
index 0000000..12ad391
--- /dev/null
+++ b/ibe/bb1.go
@@ -0,0 +1,203 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file defines an implementation of the IBE interfaces using the
+// Boneh-Boyen scheme. The paper defining this algorithm (see comments for
+// SetupBB1) uses multiplicative groups while the bn256 package used in the
+// implementation here defines an additive group. The comments follow the
+// notation in the paper while the code uses the bn256 library. For example,
+// g^i corresponds to G1.ScalarBaseMult(i).
+
+package ibe
+
+import (
+	"crypto/rand"
+	"crypto/sha256"
+	"errors"
+	"fmt"
+	"golang.org/x/crypto/bn256"
+	"math/big"
+)
+
+var errBadCiphertext = errors.New("invalid ciphertext")
+
+const marshaledG1Size = 64
+
+// Setup creates an ibe.Master based on the BB1 scheme described in "Efficient
+// Selective Identity-Based Encryption Without Random Oracles" by Dan Boneh and
+// Xavier Boyen (http://crypto.stanford.edu/~dabo/papers/bbibe.pdf).
+//
+// Specifically, Section 4.3 of the paper is implemented.
+func SetupBB1() (Master, error) {
+	var (
+		m     = &bb1master{params: new(bb1params)}
+		pk    = m.params   // shorthand
+		g0Hat = &(m.g0Hat) // shorthand
+	)
+
+	// Set generators
+	pk.g.ScalarBaseMult(big.NewInt(1))
+	pk.gHat.ScalarBaseMult(big.NewInt(1))
+
+	// Pick a random alpha and set g1 & g1Hat
+	alpha, err := random()
+	if err != nil {
+		return nil, err
+	}
+	pk.g1.ScalarBaseMult(alpha)
+	pk.g1Hat.ScalarBaseMult(alpha)
+
+	// Pick a random delta and set h and hHat
+	delta, err := random()
+	if err != nil {
+		return nil, err
+	}
+	pk.h.ScalarBaseMult(delta)
+	pk.hHat.ScalarBaseMult(delta)
+
+	// Pick a random beta and set g0Hat.
+	beta, err := random()
+	if err != nil {
+		return nil, err
+	}
+	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)
+	return m, nil
+}
+
+type bb1master struct {
+	params *bb1params // Public params
+	g0Hat  bn256.G2   // Master key
+}
+
+func (m *bb1master) Extract(id string) (PrivateKey, error) {
+	r, err := random()
+	if err != nil {
+		return nil, err
+	}
+
+	var (
+		ret = &bb1PrivateKey{params: m.params}
+		// A bunch of shorthands
+		d0    = new(bn256.G2)
+		g1Hat = &(m.params.g1Hat)
+		g0Hat = &(m.g0Hat)
+		hHat  = &(m.params.hHat)
+		i     = id2bignum(id)
+	)
+	// ret.d0 = g0Hat * (g1Hat^i * hHat)^r
+	d0.ScalarMult(g1Hat, i)
+	d0.Add(d0, hHat)
+	d0.ScalarMult(d0, r)
+	ret.d0.Add(d0, g0Hat)
+	ret.d1.ScalarBaseMult(r)
+	return ret, nil
+}
+
+func (m *bb1master) Params() Params { return m.params }
+
+type bb1params struct {
+	g, g1, h          bn256.G1
+	gHat, g1Hat, hHat bn256.G2
+	v                 *bn256.GT
+}
+
+func (e *bb1params) Encrypt(id string, m *Plaintext, C *Ciphertext) error {
+	s, err := random()
+	if err != nil {
+		return err
+	}
+
+	var (
+		vs    bn256.GT
+		tmpG1 bn256.G1
+		// Ciphertext C = (A, B, C1)
+		A  = C[0:len(m)]
+		B  = C[len(m) : len(m)+marshaledG1Size]
+		C1 = C[len(m)+marshaledG1Size:]
+	)
+	vs.ScalarMult(e.v, s)
+	pad := sha256.Sum256(vs.Marshal())
+	// A = m ⊕ H(v^s)
+	for i := range m {
+		A[i] = m[i] ^ pad[i]
+	}
+	// B = g^s
+	if err := marshalG1(B, tmpG1.ScalarBaseMult(s)); err != nil {
+		return err
+	}
+	// C1 = (g1^H(id) h)^s
+	tmpG1.ScalarMult(&e.g1, id2bignum(id))
+	tmpG1.Add(&tmpG1, &e.h)
+	tmpG1.ScalarMult(&tmpG1, s)
+	if err := marshalG1(C1, &tmpG1); err != nil {
+		return err
+	}
+	return nil
+}
+
+type bb1PrivateKey struct {
+	params *bb1params // public parameters
+	d0, d1 bn256.G2
+}
+
+func (k *bb1PrivateKey) Decrypt(C *Ciphertext, m *Plaintext) error {
+	var (
+		A     = C[0:len(m)]
+		B, C1 bn256.G1
+	)
+	if _, ok := B.Unmarshal(C[len(m) : len(m)+marshaledG1Size]); !ok {
+		return errBadCiphertext
+	}
+	if _, ok := C1.Unmarshal(C[len(m)+marshaledG1Size:]); !ok {
+		return errBadCiphertext
+	}
+	// M = A ⊕ H(e(B, d0)/e(C1,d1))
+	var (
+		numerator   = bn256.Pair(&B, &k.d0)
+		denominator = bn256.Pair(&C1, &k.d1)
+		hash        = sha256.Sum256(numerator.Add(numerator, denominator.Neg(denominator)).Marshal())
+	)
+	for i := range m {
+		m[i] = A[i] ^ hash[i]
+	}
+	return nil
+}
+
+// random returns a positive integer in the range [1, bn256.Order)
+// (denoted by Zp in http://crypto.stanford.edu/~dabo/papers/bbibe.pdf).
+//
+// The paper refers to random numbers drawn from Zp*. From a theoretical
+// perspective, the uniform distribution over Zp and Zp* start within a
+// statistical distance of 1/p (where p=bn256.Order is a ~256bit prime).  Thus,
+// drawing uniformly from Zp is no different from Zp*.
+func random() (*big.Int, error) {
+	for {
+		k, err := rand.Int(rand.Reader, bn256.Order)
+		if err != nil {
+			return nil, err
+		}
+		if k.Sign() > 0 {
+			return k, nil
+		}
+	}
+}
+
+func id2bignum(id string) *big.Int {
+	h := sha256.Sum256([]byte(id))
+	k := new(big.Int).SetBytes(h[:])
+	return k.Mod(k, bn256.Order)
+}
+
+// marshalG1 writes the marshaled form of g into dst.
+func marshalG1(dst []byte, g *bn256.G1) error {
+	src := g.Marshal()
+	if len(src) != len(dst) {
+		return fmt.Errorf("bn256.G1.Marshal returned a %d byte slice, expected %d: the BB1 IBE implementation is likely broken", len(src), len(dst))
+	}
+	copy(dst, src)
+	return nil
+}
diff --git a/ibe/bb1_test.go b/ibe/bb1_test.go
new file mode 100644
index 0000000..cbd5854
--- /dev/null
+++ b/ibe/bb1_test.go
@@ -0,0 +1,124 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ibe
+
+import (
+	"bytes"
+	"crypto/rand"
+	"reflect"
+	"testing"
+)
+
+func TestBB1Correctness(t *testing.T) {
+	master, err := SetupBB1()
+	if err != nil {
+		t.Fatal(err)
+	}
+	const (
+		alice = "alice"
+		bob   = "bob"
+	)
+	// Extract
+	aliceSK, err := master.Extract(alice)
+	if err != nil {
+		t.Fatal(err)
+	}
+	aliceSK2, err := master.Extract(alice)
+	if err != nil {
+		t.Fatal(err)
+	} else if reflect.DeepEqual(aliceSK, aliceSK2) {
+		t.Fatal("Two Extract operations yielded the same PrivateKey!")
+	}
+	bobSK, err := master.Extract(bob)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// 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)
+	}
+	if err := master.Params().Encrypt(alice, &m, &C); err != nil {
+		t.Fatal(err)
+	}
+	if err := master.Params().Encrypt(alice, &m, &C2); err != nil {
+		t.Fatal(err)
+	}
+	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 {
+			return nil, err
+		}
+		return &ret, nil
+	}
+	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[:]) {
+		t.Errorf("Got (%v, %v), want (%v, nil)", decrypted, err, m[:])
+	}
+	if decrypted, _ := decrypt(bobSK); bytes.Equal(decrypted[:], m[:]) {
+		t.Errorf("Decrypted message with a different PrivateKey")
+	}
+}
+
+var (
+	bb1        Master
+	bb1SK      PrivateKey
+	benchmarkm Plaintext
+	bb1C       Ciphertext
+)
+
+func init() {
+	var err error
+	if bb1, err = SetupBB1(); err != nil {
+		panic(err)
+	}
+	if bb1SK, err = bb1.Extract("alice"); err != nil {
+		panic(err)
+	}
+	if _, err := rand.Read(benchmarkm[:]); err != nil {
+		panic(err)
+	}
+	if err := bb1.Params().Encrypt("alice", &benchmarkm, &bb1C); err != nil {
+		panic(err)
+	}
+}
+
+func BenchmarkExtractBB1(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		if _, err := bb1.Extract("alice"); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkEncryptBB(b *testing.B) {
+	p := bb1.Params()
+	var C Ciphertext
+	for i := 0; i < b.N; i++ {
+		if err := p.Encrypt("alice", &benchmarkm, &C); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkDecryptBB(b *testing.B) {
+	var m Plaintext
+	for i := 0; i < b.N; i++ {
+		if err := bb1SK.Decrypt(&bb1C, &m); err != nil {
+			b.Fatal(err)
+		}
+	}
+}
diff --git a/ibe/ibe.go b/ibe/ibe.go
new file mode 100644
index 0000000..6045cb1
--- /dev/null
+++ b/ibe/ibe.go
@@ -0,0 +1,60 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ibe implements identity-based encryption.
+//
+// This package defines interfaces for identity-based-encryption (IBE) and
+// provides specific implementations of those interfaces.  The idea was first
+// proposed in 1984 by Adi Shamir in "Identity-Based Cryptosystems And
+// Signature Schemes"
+// (http://discovery.csc.ncsu.edu/Courses/csc774-S08/reading-assignments/shamir84.pdf)
+// and a construction based on the Bilinear Diffie-Hellman problem was
+// described in "Identity-Based Encryption from the Weil Paring" by Dan Boneh
+// and Matthew Franklin (http://crypto.stanford.edu/~dabo/papers/bfibe.pdf).
+//
+// As described in the those papers, an IBE scheme consists of four operations:
+//
+// (1) Setup: Which generates global system parameters and a master key.
+//
+// (2) Extract: Uses the master key and global system parameters to generate
+// the private key corresponding to an arbitrary identity string.
+//
+// (3) Encrypt: Uses the global system parameters to encrypt messages for a
+// particular identity.
+//
+// (4) Decrypt: Uses the private key (and global system parameters) to decrypt
+// messages. To be clear, the private key here is for the identity (sometimes
+// refered to as the "identity key" in literature) and not the master secret.
+//
+// This package defines 3 interfaces: one for Extract, one for Encrypt and one
+// for Decrypt and provides Setup function implementations for different IBE
+// 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
+
+// Master is the interface used to extract private keys for arbitrary identities.
+type Master interface {
+	Extract(id string) (PrivateKey, error)
+	Params() Params
+}
+
+// Params represents the global system parameters that are used to encrypt
+// 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
+}
+
+// PrivateKey is the interface used to decrypt encrypted messages.
+type PrivateKey interface {
+	Decrypt(C *Ciphertext, m *Plaintext) error
+}