"x/lib": Marshal IBE master
This CL adds methods to marshal and unmarshal the private
component of an IBE Master. These methods will be used by
a service that hosts an IBE master object for issuing
IBE private keys.
Change-Id: Iaee881fe24c5b01d6205b2b12be628e81641af88
diff --git a/ibe/.api b/ibe/.api
index 0d242a4..4140a05 100644
--- a/ibe/.api
+++ b/ibe/.api
@@ -1,7 +1,9 @@
+pkg ibe, func MarshalMasterKey(Master) ([]byte, error)
pkg ibe, func MarshalParams(Params) ([]byte, error)
pkg ibe, func MarshalPrivateKey(PrivateKey) ([]byte, error)
pkg ibe, func SetupBB1() (Master, error)
pkg ibe, func SetupBB2() (Master, error)
+pkg ibe, func UnmarshalMasterKey(Params, []byte) (Master, error)
pkg ibe, func UnmarshalParams([]byte) (Params, error)
pkg ibe, func UnmarshalPrivateKey(Params, []byte) (PrivateKey, error)
pkg ibe, type Master interface { Extract, Params }
diff --git a/ibe/bb_test.go b/ibe/bb_test.go
index 6959413..6973497 100644
--- a/ibe/bb_test.go
+++ b/ibe/bb_test.go
@@ -153,6 +153,10 @@
if err != nil {
t.Fatal(err)
}
+ mkbytes, err := MarshalMasterKey(master)
+ if err != nil {
+ t.Fatal(err)
+ }
m := []byte("01234567899876543210123456789012")
overhead := bbParams.CiphertextOverhead()
var (
@@ -161,6 +165,19 @@
m1 = make([]byte, len(m))
m2 = make([]byte, len(m))
)
+ // Encrypt with the original params, decrypt with key extracted from unmarshaled
+ // master key.
+ if err := bbParams.Encrypt("alice", m, C1); err != nil {
+ t.Error(err)
+ } else if mk, err := UnmarshalMasterKey(bbParams, mkbytes); err != nil {
+ t.Error(err)
+ } else if bbSK, err := mk.Extract("alice"); err != nil {
+ t.Error(err)
+ } else if err := bbSK.Decrypt(C1, m2); err != nil {
+ t.Error(err)
+ } else if !bytes.Equal(m, m2) {
+ t.Errorf("Got %q, want %q", m, m2)
+ }
// Encrypt with the original params, decrypt with the unmarshaled key.
if err := bbParams.Encrypt("alice", m, C1); err != nil {
t.Error(err)
@@ -189,6 +206,9 @@
if _, err := UnmarshalPrivateKey(bbParams, skbytes[:len(skbytes)-1]); err == nil {
t.Errorf("UnmarshalPrivateKey succeeded on truncated input")
}
+ if _, err := UnmarshalMasterKey(bbParams, mkbytes[:len(mkbytes)-1]); err == nil {
+ t.Errorf("UnmarshalMasterKey succeeded on truncated input")
+ }
// Extension errors
if _, err := UnmarshalParams(append(pbytes, 0)); err == nil {
t.Errorf("UnmarshalParams succeeded on extended input")
@@ -196,6 +216,9 @@
if _, err := UnmarshalPrivateKey(bbParams, append(skbytes, 0)); err == nil {
t.Errorf("UnmarshalPrivateKey succeeded on extended input")
}
+ if _, err := UnmarshalMasterKey(bbParams, append(mkbytes, 0)); err == nil {
+ t.Errorf("UnmarshalMasterKey succeeded on extended input")
+ }
// Zero length (no valid header either)
if _, err := UnmarshalParams(nil); err == nil {
t.Errorf("UnmarshalParams succeeded on nil input")
@@ -209,6 +232,12 @@
if _, err := UnmarshalPrivateKey(bbParams, []byte{}); err == nil {
t.Errorf("UnmarshalPrivateKey succeeded on zero length input")
}
+ if _, err := UnmarshalMasterKey(bbParams, nil); err == nil {
+ t.Errorf("UnmarshalMasterKey succeeded on nil input")
+ }
+ if _, err := UnmarshalMasterKey(bbParams, []byte{}); err == nil {
+ t.Errorf("UnmarshalMasterKey succeeded on zero length input")
+ }
}
func TestBB1Marshaling(t *testing.T) { testMarshaling(t, SetupBB1) }
diff --git a/ibe/marshal.go b/ibe/marshal.go
index de6dc70..707d731 100644
--- a/ibe/marshal.go
+++ b/ibe/marshal.go
@@ -23,15 +23,19 @@
// types of encoded bytes, 1 byte
typeBB1Params marshaledType = 0
typeBB1PrivateKey = 1
- typeBB2Params = 2
- typeBB2PrivateKey = 3
+ typeBB1MasterKey = 2
+ typeBB2Params = 3
+ typeBB2PrivateKey = 4
+ typeBB2MasterKey = 5
// Sizes excluding the magic number and type header.
headerSize = 3
marshaledBB1ParamsSize = 2*marshaledG1Size + 2*marshaledG2Size + marshaledGTSize
marshaledBB1PrivateKeySize = 2 * marshaledG2Size
+ marshaledBB1MasterKeySize = marshaledG2Size
marshaledBB2ParamsSize = 2*marshaledG1Size + marshaledGTSize
marshaledBB2PrivateKeySize = fieldElemSize + marshaledG2Size
+ marshaledBB2MasterKeySize = 2*fieldElemSize + marshaledG2Size
)
func writeFieldElement(elem *big.Int) []byte {
@@ -174,7 +178,7 @@
}
return ret, nil
default:
- return nil, fmt.Errorf("MarshalPrivateKey for %T for implemented yet", k)
+ return nil, fmt.Errorf("MarshalPrivateKey for %T not implemented yet", k)
}
}
@@ -235,3 +239,87 @@
return nil, fmt.Errorf("unrecognized private key type (%d)", typ)
}
}
+
+// MarshalMasterKey encodes the private component of m into a byte slice.
+func MarshalMasterKey(m Master) ([]byte, error) {
+ switch m := m.(type) {
+ case *bb1master:
+ ret := make([]byte, 0, headerSize+marshaledBB1MasterKeySize)
+ for _, field := range [][]byte{
+ writeHeader(typeBB1MasterKey),
+ m.g0Hat.Marshal(),
+ } {
+ ret = append(ret, field...)
+ }
+ return ret, nil
+ case *bb2master:
+ ret := make([]byte, 0, headerSize+marshaledBB2MasterKeySize)
+ for _, field := range [][]byte{
+ writeHeader(typeBB2MasterKey),
+ writeFieldElement(m.x),
+ writeFieldElement(m.y),
+ m.hHat.Marshal(),
+ } {
+ ret = append(ret, field...)
+ }
+ return ret, nil
+ default:
+ return nil, fmt.Errorf("MarshalMasterKey for %T not implemented yet", m)
+ }
+}
+
+// UnmarshalMasterKey parses an encoded Master object.
+func UnmarshalMasterKey(params Params, data []byte) (Master, error) {
+ var typ marshaledType
+ var err error
+ if typ, data, err = readHeader(data); err != nil {
+ return nil, err
+ }
+ advance := func(n int) []byte {
+ ret := data[0:n]
+ data = data[n:]
+ return ret
+ }
+ switch typ {
+ case typeBB1MasterKey:
+ if len(data) != marshaledBB1MasterKeySize {
+ return nil, fmt.Errorf("invalid size")
+ }
+ m := &bb1master{
+ g0Hat: new(bn256.G2),
+ }
+ if _, ok := m.g0Hat.Unmarshal(advance(marshaledG2Size)); !ok {
+ return nil, fmt.Errorf("failed to unmarshal g0Hat")
+ }
+ p, ok := params.(*bb1params)
+ if !ok {
+ return nil, fmt.Errorf("params type %T incompatible with %T", params, m)
+ }
+ m.params = new(bb1params)
+ *(m.params) = *p
+ return m, nil
+ case typeBB2MasterKey:
+ if len(data) != marshaledBB2MasterKeySize {
+ return nil, fmt.Errorf("invalid size")
+ }
+ m := &bb2master{
+ x: new(big.Int),
+ y: new(big.Int),
+ hHat: new(bn256.G2),
+ }
+ m.x.SetBytes(advance(fieldElemSize))
+ m.y.SetBytes(advance(fieldElemSize))
+ if _, ok := m.hHat.Unmarshal(advance(marshaledG2Size)); !ok {
+ return nil, fmt.Errorf("failed to unmarshal hHat")
+ }
+ p, ok := params.(*bb2params)
+ if !ok {
+ return nil, fmt.Errorf("params type %T incompatible with %T", params, m)
+ }
+ m.params = new(bb2params)
+ *(m.params) = *p
+ return m, nil
+ default:
+ return nil, fmt.Errorf("unrecognized master key type (%d)", typ)
+ }
+}