From e3cb617c6067123ca61c41a812199c543bc14628 Mon Sep 17 00:00:00 2001 From: Jakub Nowakowski Date: Tue, 19 Jun 2018 14:49:26 +0200 Subject: [PATCH] Splited encoding per object type, added public methods for serialization --- bson/encoding.go | 231 --------------------- bson/encoding_cypher.go | 62 ++++++ bson/encoding_cypher_test.go | 32 +++ bson/encoding_partialdecryptionzkp.go | 133 ++++++++++++ bson/encoding_partialdecryptionzkp_test.go | 68 ++++++ bson/encoding_privatekey.go | 79 +++++++ bson/encoding_privatekey_test.go | 35 ++++ bson/encoding_publickey.go | 64 ++++++ bson/encoding_publickey_test.go | 32 +++ bson/encoding_test.go | 134 ------------ bson/encoding_thresholdpublickey.go | 95 +++++++++ bson/encoding_thresholdpublickey_test.go | 37 ++++ 12 files changed, 637 insertions(+), 365 deletions(-) delete mode 100644 bson/encoding.go create mode 100644 bson/encoding_cypher.go create mode 100644 bson/encoding_cypher_test.go create mode 100644 bson/encoding_partialdecryptionzkp.go create mode 100644 bson/encoding_partialdecryptionzkp_test.go create mode 100644 bson/encoding_privatekey.go create mode 100644 bson/encoding_privatekey_test.go create mode 100644 bson/encoding_publickey.go create mode 100644 bson/encoding_publickey_test.go delete mode 100644 bson/encoding_test.go create mode 100644 bson/encoding_thresholdpublickey.go create mode 100644 bson/encoding_thresholdpublickey_test.go diff --git a/bson/encoding.go b/bson/encoding.go deleted file mode 100644 index 627ce35..0000000 --- a/bson/encoding.go +++ /dev/null @@ -1,231 +0,0 @@ -package bson - -// all the methods relative to the set/get json/bson should be stored -// in this file. - -import ( - "encoding/json" - "errors" - "fmt" - "math/big" - - "github.com/keep-network/paillier" - "gopkg.in/mgo.v2/bson" -) - -type Cypher paillier.Cypher -type ThresholdPublicKey paillier.ThresholdPublicKey -type PublicKey paillier.PublicKey -type PrivateKey paillier.PrivateKey -type PartialDecryptionZKP paillier.PartialDecryptionZKP - -type dbCypher struct { - C string -} - -func (cypher *Cypher) GetBSON() (interface{}, error) { - return &dbCypher{fmt.Sprintf("%x", cypher.C)}, nil -} - -func (cypher *Cypher) SetBSON(raw bson.Raw) error { - c := dbCypher{} - if err := raw.Unmarshal(&c); err != nil { - return err - } - var ok bool - cypher.C, ok = new(big.Int).SetString(c.C, 16) - if !ok { - return errors.New("big int not in hexadecimal format") - } - return nil -} - -type dbThresholdKey struct { - TotalNumberOfDecryptionServers int - Threshold int - V string - Vi []string - N string -} - -func (dbThresholdKey *dbThresholdKey) FromThresholdPublicKey(key *ThresholdPublicKey) { - dbThresholdKey.TotalNumberOfDecryptionServers = key.TotalNumberOfDecryptionServers - dbThresholdKey.Threshold = key.Threshold - dbThresholdKey.V = fmt.Sprintf("%x", key.V) - dbThresholdKey.N = fmt.Sprintf("%x", key.N) - dbThresholdKey.Vi = make([]string, len(key.Vi)) - for i, vi := range key.Vi { - dbThresholdKey.Vi[i] = fmt.Sprintf("%x", vi) - } -} - -func (dbThresholdKey *dbThresholdKey) ToThresholdPublicKey(key *ThresholdPublicKey) error { - key.TotalNumberOfDecryptionServers = dbThresholdKey.TotalNumberOfDecryptionServers - key.Threshold = dbThresholdKey.Threshold - oks := make([]bool, 2) - key.V, oks[0] = new(big.Int).SetString(dbThresholdKey.V, 16) - key.N, oks[1] = new(big.Int).SetString(dbThresholdKey.N, 16) - if !all(oks) { - return errors.New("not hexadecimal") - } - key.Vi = make([]*big.Int, len(dbThresholdKey.Vi)) - var ok bool - for i, vi := range dbThresholdKey.Vi { - key.Vi[i], ok = new(big.Int).SetString(vi, 16) - if !ok { - return errors.New("not hexadecimal") - } - - } - return nil -} - -func (thresholdPublicKey *ThresholdPublicKey) GetBSON() (interface{}, error) { - r := new(dbThresholdKey) - r.FromThresholdPublicKey(thresholdPublicKey) - return r, nil -} - -func (thresholdPublicKey *ThresholdPublicKey) SetBSON(raw bson.Raw) error { - r := new(dbThresholdKey) - if err := raw.Unmarshal(r); err != nil { - return err - } - return r.ToThresholdPublicKey(thresholdPublicKey) -} - -func (publicKey *PublicKey) GetBSON() (interface{}, error) { - m := make(map[string]string) - m["n"] = fmt.Sprintf("%x", publicKey.N) - return m, nil -} - -type dbPrivateKey struct { - N string `bson:",omitempty"` - Lambda string `bson:",omitempty"` - Mu string `bson:",omitempty"` -} - -func (privateKey *PrivateKey) GetBSON() (interface{}, error) { - m := make(map[string]string) - - if privateKey.N != nil { - m["n"] = fmt.Sprintf("%x", privateKey.N) - } - if privateKey.Lambda != nil { - m["lambda"] = fmt.Sprintf("%x", privateKey.Lambda) - } - return m, nil -} - -func (privateKey *PrivateKey) SetBSON(raw bson.Raw) error { - var err error = nil - c := new(dbPrivateKey) - raw.Unmarshal(c) - - if c.N != "" { - privateKey.N, err = fromHex(c.N) - if err != nil { - return err - } - } - - if c.Lambda != "" { - privateKey.Lambda, err = fromHex(c.Lambda) - if err != nil { - return err - } - } - - return err -} - -type dbPartialDecryptionZKP struct { - Z string `json:"z"` - E string `json:"e"` - C string `json:"c"` - V string `json:"v"` - N string `json:"n"` - Vi []string `json:"vi"` - Decryption string `json:"decryption"` - Id int `json:"id"` - TotalNumberOfDecryptionServers int `json:"total_number_of_decryption_servers"` - Threshold int `json:"threshold"` -} - -func (dbPDZKP *dbPartialDecryptionZKP) FromPartialDecryptionZKP(pd *PartialDecryptionZKP) { - dbPDZKP.Id = pd.Id - dbPDZKP.TotalNumberOfDecryptionServers = pd.Key.TotalNumberOfDecryptionServers - dbPDZKP.Threshold = pd.Key.Threshold - dbPDZKP.Z = fmt.Sprintf("%x", pd.Z) - dbPDZKP.E = fmt.Sprintf("%x", pd.E) - dbPDZKP.N = fmt.Sprintf("%x", pd.Key.N) - dbPDZKP.C = fmt.Sprintf("%x", pd.C) - dbPDZKP.V = fmt.Sprintf("%x", pd.Key.V) - dbPDZKP.Decryption = fmt.Sprintf("%x", pd.Decryption) - dbPDZKP.Vi = make([]string, len(pd.Key.Vi)) - for i, vi := range pd.Key.Vi { - dbPDZKP.Vi[i] = fmt.Sprintf("%x", vi) - } -} - -func (dbPDZKP *dbPartialDecryptionZKP) ToPartialDecryptionZKP(pd *PartialDecryptionZKP) error { - pd.Key = new(paillier.ThresholdPublicKey) - - var oks = make([]bool, 6) - - pd.Id = dbPDZKP.Id - pd.Key.TotalNumberOfDecryptionServers = dbPDZKP.TotalNumberOfDecryptionServers - pd.Key.Threshold = dbPDZKP.Threshold - pd.Z, oks[0] = new(big.Int).SetString(dbPDZKP.Z, 16) - pd.E, oks[1] = new(big.Int).SetString(dbPDZKP.E, 16) - pd.C, oks[2] = new(big.Int).SetString(dbPDZKP.C, 16) - pd.Key.V, oks[3] = new(big.Int).SetString(dbPDZKP.V, 16) - pd.Key.N, oks[4] = new(big.Int).SetString(dbPDZKP.N, 16) - pd.Decryption, oks[5] = new(big.Int).SetString(dbPDZKP.Decryption, 16) - - if !all(oks) { - fmt.Println(oks) - fmt.Println(dbPDZKP.E, "|", dbPDZKP.Z, "|", dbPDZKP.C, "|", dbPDZKP.V, "|", dbPDZKP.Decryption) - return errors.New("numbers not in hexadecimal format") - } - - pd.Key.Vi = make([]*big.Int, len(dbPDZKP.Vi)) - var ok bool - for i, vi := range dbPDZKP.Vi { - pd.Key.Vi[i], ok = new(big.Int).SetString(vi, 16) - if !ok { - return errors.New("numbers not in hexadecimal format") - } - } - - return nil -} - -func (pd *PartialDecryptionZKP) MarshalJSON() ([]byte, error) { - db := new(dbPartialDecryptionZKP) - db.FromPartialDecryptionZKP(pd) - return json.Marshal(db) -} - -func (pd *PartialDecryptionZKP) UnmarshalJSON(data []byte) error { - db := new(dbPartialDecryptionZKP) - if err := json.Unmarshal(data, db); err != nil { - return err - } - return db.ToPartialDecryptionZKP(pd) -} - -func (pd *PartialDecryptionZKP) GetBSON() (interface{}, error) { - db := new(dbPartialDecryptionZKP) - db.FromPartialDecryptionZKP(pd) - return db, nil -} - -func (pd *PartialDecryptionZKP) SetBSON(raw bson.Raw) error { - db := new(dbPartialDecryptionZKP) - if err := raw.Unmarshal(db); err != nil { - return err - } - return db.ToPartialDecryptionZKP(pd) -} diff --git a/bson/encoding_cypher.go b/bson/encoding_cypher.go new file mode 100644 index 0000000..7452abe --- /dev/null +++ b/bson/encoding_cypher.go @@ -0,0 +1,62 @@ +// Package bson provides functions for serialization and deserialization between +// paillier objects and BSON +package bson + +import ( + "errors" + "fmt" + "math/big" + + "github.com/keep-network/paillier" + "gopkg.in/mgo.v2/bson" +) + +type Cypher paillier.Cypher + +// Serializes Cypher to BSON +func SerializeCypher(cypher *paillier.Cypher) ([]byte, error) { + return bson.Marshal(toSerializableCypher(cypher)) +} + +// Deserializes BSON to Cypher +func DeserializeCypher(data []byte) (*paillier.Cypher, error) { + serializable := new(Cypher) + if err := bson.Unmarshal(data, serializable); err != nil { + return nil, err + } + + return toOriginalCypher(serializable), nil +} + +// Changes original Cypher to serializable Cypher +func toSerializableCypher(cypher *paillier.Cypher) *Cypher { + serializable := Cypher(*cypher) + return &serializable +} + +// Changes serializable Cypher to original Cypher +func toOriginalCypher(serializable *Cypher) *paillier.Cypher { + original := paillier.Cypher(*serializable) + return &original +} + +type dbCypher struct { + C string +} + +func (cypher *Cypher) GetBSON() (interface{}, error) { + return &dbCypher{fmt.Sprintf("%x", cypher.C)}, nil +} + +func (cypher *Cypher) SetBSON(raw bson.Raw) error { + c := dbCypher{} + if err := raw.Unmarshal(&c); err != nil { + return err + } + var ok bool + cypher.C, ok = new(big.Int).SetString(c.C, 16) + if !ok { + return errors.New("big int not in hexadecimal format") + } + return nil +} diff --git a/bson/encoding_cypher_test.go b/bson/encoding_cypher_test.go new file mode 100644 index 0000000..c6d78eb --- /dev/null +++ b/bson/encoding_cypher_test.go @@ -0,0 +1,32 @@ +package bson + +import ( + "reflect" + "testing" + + "github.com/keep-network/paillier" +) + +func TestCypherBsonSerialization(t *testing.T) { + cypher := &paillier.Cypher{ + C: b(5), + } + + serialized, err := SerializeCypher(cypher) + if err != nil { + t.Fatal(err) + } + + deserialized, err := DeserializeCypher(serialized) + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(cypher, deserialized) { + t.Errorf( + "Unexpected serialization result\nActual: %v\nExpected: %v\n", + deserialized, + cypher, + ) + } +} diff --git a/bson/encoding_partialdecryptionzkp.go b/bson/encoding_partialdecryptionzkp.go new file mode 100644 index 0000000..d592945 --- /dev/null +++ b/bson/encoding_partialdecryptionzkp.go @@ -0,0 +1,133 @@ +// Package bson provides functions for serialization and deserialization between +// paillier objects and BSON +package bson + +import ( + "encoding/json" + "errors" + "fmt" + "math/big" + + "github.com/keep-network/paillier" + "gopkg.in/mgo.v2/bson" +) + +type PartialDecryptionZKP paillier.PartialDecryptionZKP + +// Serializes PartialDecryptionZKP to BSON +func SerializePartialDecryptionZKP(pdzkp *paillier.PartialDecryptionZKP) ([]byte, error) { + return bson.Marshal(toSerializablePartialDecryptionZKP(pdzkp)) +} + +// Deserializes BSON to PartialDecryptionZKP +func DeserializePartialDecryptionZKP(data []byte) (*paillier.PartialDecryptionZKP, error) { + serializable := new(PartialDecryptionZKP) + if err := bson.Unmarshal(data, serializable); err != nil { + return nil, err + } + + return toOriginalPartialDecryptionZKP(serializable), nil +} + +// Serializes PartialDecryptionZKP to JSON +func JsonSerializePartialDecryptionZKP(pdzkp *paillier.PartialDecryptionZKP) ([]byte, error) { + return json.Marshal(toSerializablePartialDecryptionZKP(pdzkp)) +} + +// Deserializes JSON to PartialDecryptionZKP +func JsonDeserializePartialDecryptionZKP(data []byte) (*paillier.PartialDecryptionZKP, error) { + serializable := new(PartialDecryptionZKP) + if err := json.Unmarshal(data, serializable); err != nil { + return nil, err + } + + return toOriginalPartialDecryptionZKP(serializable), nil +} + +// Changes original PartialDecryptionZKP to serializable PartialDecryptionZKP +func toSerializablePartialDecryptionZKP(pdzkp *paillier.PartialDecryptionZKP) *PartialDecryptionZKP { + serializable := PartialDecryptionZKP(*pdzkp) + return &serializable +} + +// Changes serializable PartialDecryptionZKP to original PartialDecryptionZKP +func toOriginalPartialDecryptionZKP(serializable *PartialDecryptionZKP) *paillier.PartialDecryptionZKP { + original := paillier.PartialDecryptionZKP(*serializable) + return &original +} + +type dbPartialDecryptionZKP struct { + Z string `json:"z"` + E string `json:"e"` + C string `json:"c"` + V string `json:"v"` + N string `json:"n"` + Vi []string `json:"vi"` + Decryption string `json:"decryption"` + Id int `json:"id"` + TotalNumberOfDecryptionServers int `json:"total_number_of_decryption_servers"` + Threshold int `json:"threshold"` +} + +func (pdzkp *PartialDecryptionZKP) GetBSON() (interface{}, error) { + db := new(dbPartialDecryptionZKP) + db.fromPartialDecryptionZKP(pdzkp) + return db, nil +} + +func (pdzkp *PartialDecryptionZKP) SetBSON(raw bson.Raw) error { + db := new(dbPartialDecryptionZKP) + if err := raw.Unmarshal(db); err != nil { + return err + } + return db.toPartialDecryptionZKP(pdzkp) +} + +func (dbPDZKP *dbPartialDecryptionZKP) fromPartialDecryptionZKP(pdzkp *PartialDecryptionZKP) { + dbPDZKP.Id = pdzkp.Id + dbPDZKP.TotalNumberOfDecryptionServers = pdzkp.Key.TotalNumberOfDecryptionServers + dbPDZKP.Threshold = pdzkp.Key.Threshold + dbPDZKP.Z = fmt.Sprintf("%x", pdzkp.Z) + dbPDZKP.E = fmt.Sprintf("%x", pdzkp.E) + dbPDZKP.N = fmt.Sprintf("%x", pdzkp.Key.N) + dbPDZKP.C = fmt.Sprintf("%x", pdzkp.C) + dbPDZKP.V = fmt.Sprintf("%x", pdzkp.Key.V) + dbPDZKP.Decryption = fmt.Sprintf("%x", pdzkp.Decryption) + dbPDZKP.Vi = make([]string, len(pdzkp.Key.Vi)) + for i, vi := range pdzkp.Key.Vi { + dbPDZKP.Vi[i] = fmt.Sprintf("%x", vi) + } +} + +func (dbPDZKP *dbPartialDecryptionZKP) toPartialDecryptionZKP(pdzkp *PartialDecryptionZKP) error { + pdzkp.Key = new(paillier.ThresholdPublicKey) + + var oks = make([]bool, 6) + + pdzkp.Id = dbPDZKP.Id + pdzkp.Key.TotalNumberOfDecryptionServers = dbPDZKP.TotalNumberOfDecryptionServers + pdzkp.Key.Threshold = dbPDZKP.Threshold + pdzkp.Z, oks[0] = new(big.Int).SetString(dbPDZKP.Z, 16) + pdzkp.E, oks[1] = new(big.Int).SetString(dbPDZKP.E, 16) + pdzkp.C, oks[2] = new(big.Int).SetString(dbPDZKP.C, 16) + pdzkp.Key.V, oks[3] = new(big.Int).SetString(dbPDZKP.V, 16) + pdzkp.Key.N, oks[4] = new(big.Int).SetString(dbPDZKP.N, 16) + pdzkp.Decryption, oks[5] = new(big.Int).SetString(dbPDZKP.Decryption, 16) + + if !all(oks) { + fmt.Println(oks) + fmt.Println(dbPDZKP.E, "|", dbPDZKP.Z, "|", dbPDZKP.C, "|", dbPDZKP.V, "|", dbPDZKP.Decryption) + return errors.New("numbers not in hexadecimal format") + } + + pdzkp.Key.Vi = make([]*big.Int, len(dbPDZKP.Vi)) + var ok bool + for i, vi := range dbPDZKP.Vi { + pdzkp.Key.Vi[i], ok = new(big.Int).SetString(vi, 16) + if !ok { + return errors.New("numbers not in hexadecimal format") + } + } + + return nil +} diff --git a/bson/encoding_partialdecryptionzkp_test.go b/bson/encoding_partialdecryptionzkp_test.go new file mode 100644 index 0000000..40b0e1e --- /dev/null +++ b/bson/encoding_partialdecryptionzkp_test.go @@ -0,0 +1,68 @@ +package bson + +import ( + "math/big" + "reflect" + "testing" + + "github.com/keep-network/paillier" +) + +var pdzkp = &paillier.PartialDecryptionZKP{ + PartialDecryption: paillier.PartialDecryption{ + Id: 1, + Decryption: b(171), + }, + Key: &paillier.ThresholdPublicKey{ + PublicKey: paillier.PublicKey{ + N: (b(345)), + }, + TotalNumberOfDecryptionServers: 7, + Threshold: 98, + V: b(101), + Vi: []*big.Int{b(77), b(67)}, + }, + E: b(112), + Z: b(88), + C: b(99), +} + +func TestPdzkpBsonSerialization(t *testing.T) { + serialized, err := SerializePartialDecryptionZKP(pdzkp) + if err != nil { + t.Fatal(err) + } + + deserialized, err := DeserializePartialDecryptionZKP(serialized) + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(pdzkp, deserialized) { + t.Errorf( + "Unexpected serialization result\nActual: %v\nExpected: %v\n", + deserialized, + pdzkp, + ) + } +} + +func TestPdzkpJsonSerialization(t *testing.T) { + serialized, err := JsonSerializePartialDecryptionZKP(pdzkp) + if err != nil { + t.Fatal(err) + } + + deserialized, err := JsonDeserializePartialDecryptionZKP(serialized) + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(pdzkp, deserialized) { + t.Errorf( + "Unexpected serialization result\nActual: %v\nExpected: %v\n", + deserialized, + pdzkp, + ) + } +} diff --git a/bson/encoding_privatekey.go b/bson/encoding_privatekey.go new file mode 100644 index 0000000..5e81996 --- /dev/null +++ b/bson/encoding_privatekey.go @@ -0,0 +1,79 @@ +// Package bson provides functions for serialization and deserialization between +// paillier objects and BSON +package bson + +import ( + "fmt" + + "github.com/keep-network/paillier" + "gopkg.in/mgo.v2/bson" +) + +type PrivateKey paillier.PrivateKey + +// Serializes PrivateKey to BSON +func SerializePrivateKey(key *paillier.PrivateKey) ([]byte, error) { + return bson.Marshal(toSerializablePrivateKey(key)) +} + +// Deserializes BSON to PrivateKey +func DeserializePrivateKey(data []byte) (*paillier.PrivateKey, error) { + serializable := new(PrivateKey) + if err := bson.Unmarshal(data, serializable); err != nil { + return nil, err + } + + return toOriginalPrivateKey(serializable), nil +} + +// Changes original PrivateKey to serializable PrivateKey +func toSerializablePrivateKey(key *paillier.PrivateKey) *PrivateKey { + serializable := PrivateKey(*key) + return &serializable +} + +// Changes serializable PrivateKey to original PrivateKey +func toOriginalPrivateKey(serializable *PrivateKey) *paillier.PrivateKey { + original := paillier.PrivateKey(*serializable) + return &original +} + +type dbPrivateKey struct { + N string `bson:",omitempty"` + Lambda string `bson:",omitempty"` + Mu string `bson:",omitempty"` +} + +func (privateKey *PrivateKey) GetBSON() (interface{}, error) { + m := make(map[string]string) + + if privateKey.N != nil { + m["n"] = fmt.Sprintf("%x", privateKey.N) + } + if privateKey.Lambda != nil { + m["lambda"] = fmt.Sprintf("%x", privateKey.Lambda) + } + return m, nil +} + +func (privateKey *PrivateKey) SetBSON(raw bson.Raw) error { + var err error = nil + c := new(dbPrivateKey) + raw.Unmarshal(c) + + if c.N != "" { + privateKey.N, err = fromHex(c.N) + if err != nil { + return err + } + } + + if c.Lambda != "" { + privateKey.Lambda, err = fromHex(c.Lambda) + if err != nil { + return err + } + } + + return err +} diff --git a/bson/encoding_privatekey_test.go b/bson/encoding_privatekey_test.go new file mode 100644 index 0000000..9c777a7 --- /dev/null +++ b/bson/encoding_privatekey_test.go @@ -0,0 +1,35 @@ +package bson + +import ( + "reflect" + "testing" + + "github.com/keep-network/paillier" +) + +func TestSetPrivateKeyBson(t *testing.T) { + key := &paillier.PrivateKey{ + PublicKey: paillier.PublicKey{ + N: (b(345)), + }, + Lambda: b(5), + } + + serialized, err := SerializePrivateKey(key) + if err != nil { + t.Fatal(err) + } + + deserialized, err := DeserializePrivateKey(serialized) + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(key, deserialized) { + t.Errorf( + "Unexpected serialization result\nActual: %v\nExpected: %v\n", + deserialized, + key, + ) + } +} diff --git a/bson/encoding_publickey.go b/bson/encoding_publickey.go new file mode 100644 index 0000000..a44f623 --- /dev/null +++ b/bson/encoding_publickey.go @@ -0,0 +1,64 @@ +// Package bson provides functions for serialization and deserialization between +// paillier objects and BSON +package bson + +import ( + "fmt" + + "github.com/keep-network/paillier" + "gopkg.in/mgo.v2/bson" +) + +type PublicKey paillier.PublicKey + +// Serializes PublicKey to BSON +func SerializePublicKey(publicKey *paillier.PublicKey) ([]byte, error) { + return bson.Marshal(toSerializablePublicKey(publicKey)) +} + +// Deserializes BSON to PublicKey +func DeserializePublicKey(data []byte) (*paillier.PublicKey, error) { + serializable := new(PublicKey) + if err := bson.Unmarshal(data, serializable); err != nil { + return nil, err + } + + return toOriginalPublicKey(serializable), nil +} + +// Changes original PublicKey to serializable PublicKey +func toSerializablePublicKey(publicKey *paillier.PublicKey) *PublicKey { + serializable := PublicKey(*publicKey) + return &serializable +} + +// Changes serializable PublicKey to original PublicKey +func toOriginalPublicKey(serializable *PublicKey) *paillier.PublicKey { + original := paillier.PublicKey(*serializable) + return &original +} + +type dbPublicKey struct { + N string `bson:",omitempty"` +} + +func (publicKey *PublicKey) GetBSON() (interface{}, error) { + m := make(map[string]string) + m["n"] = fmt.Sprintf("%x", publicKey.N) + return m, nil +} + +func (publicKey *PublicKey) SetBSON(raw bson.Raw) error { + var err error = nil + c := new(dbPublicKey) + raw.Unmarshal(c) + + if c.N != "" { + publicKey.N, err = fromHex(c.N) + if err != nil { + return err + } + } + + return err +} diff --git a/bson/encoding_publickey_test.go b/bson/encoding_publickey_test.go new file mode 100644 index 0000000..b777e2b --- /dev/null +++ b/bson/encoding_publickey_test.go @@ -0,0 +1,32 @@ +package bson + +import ( + "reflect" + "testing" + + "github.com/keep-network/paillier" +) + +func TestSetPublicKeyBson(t *testing.T) { + key := &paillier.PublicKey{ + N: (b(345)), + } + + serialized, err := SerializePublicKey(key) + if err != nil { + t.Fatal(err) + } + + deserialized, err := DeserializePublicKey(serialized) + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(key, deserialized) { + t.Errorf( + "Unexpected serialization result\nActual: %v\nExpected: %v\n", + deserialized, + key, + ) + } +} diff --git a/bson/encoding_test.go b/bson/encoding_test.go deleted file mode 100644 index 27ad355..0000000 --- a/bson/encoding_test.go +++ /dev/null @@ -1,134 +0,0 @@ -package bson - -import ( - "crypto/rand" - "encoding/json" - "math/big" - "reflect" - "testing" - - "github.com/keep-network/paillier" - "gopkg.in/mgo.v2/bson" -) - -func AssertBSONIsGood(object, dump interface{}, t *testing.T) { - data, err := bson.Marshal(object) - if err != nil { - t.Error(err) - return - } - if err = bson.Unmarshal(data, dump); err != nil { - t.Error(err) - return - } - if !reflect.DeepEqual(object, dump) { - t.Errorf("Object: %v doesn't equal dump: %v", object, dump) - } -} - -func AssertJSONIsGood(object, dump interface{}, t *testing.T) { - data, err := json.Marshal(object) - if err != nil { - t.Error(err) - return - } - if err = json.Unmarshal(data, dump); err != nil { - t.Error(err) - return - } - if !reflect.DeepEqual(object, dump) { - t.Errorf("Object: %v doesn't equal dump: %v", object, dump) - } -} - -func TestCypherGetBSON(t *testing.T) { - key := paillier.CreatePrivateKey(big.NewInt(101), big.NewInt(113)) - cypherOriginal, err := key.Encrypt(big.NewInt(100), rand.Reader) - - cypher := new(Cypher) - cypher.C = cypherOriginal.C - - data, err := bson.Marshal(cypher) - if err != nil { - t.Error(err) - return - } - cypher2 := new(Cypher) - if err = bson.Unmarshal(data, cypher2); err != nil { - t.Error(err) - return - } - if !reflect.DeepEqual(cypher, cypher2) { - t.Errorf("%v not equal %v", cypher, cypher2) - } -} - -func TestThresholdKeyBSON(t *testing.T) { - key := &ThresholdPublicKey{ - PublicKey: paillier.PublicKey{b(9)}, - TotalNumberOfDecryptionServers: 7, - Threshold: 6, - V: b(3), - Vi: []*big.Int{b(2), b(34)}, - } - AssertBSONIsGood(key, new(ThresholdPublicKey), t) -} - -func TestSetPrivateKeyBson(t *testing.T) { - var key = new(PrivateKey) - var keyOriginal = paillier.CreatePrivateKey(big.NewInt(101), big.NewInt(113)) - - key.PublicKey = keyOriginal.PublicKey - key.Lambda = keyOriginal.Lambda - - dump := new(PrivateKey) - - AssertBSONIsGood(key, dump, t) -} - -func TestGetBSONEmptyKey(t *testing.T) { - key := new(PrivateKey) - m, err := key.GetBSON() - if err != nil { - t.Error(err) - } - if !reflect.DeepEqual(make(map[string]string), m) { - t.Error(m) - } -} - -func TestPartialDecryptionZKPJsonification(t *testing.T) { - pd := new(PartialDecryptionZKP) - pd.Key = new(paillier.ThresholdPublicKey) - pd.Key.Threshold = 98 - pd.Key.TotalNumberOfDecryptionServers = 230 - pd.Id = 1 - pd.Key.Vi = []*big.Int{b(77), b(67)} - pd.Key.N = b(131) - pd.Key.V = b(101) - pd.Decryption = b(171) - pd.E = b(112) - pd.C = b(99) - pd.Key.N = b(345) - pd.Z = b(88) - - AssertJSONIsGood(pd, new(PartialDecryptionZKP), t) -} - -func TestPartialDecryptionZKPBSONification(t *testing.T) { - pd := new(PartialDecryptionZKP) - pd.Key = new(paillier.ThresholdPublicKey) - pd.Key.Threshold = 98 - pd.Key.TotalNumberOfDecryptionServers = 230 - pd.Id = 1 - pd.Key.Vi = []*big.Int{b(77), b(67)} // vi is 67 - pd.Key.N = b(131) - pd.Key.V = b(101) - pd.Decryption = b(171) - pd.E = b(112) - pd.C = b(99) - pd.Key.N = b(345) - pd.Z = b(88) - - AssertBSONIsGood(pd, new(PartialDecryptionZKP), t) -} diff --git a/bson/encoding_thresholdpublickey.go b/bson/encoding_thresholdpublickey.go new file mode 100644 index 0000000..b2317db --- /dev/null +++ b/bson/encoding_thresholdpublickey.go @@ -0,0 +1,95 @@ +// Package bson provides functions for serialization and deserialization between +// paillier objects and BSON +package bson + +import ( + "errors" + "fmt" + "math/big" + + "github.com/keep-network/paillier" + "gopkg.in/mgo.v2/bson" +) + +type ThresholdPublicKey paillier.ThresholdPublicKey + +// Serializes ThresholdPublicKey to BSON +func SerializeThresholdPublicKey(key *paillier.ThresholdPublicKey) ([]byte, error) { + return bson.Marshal(toSerializableThresholdPublicKey(key)) +} + +// Deserializes BSON to ThresholdPublicKey +func DeserializeThresholdPublicKey(data []byte) (*paillier.ThresholdPublicKey, error) { + serializable := new(ThresholdPublicKey) + if err := bson.Unmarshal(data, serializable); err != nil { + return nil, err + } + + return toOriginalThresholdPublicKey(serializable), nil +} + +// Changes original ThresholdPublicKey to serializable ThresholdPublicKey +func toSerializableThresholdPublicKey(key *paillier.ThresholdPublicKey) *ThresholdPublicKey { + serializable := ThresholdPublicKey(*key) + return &serializable +} + +// Changes serializable ThresholdPublicKey to original ThresholdPublicKey +func toOriginalThresholdPublicKey(serializable *ThresholdPublicKey) *paillier.ThresholdPublicKey { + original := paillier.ThresholdPublicKey(*serializable) + return &original +} + +func (thresholdPublicKey *ThresholdPublicKey) GetBSON() (interface{}, error) { + r := new(dbThresholdKey) + r.fromThresholdPublicKey(thresholdPublicKey) + return r, nil +} + +func (thresholdPublicKey *ThresholdPublicKey) SetBSON(raw bson.Raw) error { + r := new(dbThresholdKey) + if err := raw.Unmarshal(r); err != nil { + return err + } + return r.toThresholdPublicKey(thresholdPublicKey) +} + +type dbThresholdKey struct { + TotalNumberOfDecryptionServers int + Threshold int + V string + Vi []string + N string +} + +func (dbThresholdKey *dbThresholdKey) fromThresholdPublicKey(key *ThresholdPublicKey) { + dbThresholdKey.TotalNumberOfDecryptionServers = key.TotalNumberOfDecryptionServers + dbThresholdKey.Threshold = key.Threshold + dbThresholdKey.V = fmt.Sprintf("%x", key.V) + dbThresholdKey.N = fmt.Sprintf("%x", key.N) + dbThresholdKey.Vi = make([]string, len(key.Vi)) + for i, vi := range key.Vi { + dbThresholdKey.Vi[i] = fmt.Sprintf("%x", vi) + } +} + +func (dbThresholdKey *dbThresholdKey) toThresholdPublicKey(key *ThresholdPublicKey) error { + key.TotalNumberOfDecryptionServers = dbThresholdKey.TotalNumberOfDecryptionServers + key.Threshold = dbThresholdKey.Threshold + oks := make([]bool, 2) + key.V, oks[0] = new(big.Int).SetString(dbThresholdKey.V, 16) + key.N, oks[1] = new(big.Int).SetString(dbThresholdKey.N, 16) + if !all(oks) { + return errors.New("not hexadecimal") + } + key.Vi = make([]*big.Int, len(dbThresholdKey.Vi)) + var ok bool + for i, vi := range dbThresholdKey.Vi { + key.Vi[i], ok = new(big.Int).SetString(vi, 16) + if !ok { + return errors.New("not hexadecimal") + } + + } + return nil +} diff --git a/bson/encoding_thresholdpublickey_test.go b/bson/encoding_thresholdpublickey_test.go new file mode 100644 index 0000000..c5fbe74 --- /dev/null +++ b/bson/encoding_thresholdpublickey_test.go @@ -0,0 +1,37 @@ +package bson + +import ( + "math/big" + "reflect" + "testing" + + "github.com/keep-network/paillier" +) + +func TestThresholdKeyBSON(t *testing.T) { + key := &paillier.ThresholdPublicKey{ + PublicKey: paillier.PublicKey{b(9)}, + TotalNumberOfDecryptionServers: 7, + Threshold: 6, + V: b(3), + Vi: []*big.Int{b(2), b(34)}, + } + + serialized, err := SerializeThresholdPublicKey(key) + if err != nil { + t.Fatal(err) + } + + deserialized, err := DeserializeThresholdPublicKey(serialized) + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(key, deserialized) { + t.Errorf( + "Unexpected serialization result\nActual: %v\nExpected: %v\n", + deserialized, + key, + ) + } +}