You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@milagro.apache.org by sm...@apache.org on 2019/10/01 08:41:50 UTC

[incubator-milagro-dta] branch develop updated (f8c4f06 -> 6bc9bc4)

This is an automated email from the ASF dual-hosted git repository.

smihaylov pushed a change to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-dta.git.


    from f8c4f06  Add missing Apache headers
     new ef993c8  CreateIdentity as a new package
     new dffff97  KeyStore interface to keep secrets
     new 6bc9bc4  Refactor identity secrets

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 cmd/service/commands.go                            |   1 +
 cmd/service/initnode.go                            |  50 -------
 cmd/service/main.go                                |  51 +++----
 cmd/servicetester/e2e_test.sh                      | 112 ++++++++--------
 go.sum                                             |  14 ++
 libs/documents/crypto.go                           |   2 +-
 libs/documents/docs.go                             |  21 ++-
 libs/documents/docs_test.go                        |  19 ++-
 libs/keystore/filestore.go                         | 111 ++++++++++++++++
 libs/keystore/filestore_test.go                    |  85 ++++++++++++
 .../customvalidators.go => keystore/keystore.go}   |  21 +--
 .../gobcodec.go => keystore/memorystore.go}        |  50 ++++---
 .../keystore/memorystore_test.go                   |  28 +++-
 pkg/bitcoinplugin/helpers.go                       |   2 +-
 pkg/common/common.go                               | 103 +++------------
 pkg/defaultservice/fulfill.go                      |  21 ++-
 pkg/defaultservice/identity.go                     | 146 ---------------------
 pkg/defaultservice/init.go                         |  13 +-
 pkg/defaultservice/order.go                        |  49 ++++---
 pkg/defaultservice/service.go                      |   2 +
 pkg/endpoints/endpoints.go                         | 101 +-------------
 pkg/identity/identity.go                           | 121 +++++++++++++++++
 .../identity/identity_test.go                      |  29 +++-
 pkg/identity/keys.go                               |  63 +++++++++
 pkg/service/service.go                             |   5 -
 25 files changed, 662 insertions(+), 558 deletions(-)
 create mode 100644 libs/keystore/filestore.go
 create mode 100644 libs/keystore/filestore_test.go
 copy libs/{validators/customvalidators.go => keystore/keystore.go} (67%)
 copy libs/{datastore/gobcodec.go => keystore/memorystore.go} (55%)
 copy plugins/safeguardsecret.go => libs/keystore/memorystore_test.go (63%)
 delete mode 100644 pkg/defaultservice/identity.go
 create mode 100644 pkg/identity/identity.go
 copy plugins/safeguardsecret.go => pkg/identity/identity_test.go (59%)
 create mode 100644 pkg/identity/keys.go


[incubator-milagro-dta] 01/03: CreateIdentity as a new package

Posted by sm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

smihaylov pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-dta.git

commit ef993c8e3f195fdf930dbecd0a37183889c04870
Author: Stanislav Mihaylov <sm...@gmail.com>
AuthorDate: Tue Sep 24 13:49:12 2019 +0300

    CreateIdentity as a new package
---
 go.sum                         |  5 +++
 libs/documents/crypto.go       |  2 +-
 libs/documents/docs.go         | 21 ++++-----
 libs/documents/docs_test.go    | 19 ++++----
 pkg/bitcoinplugin/helpers.go   |  2 +-
 pkg/common/common.go           | 41 +++++-------------
 pkg/defaultservice/identity.go | 54 ++---------------------
 pkg/identity/identity.go       | 98 ++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 135 insertions(+), 107 deletions(-)

diff --git a/go.sum b/go.sum
index c31086c..aed6fea 100644
--- a/go.sum
+++ b/go.sum
@@ -56,6 +56,7 @@ github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0=
 github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis=
 github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018 h1:6xT9KW8zLC5IlbaIF5Q7JNieBoACT7iW0YTxQHR0in0=
 github.com/davidlazar/go-crypto v0.0.0-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4=
@@ -85,6 +86,7 @@ github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3yg
 github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM=
 github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw=
 github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
 github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
 github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=
@@ -537,6 +539,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992 h1:bzMe+2coZJYHnhGgVlcQKuRy4FSny4ds8dLQjw5P1XE=
 github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o=
@@ -594,6 +597,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
 github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
@@ -760,6 +764,7 @@ gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
 gotest.tools/gotestsum v0.3.4/go.mod h1:Mnf3e5FUzXbkCfynWBGOwLssY7gTQgCHObK9tMpAriY=
diff --git a/libs/documents/crypto.go b/libs/documents/crypto.go
index f504ec0..cfb7b05 100644
--- a/libs/documents/crypto.go
+++ b/libs/documents/crypto.go
@@ -56,7 +56,7 @@ func decapsulateWithRecipient(recipient Recipient, sikeSK []byte) ([]byte, error
 	return recreatedAesKey, nil
 }
 
-func encapsulateKeyForRecipient(recipientsIDDocs map[string]IDDoc, secret []byte) (recipientList []*Recipient, err error) {
+func encapsulateKeyForRecipient(recipientsIDDocs map[string]*IDDoc, secret []byte) (recipientList []*Recipient, err error) {
 	for id, idDocument := range recipientsIDDocs {
 		r := &Recipient{}
 		iv, err := cryptowallet.RandomBytes(16)
diff --git a/libs/documents/docs.go b/libs/documents/docs.go
index ae36c11..1b190a6 100644
--- a/libs/documents/docs.go
+++ b/libs/documents/docs.go
@@ -46,11 +46,11 @@ type OrderDoc struct {
 }
 
 //NewIDDoc generate a new empty IDDoc
-func NewIDDoc() IDDoc {
-	ret := IDDoc{}
-	ret.Header = &Header{}
-	ret.IDDocument = &IDDocument{}
-	return ret
+func NewIDDoc() *IDDoc {
+	return &IDDoc{
+		&Header{},
+		&IDDocument{},
+	}
 }
 
 //NewOrderDoc generate a new order
@@ -62,17 +62,14 @@ func NewOrderDoc() OrderDoc {
 }
 
 //EncodeIDDocument encode an IDDoc into a raw bytes stream for the wire
-func EncodeIDDocument(idDocument IDDoc, blsSK []byte) ([]byte, error) {
-	header := idDocument.Header
-	plaintext := idDocument.IDDocument
-	rawDoc, err := Encode("", plaintext, nil, header, blsSK, nil)
+func EncodeIDDocument(idDocument *IDDoc, blsSK []byte) ([]byte, error) {
+	rawDoc, err := Encode("", idDocument.IDDocument, nil, idDocument.Header, blsSK, nil)
 	return rawDoc, err
 }
 
 //EncodeOrderDocument encode an OrderDoc into a raw bytes stream for the wire
-func EncodeOrderDocument(nodeID string, orderDoc OrderDoc, blsSK []byte, previousCID string, recipients map[string]IDDoc) ([]byte, error) {
+func EncodeOrderDocument(nodeID string, orderDoc OrderDoc, blsSK []byte, recipients map[string]*IDDoc) ([]byte, error) {
 	header := orderDoc.Header
-	header.PreviousCID = previousCID
 	//	rawDoc, err := Encode(orderDoc.OrderDocument, nil, header, blsSK, nil)
 	rawDoc, err := Encode(nodeID, nil, orderDoc.OrderDocument, header, blsSK, recipients)
 	return rawDoc, err
@@ -169,7 +166,7 @@ func Decode(rawDoc []byte, tag string, sikeSK []byte, recipientID string, plainT
 
 //Encode - convert the header, secret and plaintext into a message for the wire
 //The Header can be pre-populated with any nece
-func Encode(nodeID string, plainText proto.Message, secretText proto.Message, header *Header, blsSK []byte, recipients map[string]IDDoc) (rawDoc []byte, err error) {
+func Encode(nodeID string, plainText proto.Message, secretText proto.Message, header *Header, blsSK []byte, recipients map[string]*IDDoc) (rawDoc []byte, err error) {
 	plainTextDocType, err := detectDocType(plainText)
 	if err != nil {
 		return nil, errors.New("Plaintext Document - Unknown Type")
diff --git a/libs/documents/docs_test.go b/libs/documents/docs_test.go
index 40509e1..513fc7b 100644
--- a/libs/documents/docs_test.go
+++ b/libs/documents/docs_test.go
@@ -40,13 +40,13 @@ func Test_EnvelopeEncryption(t *testing.T) {
 
 	order, _ := BuildTestOrderDoc()
 	order.IPFSID = "NEW IPFS ID"
-	recipients := map[string]IDDoc{
+	recipients := map[string]*IDDoc{
 		id1: s1,
 	}
 	testText := "SEARCH_FOR_THIS123"
 	testTextBytes := []byte(testText)
 	order.Reference = testText
-	raw, _ := EncodeOrderDocument(id1, order, blsSK, "", recipients)
+	raw, _ := EncodeOrderDocument(id1, order, blsSK, recipients)
 	contains := bytes.Contains(raw, testTextBytes)
 	assert.False(t, contains, "Testtext should not be found inside the Envelope - its inside the ciphertext")
 
@@ -64,10 +64,10 @@ func Test_EncodeDecodeOrderDoc(t *testing.T) {
 	s1, id1, _, sikeSK, blsPK, blsSK := BuildTestIDDoc()
 	order, _ := BuildTestOrderDoc()
 	order.IPFSID = "NEW IPFS ID"
-	recipients := map[string]IDDoc{
+	recipients := map[string]*IDDoc{
 		id1: s1,
 	}
-	raw, _ := EncodeOrderDocument(id1, order, blsSK, "PREVIOUSCID", recipients)
+	raw, _ := EncodeOrderDocument(id1, order, blsSK, recipients)
 	reconstitutedOrder := OrderDoc{}
 	_ = DecodeOrderDocument(raw, "NEW IPFS ID", &reconstitutedOrder, sikeSK, id1, blsPK)
 	order.Header.Recipients[0].CipherText = reconstitutedOrder.Header.Recipients[0].CipherText
@@ -87,7 +87,7 @@ func Test_EncodeDecodeID(t *testing.T) {
 	iddoc, tag, _, _, _, blsSK := BuildTestIDDoc()
 	raw, _ := EncodeIDDocument(iddoc, blsSK)
 	reconstitutedIDDoc := NewIDDoc()
-	_ = DecodeIDDocument(raw, tag, &reconstitutedIDDoc)
+	_ = DecodeIDDocument(raw, tag, reconstitutedIDDoc)
 	differences := deep.Equal(reconstitutedIDDoc, iddoc)
 	var failed = false
 	for _, diff := range differences {
@@ -112,7 +112,7 @@ func Test_AESPadding(t *testing.T) {
 func Test_EncodeDecode(t *testing.T) {
 	//These are some DocID for local user
 	s1, id1, _, sikeSK1, _, _ := BuildTestIDDoc()
-	recipients := map[string]IDDoc{
+	recipients := map[string]*IDDoc{
 		id1: s1,
 	}
 	seed, _ := cryptowallet.RandomBytes(16)
@@ -121,8 +121,6 @@ func Test_EncodeDecode(t *testing.T) {
 	secretBody := &SimpleString{Content: "B"}
 	plainText := &SimpleString{Content: "A"}
 	header := &Header{}
-	previousIDCode := "previous_id_code"
-	header.PreviousCID = previousIDCode
 	rawDoc, err := Encode(id1, plainText, secretBody, header, blsSK, recipients)
 	assert.Nil(t, err, "Failed to Encode")
 
@@ -142,7 +140,6 @@ func Test_EncodeDecode(t *testing.T) {
 	assert.Equal(t, plainText.Content, reconPlainText.Content, "Verify fails")
 	assert.Equal(t, secretBody.Content, reconSecretBody.Content, "Verify fails")
 	assert.NotNil(t, reconHeader.DateTime, "Header not populated")
-	assert.Equal(t, header.PreviousCID, previousIDCode, "Verify fails")
 	assert.Equal(t, reconHeader.IPFSID, tag, "tag not loaded into header")
 }
 
@@ -181,7 +178,7 @@ func BuildTestOrderDoc() (OrderDoc, error) {
 	return order, nil
 }
 
-func BuildTestIDDoc() (IDDoc, string, []byte, []byte, []byte, []byte) {
+func BuildTestIDDoc() (*IDDoc, string, []byte, []byte, []byte, []byte) {
 	//make some test ID docs
 	seed, _ := cryptowallet.RandomBytes(16)
 
@@ -206,7 +203,7 @@ func BuildTestIDDoc() (IDDoc, string, []byte, []byte, []byte, []byte) {
 	iddoc := &IDDoc{}
 	rawDocI, _ := proto.Marshal(&signedEnvelope)
 	_ = DecodeIDDocument(rawDocI, ipfsID, iddoc)
-	return *iddoc, ipfsID, sikePK, sikeSK, blsPK, blsSK
+	return iddoc, ipfsID, sikePK, sikeSK, blsPK, blsSK
 }
 
 //createIDForSignedEnvelope - create a hash for the document to be used as an ID
diff --git a/pkg/bitcoinplugin/helpers.go b/pkg/bitcoinplugin/helpers.go
index eb65167..3a7880c 100644
--- a/pkg/bitcoinplugin/helpers.go
+++ b/pkg/bitcoinplugin/helpers.go
@@ -99,7 +99,7 @@ func adhocEncryptedEnvelopeEncode(s *Service, nodeID string, beneficiaryIDDocume
 	}
 	secretBody := &documents.SimpleString{Content: privateKeyPart1of2}
 	header := &documents.Header{}
-	recipients := map[string]documents.IDDoc{
+	recipients := map[string]*documents.IDDoc{
 		beneficiaryIDDocumentCID: beneficiaryIDDocument,
 	}
 	docEnv, err := documents.Encode(nodeID, nil, secretBody, header, blsSK, recipients)
diff --git a/pkg/common/common.go b/pkg/common/common.go
index b8b6b0c..6fefee7 100644
--- a/pkg/common/common.go
+++ b/pkg/common/common.go
@@ -22,9 +22,7 @@ package common
 
 import (
 	"encoding/hex"
-	"fmt"
 	"io"
-	"sync"
 	"time"
 
 	"github.com/apache/incubator-milagro-dta/libs/cryptowallet"
@@ -35,8 +33,6 @@ import (
 	"github.com/pkg/errors"
 )
 
-var previousIDMutex = &sync.Mutex{}
-
 //IdentitySecrets - keys required for decryption and signing
 type IdentitySecrets struct {
 	Name          string `json:"Name"`
@@ -74,14 +70,14 @@ func RetrieveOrderFromIPFS(ipfs ipfs.Connector, ipfsID string, sikeSK []byte, re
 }
 
 // RetrieveIDDocFromIPFS finds and parses the IDDocument
-func RetrieveIDDocFromIPFS(ipfs ipfs.Connector, ipfsID string) (documents.IDDoc, error) {
+func RetrieveIDDocFromIPFS(ipfs ipfs.Connector, ipfsID string) (*documents.IDDoc, error) {
 	iddoc := &documents.IDDoc{}
 	rawDocI, err := ipfs.Get(ipfsID)
 	if err != nil {
-		return documents.IDDoc{}, err
+		return nil, err
 	}
 	err = documents.DecodeIDDocument(rawDocI, ipfsID, iddoc)
-	return *iddoc, err
+	return iddoc, err
 }
 
 // MakeRandomSeedAndStore genefates and stores a random seed
@@ -112,7 +108,7 @@ func RetrieveSeed(store *datastore.Store, reference string) (seedHex string, err
 }
 
 // CreateAndStoreOrderPart2 -
-func CreateAndStoreOrderPart2(ipfs ipfs.Connector, store *datastore.Store, order *documents.OrderDoc, orderPart1CID, commitmentPublicKey, nodeID string, recipients map[string]documents.IDDoc) (orderPart2CID string, err error) {
+func CreateAndStoreOrderPart2(ipfs ipfs.Connector, store *datastore.Store, order *documents.OrderDoc, orderPart1CID, commitmentPublicKey, nodeID string, recipients map[string]*documents.IDDoc) (orderPart2CID string, err error) {
 	Part2 := documents.OrderPart2{
 		CommitmentPublicKey: commitmentPublicKey,
 		PreviousOrderCID:    orderPart1CID,
@@ -128,7 +124,7 @@ func CreateAndStoreOrderPart2(ipfs ipfs.Connector, store *datastore.Store, order
 }
 
 // CreateAndStorePart3 adds part 3 "redemption request" to the order doc
-func CreateAndStorePart3(ipfs ipfs.Connector, store *datastore.Store, order *documents.OrderDoc, orderPart2CID, nodeID string, beneficiaryEncryptedData []byte, recipients map[string]documents.IDDoc) (orderPart3CID string, err error) {
+func CreateAndStorePart3(ipfs ipfs.Connector, store *datastore.Store, order *documents.OrderDoc, orderPart2CID, nodeID string, beneficiaryEncryptedData []byte, recipients map[string]*documents.IDDoc) (orderPart3CID string, err error) {
 	//Add part 3 "redemption request" to the order doc
 	redemptionRequest := documents.OrderPart3{
 		//TODO
@@ -147,7 +143,7 @@ func CreateAndStorePart3(ipfs ipfs.Connector, store *datastore.Store, order *doc
 }
 
 // CreateAndStoreOrderPart4 -
-func CreateAndStoreOrderPart4(ipfs ipfs.Connector, store *datastore.Store, order *documents.OrderDoc, commitmentPrivateKey, orderPart3CID, nodeID string, recipients map[string]documents.IDDoc) (orderPart4CID string, err error) {
+func CreateAndStoreOrderPart4(ipfs ipfs.Connector, store *datastore.Store, order *documents.OrderDoc, commitmentPrivateKey, orderPart3CID, nodeID string, recipients map[string]*documents.IDDoc) (orderPart4CID string, err error) {
 	Part4 := documents.OrderPart4{
 		Secret:           commitmentPrivateKey,
 		PreviousOrderCID: orderPart3CID,
@@ -163,7 +159,7 @@ func CreateAndStoreOrderPart4(ipfs ipfs.Connector, store *datastore.Store, order
 }
 
 // WriteOrderToIPFS writes the order document to IPFS network
-func WriteOrderToIPFS(nodeID string, ipfs ipfs.Connector, store *datastore.Store, id string, order *documents.OrderDoc, recipients map[string]documents.IDDoc) (ipfsAddress string, err error) { // Get the secret keys
+func WriteOrderToIPFS(nodeID string, ipfs ipfs.Connector, store *datastore.Store, id string, order *documents.OrderDoc, recipients map[string]*documents.IDDoc) (ipfsAddress string, err error) { // Get the secret keys
 	secrets := &IdentitySecrets{}
 	if err := store.Get("id-doc", nodeID, secrets); err != nil {
 		return "", errors.New("load secrets from store")
@@ -173,18 +169,7 @@ func WriteOrderToIPFS(nodeID string, ipfs ipfs.Connector, store *datastore.Store
 		return "", errors.Wrap(err, "Decode identity secrets")
 	}
 
-	////Mutex Lock - only one thread at once can write to IPFS as we need to keep track of the previous ID and put it into the next doc to create a chain
-	previousIDMutex.Lock()
-	previousIDKey := fmt.Sprintf("previous-id-%s", nodeID)
-	var previousID string
-	if err := store.Get("id-doc", previousIDKey, &previousID); err != nil {
-		previousID = "genesis"
-		if err := store.Set("id-doc", previousIDKey, previousID, nil); err != nil {
-			return "", err
-		}
-	}
-
-	rawDoc, err := documents.EncodeOrderDocument(nodeID, *order, blsSecretKey, previousID, recipients)
+	rawDoc, err := documents.EncodeOrderDocument(nodeID, *order, blsSecretKey, recipients)
 	if err != nil {
 		return "", errors.Wrap(err, "Failed to encode IDDocument")
 	}
@@ -192,13 +177,7 @@ func WriteOrderToIPFS(nodeID string, ipfs ipfs.Connector, store *datastore.Store
 	if err != nil {
 		return "", errors.Wrap(err, "Failed to Save Raw Document into IPFS")
 	}
-	if err := store.Set("id-doc", previousIDKey, ipfsAddress, nil); err != nil {
-		return "", err
-	}
-	previousIDMutex.Unlock()
 
-	//Write order to store
-	//orderRef := fmt.Sprintf("order-ref-%s", order.Reference)
 	if err := store.Set("order", order.Reference, ipfsAddress, map[string]string{"time": time.Now().UTC().Format(time.RFC3339)}); err != nil {
 		return "", errors.New("Save Order to store")
 	}
@@ -241,7 +220,7 @@ func RetrieveIdentitySecrets(store *datastore.Store, nodeID string) (name string
 }
 
 // BuildRecipientList builds a list of recipients who are able to decrypt the encrypted envelope
-func BuildRecipientList(ipfs ipfs.Connector, localNodeDocCID, remoteNodeDocCID string) (map[string]documents.IDDoc, error) {
+func BuildRecipientList(ipfs ipfs.Connector, localNodeDocCID, remoteNodeDocCID string) (map[string]*documents.IDDoc, error) {
 	remoteNodeDoc, err := RetrieveIDDocFromIPFS(ipfs, remoteNodeDocCID)
 	if err != nil {
 		return nil, err
@@ -252,7 +231,7 @@ func BuildRecipientList(ipfs ipfs.Connector, localNodeDocCID, remoteNodeDocCID s
 		return nil, err
 	}
 
-	recipients := map[string]documents.IDDoc{
+	recipients := map[string]*documents.IDDoc{
 		remoteNodeDocCID: remoteNodeDoc,
 		localNodeDocCID:  localNodeDoc,
 	}
diff --git a/pkg/defaultservice/identity.go b/pkg/defaultservice/identity.go
index d58aee8..ae256e5 100644
--- a/pkg/defaultservice/identity.go
+++ b/pkg/defaultservice/identity.go
@@ -19,67 +19,19 @@ package defaultservice
 
 import (
 	"encoding/hex"
-	"time"
 
-	"github.com/apache/incubator-milagro-dta/libs/crypto"
-	"github.com/apache/incubator-milagro-dta/libs/cryptowallet"
 	"github.com/apache/incubator-milagro-dta/libs/documents"
 	"github.com/apache/incubator-milagro-dta/pkg/api"
 	"github.com/apache/incubator-milagro-dta/pkg/common"
+	"github.com/apache/incubator-milagro-dta/pkg/identity"
 	"github.com/pkg/errors"
 )
 
 // CreateIdentity creates a new identity
 func (s *Service) CreateIdentity(req *api.CreateIdentityRequest) (*api.CreateIdentityResponse, error) {
-	name := req.Name
-
-	//generate crypto random seed
-	seed, err := cryptowallet.RandomBytes(48)
-	if err != nil {
-		return nil, errors.Wrap(err, "Failed to Generate random seed")
-	}
-
-	//Generate SIKE keys
-	rc1, sikePublicKey, sikeSecretKey := crypto.SIKEKeys(seed)
-	if rc1 != 0 {
-		return nil, errors.New("Failed to generate SIKE keys")
-	}
-
-	//Generate BLS keys
-	rc1, blsPublicKey, blsSecretKey := crypto.BLSKeys(seed, nil)
-	if rc1 != 0 {
-		return nil, errors.New("Failed to generate BLS keys")
-	}
-
-	ecPubKey, err := common.InitECKeys(seed)
+	idDocumentCID, err := identity.CreateIdentity(req.Name, s.Ipfs, s.Store)
 	if err != nil {
-		return nil, errors.Wrap(err, "Failed to Generate EC Pub Key from random seed")
-	}
-	//build ID Doc
-	idDocument := documents.NewIDDoc()
-	idDocument.AuthenticationReference = name
-	idDocument.BeneficiaryECPublicKey = ecPubKey
-	idDocument.SikePublicKey = sikePublicKey
-	idDocument.BLSPublicKey = blsPublicKey
-	idDocument.Timestamp = time.Now().Unix()
-	//Encode the IDDoc to envelope byte stream
-	rawDoc, err := documents.EncodeIDDocument(idDocument, blsSecretKey)
-	if err != nil {
-		return nil, errors.Wrap(err, "Failed to encode IDDocument")
-	}
-	idDocumentCID, err := s.Ipfs.Add(rawDoc)
-	if err != nil {
-		return nil, errors.Wrap(err, "Failed to Save Raw Document into IPFS")
-	}
-	secrets := common.IdentitySecrets{
-		Name:          name,
-		Seed:          hex.EncodeToString(seed),
-		BLSSecretKey:  hex.EncodeToString(blsSecretKey),
-		SikeSecretKey: hex.EncodeToString(sikeSecretKey),
-	}
-
-	if err := s.Store.Set("id-doc", idDocumentCID, secrets, map[string]string{"time": time.Now().UTC().Format(time.RFC3339)}); err != nil {
-		return nil, errors.Wrap(err, "Failed to Save ID Document - Write to Store")
+		return nil, err
 	}
 
 	return &api.CreateIdentityResponse{
diff --git a/pkg/identity/identity.go b/pkg/identity/identity.go
new file mode 100644
index 0000000..edbba97
--- /dev/null
+++ b/pkg/identity/identity.go
@@ -0,0 +1,98 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+/*
+Package identity - manage Identity document and keys
+*/
+package identity
+
+import (
+	"encoding/hex"
+	"time"
+
+	"github.com/apache/incubator-milagro-dta/libs/crypto"
+	"github.com/apache/incubator-milagro-dta/libs/cryptowallet"
+	"github.com/apache/incubator-milagro-dta/libs/datastore"
+	"github.com/apache/incubator-milagro-dta/libs/documents"
+	"github.com/apache/incubator-milagro-dta/libs/ipfs"
+	"github.com/apache/incubator-milagro-dta/pkg/common"
+	"github.com/pkg/errors"
+)
+
+// CreateIdentity creates a new identity
+// returns Identity secrets and Identity document
+func CreateIdentity(name string, ipfsConn ipfs.Connector, store *datastore.Store) (idDocumentCID string, err error) {
+	//generate crypto random seed
+	seed, err := cryptowallet.RandomBytes(48)
+	if err != nil {
+		err = errors.Wrap(err, "Failed to generate random seed")
+		return
+	}
+
+	//Generate SIKE keys
+	rc1, sikePublicKey, sikeSecretKey := crypto.SIKEKeys(seed)
+	if rc1 != 0 {
+		err = errors.New("Failed to generate SIKE keys")
+		return
+	}
+
+	//Generate BLS keys
+	rc1, blsPublicKey, blsSecretKey := crypto.BLSKeys(seed, nil)
+	if rc1 != 0 {
+		err = errors.New("Failed to generate BLS keys")
+		return
+	}
+
+	ecPubKey, err := common.InitECKeys(seed)
+	if err != nil {
+		err = errors.Wrap(err, "Failed to generate EC Public Key")
+		return
+	}
+
+	//build ID Doc
+	idDocument := documents.NewIDDoc()
+	idDocument.AuthenticationReference = name
+	idDocument.BeneficiaryECPublicKey = ecPubKey
+	idDocument.SikePublicKey = sikePublicKey
+	idDocument.BLSPublicKey = blsPublicKey
+	idDocument.Timestamp = time.Now().Unix()
+
+	rawIDDoc, err := documents.EncodeIDDocument(idDocument, blsSecretKey)
+	if err != nil {
+		err = errors.Wrap(err, "Failed to encode IDDocument")
+		return
+	}
+
+	idDocumentCID, err = ipfsConn.Add(rawIDDoc)
+
+	secrets := common.IdentitySecrets{
+		Name:          name,
+		Seed:          hex.EncodeToString(seed),
+		BLSSecretKey:  hex.EncodeToString(blsSecretKey),
+		SikeSecretKey: hex.EncodeToString(sikeSecretKey),
+	}
+
+	if store != nil {
+		err = store.Set("id-doc", idDocumentCID, secrets, map[string]string{"time": time.Now().UTC().Format(time.RFC3339)})
+		if err != nil {
+			err = errors.Wrap(err, "Failed to store ID Document")
+			return
+		}
+	}
+
+	return idDocumentCID, nil
+}


[incubator-milagro-dta] 03/03: Refactor identity secrets

Posted by sm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

smihaylov pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-dta.git

commit 6bc9bc4c9a45e1d01ef3e91f03fda0d03cb3a900
Author: Stanislav Mihaylov <sm...@gmail.com>
AuthorDate: Fri Sep 27 11:13:41 2019 +0300

    Refactor identity secrets
    
    Run CreateIdentity only once on init of the node
    Have one seed and keys for the node
    Remove create and list identity endpoints
---
 cmd/service/commands.go                            |   1 +
 cmd/service/initnode.go                            |  50 ---------
 cmd/service/main.go                                |  51 ++++------
 cmd/servicetester/e2e_test.sh                      | 112 ++++++++++-----------
 go.sum                                             |   9 ++
 libs/keystore/filestore_test.go                    |   2 +-
 libs/keystore/memorystore_test.go                  |   2 +-
 pkg/common/common.go                               |  70 +++----------
 pkg/defaultservice/fulfill.go                      |  21 +++-
 pkg/defaultservice/identity.go                     |  98 ------------------
 pkg/defaultservice/init.go                         |  13 ++-
 pkg/defaultservice/order.go                        |  49 +++++----
 pkg/defaultservice/service.go                      |   2 +
 pkg/endpoints/endpoints.go                         | 101 +------------------
 pkg/identity/identity.go                           |  89 ++++++++++------
 .../identity/identity_test.go                      |  31 +++---
 pkg/identity/keys.go                               |  63 ++++++++++++
 pkg/service/service.go                             |   5 -
 18 files changed, 298 insertions(+), 471 deletions(-)

diff --git a/cmd/service/commands.go b/cmd/service/commands.go
index 2f9167e..d3d16bd 100644
--- a/cmd/service/commands.go
+++ b/cmd/service/commands.go
@@ -28,6 +28,7 @@ import (
 const (
 	envMilagroHome      = "MILAGRO_HOME"
 	milagroConfigFolder = ".milagro"
+	keysFile            = "keys"
 
 	cmdInit   = "init"
 	cmdDaemon = "daemon"
diff --git a/cmd/service/initnode.go b/cmd/service/initnode.go
index 2760e51..ecc3b57 100644
--- a/cmd/service/initnode.go
+++ b/cmd/service/initnode.go
@@ -26,14 +26,6 @@ import (
 	"fmt"
 	"os"
 	"strings"
-
-	"github.com/apache/incubator-milagro-dta/libs/datastore"
-	"github.com/apache/incubator-milagro-dta/libs/documents"
-	"github.com/apache/incubator-milagro-dta/libs/ipfs"
-	"github.com/apache/incubator-milagro-dta/libs/logger"
-	"github.com/apache/incubator-milagro-dta/pkg/api"
-	"github.com/apache/incubator-milagro-dta/pkg/common"
-	"github.com/apache/incubator-milagro-dta/pkg/service"
 )
 
 type initOptions struct {
@@ -115,48 +107,6 @@ func interactiveSetup(i *initOptions) error {
 	return nil
 }
 
-//checkForID - Setup a NodeID if not supplied in the config
-func checkForID(logger *logger.Logger, optNodeID, optNodeName string, ipfs ipfs.Connector, store *datastore.Store, service service.Service) (nodeID string, err error) {
-	if optNodeID != "" {
-		var idSecrets = &common.IdentitySecrets{}
-		if err := store.Get("id-doc", optNodeID, idSecrets); err == nil {
-			id := &documents.IDDoc{}
-			rawDocI, err := ipfs.Get(optNodeID)
-			if err == nil {
-				if err := documents.DecodeIDDocument(rawDocI, optNodeID, id); err != nil {
-					logger.Error("Invalid ID document")
-					return "", err
-				}
-				return optNodeID, nil
-			}
-			logger.Error("ID not found in IPFS: %v", optNodeID)
-		} else {
-			logger.Error("ID not found in the database: %v", optNodeID)
-		}
-	} else {
-		logger.Error("No ID found in flags or config")
-	}
-
-	if optNodeName == "" {
-		return "", errors.New("Please provide Node name")
-	}
-
-	return createNewID(optNodeName, service)
-}
-
-func createNewID(name string, service service.Service) (newID string, err error) {
-
-	req := &api.CreateIdentityRequest{
-		Name: strings.TrimSpace(name),
-	}
-
-	resp, err := service.CreateIdentity(req)
-	if err != nil {
-		return "", err
-	}
-	return resp.IDDocumentCID, nil
-}
-
 func generateRandomName() string {
 	b := make([]byte, 8)
 	rand.Read(b)
diff --git a/cmd/service/main.go b/cmd/service/main.go
index 3953a8b..7e6a8ef 100644
--- a/cmd/service/main.go
+++ b/cmd/service/main.go
@@ -30,6 +30,8 @@ import (
 	"strings"
 	"syscall"
 
+	"github.com/apache/incubator-milagro-dta/libs/keystore"
+
 	"github.com/apache/incubator-milagro-dta/libs/datastore"
 	"github.com/apache/incubator-milagro-dta/libs/ipfs"
 	"github.com/apache/incubator-milagro-dta/libs/logger"
@@ -38,6 +40,7 @@ import (
 	"github.com/apache/incubator-milagro-dta/pkg/config"
 	"github.com/apache/incubator-milagro-dta/pkg/defaultservice"
 	"github.com/apache/incubator-milagro-dta/pkg/endpoints"
+	"github.com/apache/incubator-milagro-dta/pkg/identity"
 	"github.com/apache/incubator-milagro-dta/plugins"
 	"github.com/go-kit/kit/metrics/prometheus"
 	"github.com/pkg/errors"
@@ -74,11 +77,6 @@ func initConfig(args []string) error {
 	// Init the config folder
 	config.Init(configFolder(), cfg)
 
-	store, err := initDataStore(cfg.Node.Datastore)
-	if err != nil {
-		return errors.Wrap(err, "init datastore")
-	}
-
 	logger.Info("IPFS connector type: %s", cfg.IPFS.Connector)
 	var ipfsConnector ipfs.Connector
 	switch cfg.IPFS.Connector {
@@ -95,23 +93,15 @@ func initConfig(args []string) error {
 		return errors.Wrap(err, "init IPFS connector")
 	}
 
-	svcPlugin := plugins.FindServicePlugin(cfg.Plugins.Service)
-	if svcPlugin == nil {
-		return errors.Errorf("Invalid service plugin: %v", initOptions.ServicePlugin)
+	keyStore, err := keystore.NewFileStore(filepath.Join(configFolder(), keysFile))
+	if err != nil {
+		return err
 	}
-
-	if err := svcPlugin.Init(
-		svcPlugin,
-		defaultservice.WithLogger(logger),
-		defaultservice.WithRng(rand.Reader),
-		defaultservice.WithStore(store),
-		defaultservice.WithIPFS(ipfsConnector),
-		defaultservice.WithConfig(cfg),
-	); err != nil {
-		return errors.Errorf("init service plugin %s", cfg.Plugins.Service)
+	_, rawDocID, secret, err := identity.CreateIdentity(cfg.Node.NodeName)
+	if err != nil {
+		return err
 	}
-
-	newID, err := createNewID(cfg.Node.NodeName, svcPlugin)
+	newID, err := identity.StoreIdentity(rawDocID, secret, ipfsConnector, keyStore)
 	if err != nil {
 		return err
 	}
@@ -175,6 +165,10 @@ func startDaemon(args []string) error {
 	if err != nil {
 		return errors.Wrap(err, "init IPFS connector")
 	}
+	keyStore, err := keystore.NewFileStore(filepath.Join(configFolder(), keysFile))
+	if err != nil {
+		return err
+	}
 
 	// Setup Endpoint authorizer
 	var authorizer transport.Authorizer
@@ -208,7 +202,8 @@ func startDaemon(args []string) error {
 		svcPlugin,
 		defaultservice.WithLogger(logger),
 		defaultservice.WithRng(rand.Reader),
-		defaultservice.WithStore(store),
+		defaultservice.WithDataStore(store),
+		defaultservice.WithKeyStore(keyStore),
 		defaultservice.WithIPFS(ipfsConnector),
 		defaultservice.WithMasterFiduciary(masterFiduciaryServer),
 		defaultservice.WithConfig(cfg),
@@ -217,20 +212,12 @@ func startDaemon(args []string) error {
 	}
 	logger.Info("Service plugin loaded: %s", svcPlugin.Name())
 
-	nodeID, err := checkForID(logger, cfg.Node.NodeID, cfg.Node.NodeName, ipfsConnector, store, svcPlugin)
-	if err != nil {
-		return err
-	}
-
-	if nodeID != cfg.Node.NodeID {
-		cfg.Node.NodeID = nodeID
-		if err := config.SaveConfig(configFolder(), cfg); err != nil {
-			return errors.Wrap(err, "cannot update config")
-		}
+	if err := identity.CheckIdentity(cfg.Node.NodeID, cfg.Node.NodeName, ipfsConnector, keyStore); err != nil {
+		return errors.Wrap(err, "Invalid node identity")
 	}
 
 	svcPlugin.SetMasterFiduciaryNodeID(cfg.Node.MasterFiduciaryNodeID)
-	svcPlugin.SetNodeID(nodeID)
+	svcPlugin.SetNodeID(cfg.Node.NodeID)
 
 	// Create metrics
 	duration := prometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
diff --git a/cmd/servicetester/e2e_test.sh b/cmd/servicetester/e2e_test.sh
index 8ba4277..66c59df 100755
--- a/cmd/servicetester/e2e_test.sh
+++ b/cmd/servicetester/e2e_test.sh
@@ -95,63 +95,61 @@ execute_bitcoin () {
 
 
    #make another BeneficiaryID
-   output5=$(curl -s -X POST "http://localhost:5556/$apiVersion/identity" -H "accept: */*" -H       "Content-Type: application/json" -d "{\"Name\":\"AA\"}")
-   benid=$(echo $output5 | jq -r .idDocumentCID)
-
-
-
-   #Tests against the Bitcoin Extension - different befificary
-   output6=$(curl -s -X POST "http://localhost:5556/$apiVersion/order" -H "accept: */*" -H "Content-Type: application/json" -d "{\"beneficiaryIDDocumentCID\":\"\",\"extension\":{\"coin\":\"0\"}}")
-   #echo $output6
-   op6=$(echo $output6 | jq .orderReference)
-   commitment6=$(echo $output6 | jq .commitment)
-   address6=$(echo $output6 | jq .extension.address)
-
-   output7=$(curl -s -X POST "http://localhost:5556/$apiVersion/order/secret" -H "accept: */*" -H "Content-Type: application/json" -d "{\"orderReference\":$op6,\"beneficiaryIDDocumentCID\":\"$benid\"}")
-   address7=$(echo $output7 | jq .extension.address)
-   commitment7=$(echo $output7 | jq .commitment)
-
-   echo "Committment5 $commitment6 $address6"
-   echo "Committment6 $commitment7 $address7"
-
-   if [ -z $commitment7 ]; then
-       echo "Failed Commitment is empty"
-       exit 1
-   fi
-
-   if [ $commitment6 == $commitment7 ]; then
-     echo "Pass - Id, Order & OrderSecret(Beneficiary)"
-   else
-     echo "Fail"
-     exit 1
-   fi
-
-  output8=$(curl -s -X POST "http://localhost:5556/$apiVersion/order" -H "accept: */*" -H "Content-Type: application/json" -d "{\"beneficiaryIDDocumentCID\":\"$benid\",\"extension\":{\"coin\":\"0\"}}")
-  op8=$(echo $output8 | jq .orderReference)
-  commitment8=$(echo $output8 | jq .commitment)
-  address8=$(echo $output8 | jq .extension.address)
-
-
-  output9=$(curl -s -X POST "http://localhost:5556/$apiVersion/order/secret" -H "accept: */*" -H "Content-Type: application/json" -d "{\"orderReference\":$op8}")
-  commitment9=$(echo $output9 | jq .commitment)
-  address9=$(echo $output9 | jq .extension.address)
-  orderReference=$(echo $output9 | jq .orderReference)
-  orderIndex=1
-
-  echo "Committment7 $commitment8 $address8"
-  echo "Committment8 $commitment9 $address9"
-
-  if [ -z $commitment9 ]; then
-      echo "Failed Commitment is empty"
-      exit 1
-  fi
-
-  if [ $commitment8 == $commitment9 ]; then
-    echo "Pass - Id, Order(Beneficiary) & OrderSecret"
-  else
-      echo "Fail"
-      exit 1
-  fi
+  #  output5=$(curl -s -X POST "http://localhost:5556/$apiVersion/identity" -H "accept: */*" -H       "Content-Type: application/json" -d "{\"Name\":\"AA\"}")
+  #  benid=$(echo $output5 | jq -r .idDocumentCID)
+
+  #  #Tests against the Bitcoin Extension - different befificary
+  #  output6=$(curl -s -X POST "http://localhost:5556/$apiVersion/order" -H "accept: */*" -H "Content-Type: application/json" -d "{\"beneficiaryIDDocumentCID\":\"\",\"extension\":{\"coin\":\"0\"}}")
+  #  #echo $output6
+  #  op6=$(echo $output6 | jq .orderReference)
+  #  commitment6=$(echo $output6 | jq .commitment)
+  #  address6=$(echo $output6 | jq .extension.address)
+
+  #  output7=$(curl -s -X POST "http://localhost:5556/$apiVersion/order/secret" -H "accept: */*" -H "Content-Type: application/json" -d "{\"orderReference\":$op6,\"beneficiaryIDDocumentCID\":\"$benid\"}")
+  #  address7=$(echo $output7 | jq .extension.address)
+  #  commitment7=$(echo $output7 | jq .commitment)
+
+  #  echo "Committment5 $commitment6 $address6"
+  #  echo "Committment6 $commitment7 $address7"
+
+  #  if [ -z $commitment7 ]; then
+  #      echo "Failed Commitment is empty"
+  #      exit 1
+  #  fi
+
+  #  if [ $commitment6 == $commitment7 ]; then
+  #    echo "Pass - Id, Order & OrderSecret(Beneficiary)"
+  #  else
+  #    echo "Fail"
+  #    exit 1
+  #  fi
+
+  # output8=$(curl -s -X POST "http://localhost:5556/$apiVersion/order" -H "accept: */*" -H "Content-Type: application/json" -d "{\"beneficiaryIDDocumentCID\":\"$benid\",\"extension\":{\"coin\":\"0\"}}")
+  # op8=$(echo $output8 | jq .orderReference)
+  # commitment8=$(echo $output8 | jq .commitment)
+  # address8=$(echo $output8 | jq .extension.address)
+
+
+  # output9=$(curl -s -X POST "http://localhost:5556/$apiVersion/order/secret" -H "accept: */*" -H "Content-Type: application/json" -d "{\"orderReference\":$op8}")
+  # commitment9=$(echo $output9 | jq .commitment)
+  # address9=$(echo $output9 | jq .extension.address)
+  # orderReference=$(echo $output9 | jq .orderReference)
+  # orderIndex=1
+
+  # echo "Committment7 $commitment8 $address8"
+  # echo "Committment8 $commitment9 $address9"
+
+  # if [ -z $commitment9 ]; then
+  #     echo "Failed Commitment is empty"
+  #     exit 1
+  # fi
+
+  # if [ $commitment8 == $commitment9 ]; then
+  #   echo "Pass - Id, Order(Beneficiary) & OrderSecret"
+  # else
+  #     echo "Fail"
+  #     exit 1
+  # fi
 
 }
 
diff --git a/go.sum b/go.sum
index aed6fea..dfb1954 100644
--- a/go.sum
+++ b/go.sum
@@ -13,6 +13,7 @@ github.com/Stebalien/go-bitfield v0.0.0-20180330043415-076a62f9ce6e/go.mod h1:3o
 github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo=
 github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s=
 github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
+github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg=
 github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@@ -28,13 +29,18 @@ github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dm
 github.com/btcsuite/btcd v0.0.0-20190427004231-96897255fd17/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
 github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3 h1:A/EVblehb75cUgXA5njHPn0kLAsykn6mJGz7rnmW5W0=
 github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
+github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
 github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
 github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
 github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
 github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
+github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw=
 github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
+github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd h1:qdGvebPBDuYDPGi1WCPjy1tGyMpmDK8IEapSsszn7HE=
 github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
+github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723 h1:ZA/jbKoGcVAnER6pCHPEkGdZOV7U1oLUedErBHCUMs0=
 github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
+github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc=
 github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
 github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
 github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY=
@@ -283,14 +289,17 @@ github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod
 github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
 github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10=
 github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
+github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89 h1:12K8AlpT0/6QUXSfV0yi4Q0jkbq8NDtIKFtF61AoqV0=
 github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI=
 github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
 github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/gotool v0.0.0-20161130080628-0de1eaf82fa3/go.mod h1:jxZFDH7ILpTPQTk+E2s+z4CUas9lVNjIuKR4c5/zKgM=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE=
 github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
 github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
diff --git a/libs/keystore/filestore_test.go b/libs/keystore/filestore_test.go
index 7e946dd..52c5958 100644
--- a/libs/keystore/filestore_test.go
+++ b/libs/keystore/filestore_test.go
@@ -28,7 +28,7 @@ import (
 )
 
 func TestFileStore(t *testing.T) {
-	keys := map[string][]byte{"key1": []byte{1}, "key2": []byte{1, 2}, "key3": []byte{1, 2, 3}}
+	keys := map[string][]byte{"key1": {1}, "key2": {1, 2}, "key3": {1, 2, 3}}
 
 	fn := tmpFileName()
 	defer func() {
diff --git a/libs/keystore/memorystore_test.go b/libs/keystore/memorystore_test.go
index 5dd92a2..bd2a2b8 100644
--- a/libs/keystore/memorystore_test.go
+++ b/libs/keystore/memorystore_test.go
@@ -23,7 +23,7 @@ import (
 )
 
 func TestMemoryStore(t *testing.T) {
-	keys := map[string][]byte{"key1": []byte{1}, "key2": []byte{1, 2}, "key3": []byte{1, 2, 3}}
+	keys := map[string][]byte{"key1": {1}, "key2": {1, 2}, "key3": {1, 2, 3}}
 
 	ms, err := NewMemoryStore()
 	if err != nil {
diff --git a/pkg/common/common.go b/pkg/common/common.go
index 6fefee7..03f815a 100644
--- a/pkg/common/common.go
+++ b/pkg/common/common.go
@@ -25,22 +25,15 @@ import (
 	"io"
 	"time"
 
-	"github.com/apache/incubator-milagro-dta/libs/cryptowallet"
 	"github.com/apache/incubator-milagro-dta/libs/datastore"
 	"github.com/apache/incubator-milagro-dta/libs/documents"
 	"github.com/apache/incubator-milagro-dta/libs/ipfs"
+	"github.com/apache/incubator-milagro-dta/libs/keystore"
+	"github.com/apache/incubator-milagro-dta/pkg/identity"
 	"github.com/google/uuid"
 	"github.com/pkg/errors"
 )
 
-//IdentitySecrets - keys required for decryption and signing
-type IdentitySecrets struct {
-	Name          string `json:"Name"`
-	Seed          string `json:"Seed"`
-	SikeSecretKey string `json:"SikeSecretKey"`
-	BLSSecretKey  string `json:"BlsSecretKey"`
-}
-
 // CreateNewDepositOrder - Generate an empty new Deposit Order with random reference
 func CreateNewDepositOrder(BeneficiaryIDDocumentCID string, nodeID string) (*documents.OrderDoc, error) {
 	//Create a reference for this order
@@ -108,7 +101,7 @@ func RetrieveSeed(store *datastore.Store, reference string) (seedHex string, err
 }
 
 // CreateAndStoreOrderPart2 -
-func CreateAndStoreOrderPart2(ipfs ipfs.Connector, store *datastore.Store, order *documents.OrderDoc, orderPart1CID, commitmentPublicKey, nodeID string, recipients map[string]*documents.IDDoc) (orderPart2CID string, err error) {
+func CreateAndStoreOrderPart2(ipfs ipfs.Connector, store *datastore.Store, keyStore keystore.Store, order *documents.OrderDoc, orderPart1CID, commitmentPublicKey, nodeID string, recipients map[string]*documents.IDDoc) (orderPart2CID string, err error) {
 	Part2 := documents.OrderPart2{
 		CommitmentPublicKey: commitmentPublicKey,
 		PreviousOrderCID:    orderPart1CID,
@@ -116,7 +109,7 @@ func CreateAndStoreOrderPart2(ipfs ipfs.Connector, store *datastore.Store, order
 	}
 	order.OrderPart2 = &Part2
 	//Write the updated doc back to IPFS
-	orderPart2CID, err = WriteOrderToIPFS(nodeID, ipfs, store, nodeID, order, recipients)
+	orderPart2CID, err = WriteOrderToIPFS(nodeID, ipfs, store, keyStore, nodeID, order, recipients)
 	if err != nil {
 		return "", err
 	}
@@ -124,7 +117,7 @@ func CreateAndStoreOrderPart2(ipfs ipfs.Connector, store *datastore.Store, order
 }
 
 // CreateAndStorePart3 adds part 3 "redemption request" to the order doc
-func CreateAndStorePart3(ipfs ipfs.Connector, store *datastore.Store, order *documents.OrderDoc, orderPart2CID, nodeID string, beneficiaryEncryptedData []byte, recipients map[string]*documents.IDDoc) (orderPart3CID string, err error) {
+func CreateAndStorePart3(ipfs ipfs.Connector, store *datastore.Store, keyStore keystore.Store, order *documents.OrderDoc, orderPart2CID, nodeID string, beneficiaryEncryptedData []byte, recipients map[string]*documents.IDDoc) (orderPart3CID string, err error) {
 	//Add part 3 "redemption request" to the order doc
 	redemptionRequest := documents.OrderPart3{
 		//TODO
@@ -135,7 +128,7 @@ func CreateAndStorePart3(ipfs ipfs.Connector, store *datastore.Store, order *doc
 	}
 	order.OrderPart3 = &redemptionRequest
 	//Write the updated doc back to IPFS
-	orderPart3CID, err = WriteOrderToIPFS(nodeID, ipfs, store, nodeID, order, recipients)
+	orderPart3CID, err = WriteOrderToIPFS(nodeID, ipfs, store, keyStore, nodeID, order, recipients)
 	if err != nil {
 		return "", nil
 	}
@@ -143,7 +136,7 @@ func CreateAndStorePart3(ipfs ipfs.Connector, store *datastore.Store, order *doc
 }
 
 // CreateAndStoreOrderPart4 -
-func CreateAndStoreOrderPart4(ipfs ipfs.Connector, store *datastore.Store, order *documents.OrderDoc, commitmentPrivateKey, orderPart3CID, nodeID string, recipients map[string]*documents.IDDoc) (orderPart4CID string, err error) {
+func CreateAndStoreOrderPart4(ipfs ipfs.Connector, store *datastore.Store, keyStore keystore.Store, order *documents.OrderDoc, commitmentPrivateKey, orderPart3CID, nodeID string, recipients map[string]*documents.IDDoc) (orderPart4CID string, err error) {
 	Part4 := documents.OrderPart4{
 		Secret:           commitmentPrivateKey,
 		PreviousOrderCID: orderPart3CID,
@@ -151,7 +144,7 @@ func CreateAndStoreOrderPart4(ipfs ipfs.Connector, store *datastore.Store, order
 	}
 	order.OrderPart4 = &Part4
 	//Write the updated doc back to IPFS
-	orderPart4CID, err = WriteOrderToIPFS(nodeID, ipfs, store, nodeID, order, recipients)
+	orderPart4CID, err = WriteOrderToIPFS(nodeID, ipfs, store, keyStore, nodeID, order, recipients)
 	if err != nil {
 		return "", nil
 	}
@@ -159,14 +152,14 @@ func CreateAndStoreOrderPart4(ipfs ipfs.Connector, store *datastore.Store, order
 }
 
 // WriteOrderToIPFS writes the order document to IPFS network
-func WriteOrderToIPFS(nodeID string, ipfs ipfs.Connector, store *datastore.Store, id string, order *documents.OrderDoc, recipients map[string]*documents.IDDoc) (ipfsAddress string, err error) { // Get the secret keys
-	secrets := &IdentitySecrets{}
-	if err := store.Get("id-doc", nodeID, secrets); err != nil {
-		return "", errors.New("load secrets from store")
+func WriteOrderToIPFS(nodeID string, ipfs ipfs.Connector, store *datastore.Store, keyStore keystore.Store, id string, order *documents.OrderDoc, recipients map[string]*documents.IDDoc) (ipfsAddress string, err error) { // Get the secret keys
+	seed, err := keyStore.Get("seed")
+	if err != nil {
+		return "", errors.New("load secrets")
 	}
-	blsSecretKey, err := hex.DecodeString(secrets.BLSSecretKey)
+	_, blsSecretKey, err := identity.GenerateBLSKeys(seed)
 	if err != nil {
-		return "", errors.Wrap(err, "Decode identity secrets")
+		return "", err
 	}
 
 	rawDoc, err := documents.EncodeOrderDocument(nodeID, *order, blsSecretKey, recipients)
@@ -184,41 +177,6 @@ func WriteOrderToIPFS(nodeID string, ipfs ipfs.Connector, store *datastore.Store
 	return ipfsAddress, nil
 }
 
-//InitECKeys - generate EC keys using BIP44 HD Wallets (as bitcoin) from seed
-func InitECKeys(seed []byte) ([]byte, error) {
-	//EC ADD Keypair Protocol
-	_, pubKeyECADD, _, err := cryptowallet.Bip44Address(seed, cryptowallet.CoinTypeBitcoinMain, 0, 0, 0)
-	if err != nil {
-		return nil, errors.Wrap(err, "Failed to derive EC HD Wallet Key")
-	}
-	return pubKeyECADD.SerializeCompressed(), nil
-}
-
-// RetrieveIdentitySecrets gets the secrets for the node ID
-func RetrieveIdentitySecrets(store *datastore.Store, nodeID string) (name string, seed []byte, blsSK []byte, sikeSK []byte, err error) {
-
-	var idSecrets = &IdentitySecrets{}
-	if err := store.Get("id-doc", nodeID, idSecrets); err != nil {
-		return "", nil, nil, nil, err
-	}
-
-	seed, err = hex.DecodeString(idSecrets.Seed)
-	if err != nil {
-		return "", nil, nil, nil, err
-	}
-
-	blsSK, err = hex.DecodeString(idSecrets.BLSSecretKey)
-	if err != nil {
-		return "", nil, nil, nil, err
-	}
-
-	sikeSK, err = hex.DecodeString(idSecrets.SikeSecretKey)
-	if err != nil {
-		return "", nil, nil, nil, err
-	}
-	return idSecrets.Name, seed, blsSK, sikeSK, nil
-}
-
 // BuildRecipientList builds a list of recipients who are able to decrypt the encrypted envelope
 func BuildRecipientList(ipfs ipfs.Connector, localNodeDocCID, remoteNodeDocCID string) (map[string]*documents.IDDoc, error) {
 	remoteNodeDoc, err := RetrieveIDDocFromIPFS(ipfs, remoteNodeDocCID)
diff --git a/pkg/defaultservice/fulfill.go b/pkg/defaultservice/fulfill.go
index a45eacb..ae6e21f 100644
--- a/pkg/defaultservice/fulfill.go
+++ b/pkg/defaultservice/fulfill.go
@@ -21,6 +21,7 @@ import (
 	"github.com/apache/incubator-milagro-dta/libs/cryptowallet"
 	"github.com/apache/incubator-milagro-dta/pkg/api"
 	"github.com/apache/incubator-milagro-dta/pkg/common"
+	"github.com/apache/incubator-milagro-dta/pkg/identity"
 )
 
 // FulfillOrder -
@@ -28,7 +29,13 @@ func (s *Service) FulfillOrder(req *api.FulfillOrderRequest) (*api.FulfillOrderR
 	orderPart1CID := req.OrderPart1CID
 	nodeID := s.NodeID()
 	remoteIDDocCID := req.DocumentCID
-	_, _, _, sikeSK, err := common.RetrieveIdentitySecrets(s.Store, nodeID)
+
+	// SIKE key
+	keyseed, err := s.KeyStore.Get("seed")
+	if err != nil {
+		return nil, err
+	}
+	_, sikeSK, err := identity.GenerateSIKEKeys(keyseed)
 	if err != nil {
 		return nil, err
 	}
@@ -62,7 +69,7 @@ func (s *Service) FulfillOrder(req *api.FulfillOrderRequest) (*api.FulfillOrderR
 	}
 
 	//Create an order response in IPFS
-	orderPart2CID, err := common.CreateAndStoreOrderPart2(s.Ipfs, s.Store, order, orderPart1CID, commitmentPublicKey, nodeID, recipientList)
+	orderPart2CID, err := common.CreateAndStoreOrderPart2(s.Ipfs, s.Store, s.KeyStore, order, orderPart1CID, commitmentPublicKey, nodeID, recipientList)
 	if err != nil {
 		return nil, err
 	}
@@ -78,7 +85,13 @@ func (s *Service) FulfillOrderSecret(req *api.FulfillOrderSecretRequest) (*api.F
 	orderPart3CID := req.OrderPart3CID
 	nodeID := s.NodeID()
 	remoteIDDocCID := req.SenderDocumentCID
-	_, _, _, sikeSK, err := common.RetrieveIdentitySecrets(s.Store, nodeID)
+
+	// SIKE key
+	keyseed, err := s.KeyStore.Get("seed")
+	if err != nil {
+		return nil, err
+	}
+	_, sikeSK, err := identity.GenerateSIKEKeys(keyseed)
 	if err != nil {
 		return nil, err
 	}
@@ -112,7 +125,7 @@ func (s *Service) FulfillOrderSecret(req *api.FulfillOrderSecretRequest) (*api.F
 	}
 
 	//Create an order response in IPFS
-	orderPart4ID, err := common.CreateAndStoreOrderPart4(s.Ipfs, s.Store, order, commitmentPrivateKey, orderPart3CID, nodeID, recipientList)
+	orderPart4ID, err := common.CreateAndStoreOrderPart4(s.Ipfs, s.Store, s.KeyStore, order, commitmentPrivateKey, orderPart3CID, nodeID, recipientList)
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/defaultservice/identity.go b/pkg/defaultservice/identity.go
deleted file mode 100644
index ae256e5..0000000
--- a/pkg/defaultservice/identity.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package defaultservice
-
-import (
-	"encoding/hex"
-
-	"github.com/apache/incubator-milagro-dta/libs/documents"
-	"github.com/apache/incubator-milagro-dta/pkg/api"
-	"github.com/apache/incubator-milagro-dta/pkg/common"
-	"github.com/apache/incubator-milagro-dta/pkg/identity"
-	"github.com/pkg/errors"
-)
-
-// CreateIdentity creates a new identity
-func (s *Service) CreateIdentity(req *api.CreateIdentityRequest) (*api.CreateIdentityResponse, error) {
-	idDocumentCID, err := identity.CreateIdentity(req.Name, s.Ipfs, s.Store)
-	if err != nil {
-		return nil, err
-	}
-
-	return &api.CreateIdentityResponse{
-		IDDocumentCID: idDocumentCID,
-	}, nil
-}
-
-// GetIdentity retrieves an identity
-func (s *Service) GetIdentity(req *api.GetIdentityRequest) (*api.GetIdentityResponse, error) {
-	idDocumentCID := req.IDDocumentCID
-	idDocument, err := common.RetrieveIDDocFromIPFS(s.Ipfs, idDocumentCID)
-	if err != nil {
-		return nil, err
-	}
-	return &api.GetIdentityResponse{
-		IDDocumentCID:           idDocumentCID,
-		AuthenticationReference: idDocument.AuthenticationReference,
-		BeneficiaryECPublicKey:  hex.EncodeToString(idDocument.BeneficiaryECPublicKey),
-		SikePublicKey:           hex.EncodeToString(idDocument.SikePublicKey),
-		BLSPublicKey:            hex.EncodeToString(idDocument.BLSPublicKey),
-		Timestamp:               idDocument.Timestamp,
-	}, nil
-}
-
-// IdentityList reutrns the list of identities
-func (s *Service) IdentityList(req *api.IdentityListRequest) (*api.IdentityListResponse, error) {
-	page := req.Page
-	perPage := req.PerPage
-	sortBy := req.SortBy
-
-	IDDocumentCIDes, err := s.Store.ListKeys("id-doc", "time", page*perPage, perPage, sortBy != "dateCreatedAsc")
-	if err != nil {
-		return nil, err
-	}
-
-	fullIDList := make([]api.GetIdentityResponse, len(IDDocumentCIDes))
-	for i, idAddress := range IDDocumentCIDes {
-
-		rawDocI, err := s.Ipfs.Get(idAddress)
-		if err != nil {
-			return nil, errors.Wrapf(err, "Read identity Doc")
-		}
-
-		idDocument := &documents.IDDoc{}
-		if err = documents.DecodeIDDocument(rawDocI, idAddress, idDocument); err != nil {
-			return nil, err
-		}
-		//Need to copy the whole object so I can append the idddocadderess
-		idWithAddress := api.GetIdentityResponse{
-			IDDocumentCID:           idAddress,
-			AuthenticationReference: idDocument.AuthenticationReference,
-			BeneficiaryECPublicKey:  hex.EncodeToString(idDocument.BeneficiaryECPublicKey),
-			SikePublicKey:           hex.EncodeToString(idDocument.SikePublicKey),
-			BLSPublicKey:            hex.EncodeToString(idDocument.BLSPublicKey),
-			Timestamp:               idDocument.Timestamp,
-		}
-
-		fullIDList[i] = idWithAddress
-	}
-
-	return &api.IdentityListResponse{
-		IDDocumentList: fullIDList,
-	}, nil
-}
diff --git a/pkg/defaultservice/init.go b/pkg/defaultservice/init.go
index a39697a..f0c0190 100644
--- a/pkg/defaultservice/init.go
+++ b/pkg/defaultservice/init.go
@@ -22,6 +22,7 @@ import (
 
 	"github.com/apache/incubator-milagro-dta/libs/datastore"
 	"github.com/apache/incubator-milagro-dta/libs/ipfs"
+	"github.com/apache/incubator-milagro-dta/libs/keystore"
 	"github.com/apache/incubator-milagro-dta/libs/logger"
 	"github.com/apache/incubator-milagro-dta/pkg/api"
 	"github.com/apache/incubator-milagro-dta/pkg/config"
@@ -59,14 +60,22 @@ func WithRng(rng io.Reader) ServiceOption {
 	}
 }
 
-// WithStore adds store to the Service
-func WithStore(store *datastore.Store) ServiceOption {
+// WithDataStore adds store to the Service
+func WithDataStore(store *datastore.Store) ServiceOption {
 	return func(s *Service) error {
 		s.Store = store
 		return nil
 	}
 }
 
+// WithKeyStore adds store to the Service
+func WithKeyStore(store keystore.Store) ServiceOption {
+	return func(s *Service) error {
+		s.KeyStore = store
+		return nil
+	}
+}
+
 // WithIPFS adds ipfs connector to the Service
 func WithIPFS(ipfsConnector ipfs.Connector) ServiceOption {
 	return func(s *Service) error {
diff --git a/pkg/defaultservice/order.go b/pkg/defaultservice/order.go
index 4326ba0..bafd24c 100644
--- a/pkg/defaultservice/order.go
+++ b/pkg/defaultservice/order.go
@@ -25,6 +25,7 @@ import (
 	"github.com/apache/incubator-milagro-dta/libs/documents"
 	"github.com/apache/incubator-milagro-dta/pkg/api"
 	"github.com/apache/incubator-milagro-dta/pkg/common"
+	"github.com/apache/incubator-milagro-dta/pkg/identity"
 	"github.com/pkg/errors"
 )
 
@@ -42,7 +43,12 @@ func (s *Service) GetOrder(req *api.GetOrderRequest) (*api.GetOrderResponse, err
 		return nil, err
 	}
 
-	_, _, _, sikeSK, err := common.RetrieveIdentitySecrets(s.Store, s.NodeID())
+	// SIKE key
+	keyseed, err := s.KeyStore.Get("seed")
+	if err != nil {
+		return nil, err
+	}
+	_, sikeSK, err := identity.GenerateSIKEKeys(keyseed)
 	if err != nil {
 		return nil, err
 	}
@@ -116,6 +122,7 @@ func (s *Service) Order(req *api.OrderRequest) (*api.OrderResponse, error) {
 	//Initialise values from Request object
 	beneficiaryIDDocumentCID := req.BeneficiaryIDDocumentCID
 	iDDocID := s.NodeID()
+
 	recipientList, err := common.BuildRecipientList(s.Ipfs, iDDocID, s.MasterFiduciaryNodeID())
 	if err != nil {
 		return nil, err
@@ -138,7 +145,7 @@ func (s *Service) Order(req *api.OrderRequest) (*api.OrderResponse, error) {
 	}
 
 	//Write Order to IPFS
-	orderPart1CID, err := common.WriteOrderToIPFS(iDDocID, s.Ipfs, s.Store, iDDocID, order, recipientList)
+	orderPart1CID, err := common.WriteOrderToIPFS(iDDocID, s.Ipfs, s.Store, s.KeyStore, iDDocID, order, recipientList)
 	if err != nil {
 		return nil, err
 	}
@@ -154,11 +161,16 @@ func (s *Service) Order(req *api.OrderRequest) (*api.OrderResponse, error) {
 		return nil, errors.Wrap(err, "Contacting Fiduciary")
 	}
 
-	//Get the updated order out of IPFS
-	_, _, _, sikeSK, err := common.RetrieveIdentitySecrets(s.Store, iDDocID)
+	// SIKE key
+	keyseed, err := s.KeyStore.Get("seed")
+	if err != nil {
+		return nil, err
+	}
+	_, sikeSK, err := identity.GenerateSIKEKeys(keyseed)
 	if err != nil {
 		return nil, err
 	}
+
 	updatedOrder, err := common.RetrieveOrderFromIPFS(s.Ipfs, response.OrderPart2CID, sikeSK, iDDocID, remoteIDDoc.BLSPublicKey)
 	if err != nil {
 		return nil, errors.Wrap(err, "Fail to retrieve Order from IPFS")
@@ -208,7 +220,16 @@ func (s *Service) OrderSecret(req *api.OrderSecretRequest) (*api.OrderSecretResp
 		return nil, err
 	}
 
-	_, _, blsSK, sikeSK, err := common.RetrieveIdentitySecrets(s.Store, nodeID)
+	// SIKE and BLS keys
+	keyseed, err := s.KeyStore.Get("seed")
+	if err != nil {
+		return nil, err
+	}
+	_, sikeSK, err := identity.GenerateSIKEKeys(keyseed)
+	if err != nil {
+		return nil, err
+	}
+	_, blsSK, err := identity.GenerateBLSKeys(keyseed)
 	if err != nil {
 		return nil, err
 	}
@@ -219,19 +240,9 @@ func (s *Service) OrderSecret(req *api.OrderSecretRequest) (*api.OrderSecretResp
 		return nil, errors.Wrap(err, "Fail to retrieve Order from IPFS")
 	}
 
-	var beneficiariesSikeSK []byte
-	var beneficiaryCID string
-
-	if req.BeneficiaryIDDocumentCID != "" {
-		beneficiaryCID = req.BeneficiaryIDDocumentCID
-	} else {
-		beneficiaryCID = order.BeneficiaryCID
-	}
-
-	_, beneficiariesSeed, _, beneficiariesSikeSK, err := common.RetrieveIdentitySecrets(s.Store, beneficiaryCID)
-	if err != nil {
-		return nil, err
-	}
+	// TODO: Split Beneficiary and Principal
+	beneficiariesSeed := keyseed
+	beneficiariesSikeSK := sikeSK
 
 	if err := s.Plugin.ValidateOrderSecretRequest(req, *order); err != nil {
 		return nil, err
@@ -245,7 +256,7 @@ func (s *Service) OrderSecret(req *api.OrderSecretRequest) (*api.OrderSecretResp
 	}
 
 	//Create a request Object in IPFS
-	orderPart3CID, err := common.CreateAndStorePart3(s.Ipfs, s.Store, order, orderPart2CID, nodeID, beneficiaryEncryptedData, recipientList)
+	orderPart3CID, err := common.CreateAndStorePart3(s.Ipfs, s.Store, s.KeyStore, order, orderPart2CID, nodeID, beneficiaryEncryptedData, recipientList)
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/defaultservice/service.go b/pkg/defaultservice/service.go
index f03ef54..b1787a3 100644
--- a/pkg/defaultservice/service.go
+++ b/pkg/defaultservice/service.go
@@ -26,6 +26,7 @@ import (
 
 	"github.com/apache/incubator-milagro-dta/libs/datastore"
 	"github.com/apache/incubator-milagro-dta/libs/ipfs"
+	"github.com/apache/incubator-milagro-dta/libs/keystore"
 	"github.com/apache/incubator-milagro-dta/libs/logger"
 	"github.com/apache/incubator-milagro-dta/libs/transport"
 	"github.com/apache/incubator-milagro-dta/pkg/api"
@@ -43,6 +44,7 @@ type Service struct {
 	Logger                *logger.Logger
 	Rng                   io.Reader
 	Store                 *datastore.Store
+	KeyStore              keystore.Store
 	Ipfs                  ipfs.Connector
 	MasterFiduciaryServer api.ClientService
 	nodeID                string
diff --git a/pkg/endpoints/endpoints.go b/pkg/endpoints/endpoints.go
index 1481e8f..b1f7d9d 100644
--- a/pkg/endpoints/endpoints.go
+++ b/pkg/endpoints/endpoints.go
@@ -46,48 +46,6 @@ var (
 
 // Endpoints returns all the exported endpoints
 func Endpoints(svc service.Service, corsAllow string, authorizer transport.Authorizer, logger *logger.Logger, nodeType string, pluginEndpoints service.Endpoints) transport.HTTPEndpoints {
-	identityEndpoints := transport.HTTPEndpoints{
-		"CreateIdentity": {
-			Path:        "/" + apiVersion + "/identity",
-			Method:      http.MethodPost,
-			Endpoint:    MakeCreateIdentityEndpoint(svc),
-			NewRequest:  func() interface{} { return &api.CreateIdentityRequest{} },
-			NewResponse: func() interface{} { return &api.CreateIdentityResponse{} },
-			Options: transport.ServerOptions(
-				transport.SetCors(corsAllow),
-				transport.AuthorizeOIDC(authorizer, false),
-			),
-			ErrStatus: transport.ErrorStatus{
-				transport.ErrInvalidRequest: http.StatusUnprocessableEntity,
-			},
-		},
-		"GetIdentity": {
-			Path:        "/" + apiVersion + "/identity/{IDDocumentCID}",
-			Method:      http.MethodGet,
-			Endpoint:    MakeGetIdentityEndpoint(svc),
-			NewResponse: func() interface{} { return &api.GetIdentityResponse{} },
-			Options: transport.ServerOptions(
-				transport.SetCors(corsAllow),
-				transport.AuthorizeOIDC(authorizer, false),
-			),
-			ErrStatus: transport.ErrorStatus{
-				transport.ErrInvalidRequest: http.StatusUnprocessableEntity,
-			},
-		},
-		"IdentityList": {
-			Path:        "/" + apiVersion + "/identity",
-			Method:      http.MethodGet,
-			Endpoint:    MakeIdentityListEndpoint(svc),
-			NewResponse: func() interface{} { return &api.IdentityListResponse{} },
-			Options: transport.ServerOptions(
-				transport.SetCors(corsAllow),
-				transport.AuthorizeOIDC(authorizer, false),
-			),
-			ErrStatus: transport.ErrorStatus{
-				transport.ErrInvalidRequest: http.StatusUnprocessableEntity,
-			},
-		},
-	}
 	principalEndpoints := transport.HTTPEndpoints{
 		"Order": {
 			Path:        "/" + apiVersion + "/order",
@@ -198,11 +156,11 @@ func Endpoints(svc service.Service, corsAllow string, authorizer transport.Autho
 	endpoints := transport.HTTPEndpoints{}
 	switch strings.ToLower(nodeType) {
 	case "multi":
-		endpoints = concatEndpoints(masterFiduciaryEndpoints, identityEndpoints, principalEndpoints, statusEndPoints)
+		endpoints = concatEndpoints(masterFiduciaryEndpoints, principalEndpoints, statusEndPoints)
 	case "principal":
-		endpoints = concatEndpoints(identityEndpoints, principalEndpoints, statusEndPoints)
+		endpoints = concatEndpoints(principalEndpoints, statusEndPoints)
 	case "fiduciary", "masterfiduciary":
-		endpoints = concatEndpoints(masterFiduciaryEndpoints, identityEndpoints, statusEndPoints)
+		endpoints = concatEndpoints(masterFiduciaryEndpoints, statusEndPoints)
 	}
 
 	plugNamespace, plugEndpoints := pluginEndpoints.Endpoints()
@@ -232,59 +190,6 @@ func concatPluginEndpoints(logger *logger.Logger, dst transport.HTTPEndpoints, n
 	return dst
 }
 
-//MakeCreateIdentityEndpoint -
-func MakeCreateIdentityEndpoint(m service.Service) endpoint.Endpoint {
-	return func(ctx context.Context, request interface{}) (response interface{}, err error) {
-		req, ok := request.(*api.CreateIdentityRequest)
-		if !ok {
-			return nil, transport.ErrInvalidRequest
-		}
-		if err := validateRequest(req); err != nil {
-			return "", err
-		}
-		return m.CreateIdentity(req)
-	}
-}
-
-//MakeGetIdentityEndpoint -
-func MakeGetIdentityEndpoint(m service.Service) endpoint.Endpoint {
-	return func(ctx context.Context, request interface{}) (response interface{}, err error) {
-		params := transport.GetURLParams(ctx)
-		req := &api.GetIdentityRequest{
-			IDDocumentCID: params.Get("IDDocumentCID"),
-		}
-		if err := validateRequest(req); err != nil {
-			return "", err
-		}
-		return m.GetIdentity(req)
-	}
-}
-
-//MakeIdentityListEndpoint -
-func MakeIdentityListEndpoint(m service.Service) endpoint.Endpoint {
-	return func(ctx context.Context, request interface{}) (response interface{}, err error) {
-		params := transport.GetParams(ctx)
-		sortBy := params.Get("sortBy")
-		perPage, err := strconv.Atoi(params.Get("perPage"))
-		if err != nil {
-			return nil, transport.ErrInvalidRequest
-		}
-		page, err := strconv.Atoi(params.Get("page"))
-		if err != nil {
-			return nil, transport.ErrInvalidRequest
-		}
-		req := &api.IdentityListRequest{
-			Page:    page,
-			PerPage: perPage,
-			SortBy:  sortBy,
-		}
-		if err := validateRequest(req); err != nil {
-			return "", err
-		}
-		return m.IdentityList(req)
-	}
-}
-
 //MakeOrderListEndpoint -
 func MakeOrderListEndpoint(m service.Service) endpoint.Endpoint {
 	return func(ctx context.Context, request interface{}) (response interface{}, err error) {
diff --git a/pkg/identity/identity.go b/pkg/identity/identity.go
index edbba97..6e94c05 100644
--- a/pkg/identity/identity.go
+++ b/pkg/identity/identity.go
@@ -21,78 +21,101 @@ Package identity - manage Identity document and keys
 package identity
 
 import (
-	"encoding/hex"
+	"bytes"
 	"time"
 
-	"github.com/apache/incubator-milagro-dta/libs/crypto"
 	"github.com/apache/incubator-milagro-dta/libs/cryptowallet"
-	"github.com/apache/incubator-milagro-dta/libs/datastore"
 	"github.com/apache/incubator-milagro-dta/libs/documents"
 	"github.com/apache/incubator-milagro-dta/libs/ipfs"
-	"github.com/apache/incubator-milagro-dta/pkg/common"
+	"github.com/apache/incubator-milagro-dta/libs/keystore"
 	"github.com/pkg/errors"
 )
 
 // CreateIdentity creates a new identity
-// returns Identity secrets and Identity document
-func CreateIdentity(name string, ipfsConn ipfs.Connector, store *datastore.Store) (idDocumentCID string, err error) {
+// returns Identity document and secret
+func CreateIdentity(name string) (idDocument *documents.IDDoc, rawIDDoc, seed []byte, err error) {
 	//generate crypto random seed
-	seed, err := cryptowallet.RandomBytes(48)
+	seed, err = cryptowallet.RandomBytes(48)
 	if err != nil {
 		err = errors.Wrap(err, "Failed to generate random seed")
 		return
 	}
 
-	//Generate SIKE keys
-	rc1, sikePublicKey, sikeSecretKey := crypto.SIKEKeys(seed)
-	if rc1 != 0 {
-		err = errors.New("Failed to generate SIKE keys")
+	sikePublicKey, _, err := GenerateSIKEKeys(seed)
+	if err != nil {
 		return
 	}
 
-	//Generate BLS keys
-	rc1, blsPublicKey, blsSecretKey := crypto.BLSKeys(seed, nil)
-	if rc1 != 0 {
-		err = errors.New("Failed to generate BLS keys")
+	blsPublicKey, blsSecretKey, err := GenerateBLSKeys(seed)
+	if err != nil {
 		return
 	}
 
-	ecPubKey, err := common.InitECKeys(seed)
+	ecPublicKey, err := GenerateECPublicKey(seed)
 	if err != nil {
-		err = errors.Wrap(err, "Failed to generate EC Public Key")
 		return
 	}
 
-	//build ID Doc
-	idDocument := documents.NewIDDoc()
+	// build ID Doc
+	idDocument = documents.NewIDDoc()
 	idDocument.AuthenticationReference = name
-	idDocument.BeneficiaryECPublicKey = ecPubKey
+	idDocument.BeneficiaryECPublicKey = ecPublicKey
 	idDocument.SikePublicKey = sikePublicKey
 	idDocument.BLSPublicKey = blsPublicKey
 	idDocument.Timestamp = time.Now().Unix()
 
-	rawIDDoc, err := documents.EncodeIDDocument(idDocument, blsSecretKey)
+	// encode ID Doc
+	rawIDDoc, err = documents.EncodeIDDocument(idDocument, blsSecretKey)
 	if err != nil {
 		err = errors.Wrap(err, "Failed to encode IDDocument")
 		return
 	}
 
+	return
+}
+
+// StoreIdentity writes IDDocument to IPFS and secret to keystore
+func StoreIdentity(rawIDDoc, secret []byte, ipfsConn ipfs.Connector, store keystore.Store) (idDocumentCID string, err error) {
+	// add ID Doc to IPFS
 	idDocumentCID, err = ipfsConn.Add(rawIDDoc)
+	if err != nil {
+		return
+	}
+	// store the seed
+	err = store.Set("seed", secret)
+	return
+}
+
+// CheckIdentity verifies the IDDocument
+func CheckIdentity(id, name string, ipfsConn ipfs.Connector, store keystore.Store) error {
 
-	secrets := common.IdentitySecrets{
-		Name:          name,
-		Seed:          hex.EncodeToString(seed),
-		BLSSecretKey:  hex.EncodeToString(blsSecretKey),
-		SikeSecretKey: hex.EncodeToString(sikeSecretKey),
+	rawIDDoc, err := ipfsConn.Get(id)
+	if err != nil {
+		return errors.Wrap(err, "ID Document not found")
+	}
+
+	idDoc := &documents.IDDoc{}
+	if err := documents.DecodeIDDocument(rawIDDoc, id, idDoc); err != nil {
+		return errors.Wrap(err, "Decode ID document")
+	}
+
+	if idDoc.AuthenticationReference != name {
+		return errors.New("Name doesn't match the authentication reference")
 	}
 
-	if store != nil {
-		err = store.Set("id-doc", idDocumentCID, secrets, map[string]string{"time": time.Now().UTC().Format(time.RFC3339)})
-		if err != nil {
-			err = errors.Wrap(err, "Failed to store ID Document")
-			return
-		}
+	seed, err := store.Get("seed")
+	if err != nil {
+		return errors.Wrap(err, "Seed not found")
+	}
+
+	sikePublic, _, err := GenerateSIKEKeys(seed)
+	if !bytes.Equal(idDoc.SikePublicKey, sikePublic) {
+		return errors.New("SIKE keys are different")
+	}
+	blsPublic, _, err := GenerateBLSKeys(seed)
+	if !bytes.Equal(idDoc.BLSPublicKey, blsPublic) {
+		return errors.New("BLS keys are different")
 	}
 
-	return idDocumentCID, nil
+	return nil
 }
diff --git a/libs/keystore/memorystore_test.go b/pkg/identity/identity_test.go
similarity index 63%
copy from libs/keystore/memorystore_test.go
copy to pkg/identity/identity_test.go
index 5dd92a2..fdbed83 100644
--- a/libs/keystore/memorystore_test.go
+++ b/pkg/identity/identity_test.go
@@ -15,32 +15,33 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package keystore
+package identity
 
 import (
-	"bytes"
 	"testing"
+
+	"github.com/apache/incubator-milagro-dta/libs/ipfs"
+	"github.com/apache/incubator-milagro-dta/libs/keystore"
 )
 
-func TestMemoryStore(t *testing.T) {
-	keys := map[string][]byte{"key1": []byte{1}, "key2": []byte{1, 2}, "key3": []byte{1, 2, 3}}
+func TestCreateIdentity(t *testing.T) {
 
-	ms, err := NewMemoryStore()
+	ipfsNode, err := ipfs.NewMemoryConnector()
 	if err != nil {
 		t.Fatal(err)
 	}
-	for k, v := range keys {
-		ms.Set(k, v)
+
+	store, _ := keystore.NewMemoryStore()
+
+	_, rawIDDoc, secret, err := CreateIdentity("test")
+	if err != nil {
+		t.Fatal(err)
 	}
 
-	for name, v := range keys {
-		key, err := ms.Get(name)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if !bytes.Equal(v, key) {
-			t.Errorf("Key not match: %v. Expected: %v, Found: %v", name, v, key)
-		}
+	idDocID, err := StoreIdentity(rawIDDoc, secret, ipfsNode, store)
 
+	if err := CheckIdentity(idDocID, "test", ipfsNode, store); err != nil {
+		t.Fatal(err)
 	}
+
 }
diff --git a/pkg/identity/keys.go b/pkg/identity/keys.go
new file mode 100644
index 0000000..276b157
--- /dev/null
+++ b/pkg/identity/keys.go
@@ -0,0 +1,63 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package identity
+
+import (
+	"fmt"
+
+	"github.com/apache/incubator-milagro-dta/libs/crypto"
+	"github.com/apache/incubator-milagro-dta/libs/cryptowallet"
+	"github.com/pkg/errors"
+)
+
+// Secrets - keys required for decryption and signing
+type Secrets struct {
+	Seed          []byte
+	SikeSecretKey []byte
+	BLSSecretKey  []byte
+}
+
+// GenerateBLSKeys generate BLS keys from seed
+func GenerateBLSKeys(seed []byte) (blsPublic, blsSecret []byte, err error) {
+	rc1, blsPublic, blsSecret := crypto.BLSKeys(seed, nil)
+	if rc1 != 0 {
+		err = fmt.Errorf("Failed to generate BLS keys: %v", rc1)
+	}
+	return
+}
+
+// GenerateSIKEKeys generate SIKE keys from seed
+func GenerateSIKEKeys(seed []byte) (sikePublic, sikeSecret []byte, err error) {
+	rc1, sikePublic, sikeSecret := crypto.SIKEKeys(seed)
+	if rc1 != 0 {
+		err = fmt.Errorf("Failed to generate SIKE keys: %v", rc1)
+	}
+	return
+}
+
+// GenerateECPublicKey - generate EC keys using BIP44 HD Wallets (as bitcoin) from seed
+func GenerateECPublicKey(seed []byte) (ecPublic []byte, err error) {
+	//EC ADD Keypair Protocol
+	_, pubKeyECADD, _, err := cryptowallet.Bip44Address(seed, cryptowallet.CoinTypeBitcoinMain, 0, 0, 0)
+	if err != nil {
+		err = errors.Wrap(err, "Failed to derive EC HD Wallet Key")
+		return
+	}
+
+	return pubKeyECADD.SerializeCompressed(), nil
+}
diff --git a/pkg/service/service.go b/pkg/service/service.go
index 0121994..f0ed3d4 100644
--- a/pkg/service/service.go
+++ b/pkg/service/service.go
@@ -27,11 +27,6 @@ import (
 
 // Service is the CustodyService interface
 type Service interface {
-	//Identity
-	CreateIdentity(req *api.CreateIdentityRequest) (*api.CreateIdentityResponse, error)
-	GetIdentity(req *api.GetIdentityRequest) (*api.GetIdentityResponse, error)
-	IdentityList(req *api.IdentityListRequest) (*api.IdentityListResponse, error)
-
 	//Order
 	GetOrder(req *api.GetOrderRequest) (*api.GetOrderResponse, error)
 	OrderList(req *api.OrderListRequest) (*api.OrderListResponse, error)


[incubator-milagro-dta] 02/03: KeyStore interface to keep secrets

Posted by sm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

smihaylov pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-dta.git

commit dffff97e82de8d7dcf701a8687d622bc7856d55d
Author: Stanislav Mihaylov <sm...@gmail.com>
AuthorDate: Wed Sep 25 11:06:40 2019 +0300

    KeyStore interface to keep secrets
    
    File KeyStore implementation to keep secrets in a json file
---
 libs/keystore/filestore.go        | 111 ++++++++++++++++++++++++++++++++++++++
 libs/keystore/filestore_test.go   |  85 +++++++++++++++++++++++++++++
 libs/keystore/keystore.go         |  36 +++++++++++++
 libs/keystore/memorystore.go      |  59 ++++++++++++++++++++
 libs/keystore/memorystore_test.go |  46 ++++++++++++++++
 5 files changed, 337 insertions(+)

diff --git a/libs/keystore/filestore.go b/libs/keystore/filestore.go
new file mode 100644
index 0000000..5491563
--- /dev/null
+++ b/libs/keystore/filestore.go
@@ -0,0 +1,111 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package keystore
+
+import (
+	"encoding/json"
+	"io/ioutil"
+	"os"
+	"sync"
+
+	"github.com/pkg/errors"
+)
+
+// FileStore is the key Store implementation storing the keys in a file
+type FileStore struct {
+	sync.RWMutex
+	filePath string
+	keys     map[string][]byte
+}
+
+// NewFileStore creates a new FileStore
+func NewFileStore(filePath string) (Store, error) {
+	fs := &FileStore{
+		filePath: filePath,
+		keys:     map[string][]byte{},
+	}
+
+	if err := fs.loadKeys(); err != nil {
+		return nil, err
+	}
+
+	return fs, nil
+}
+
+// Set stores multiple keys at once
+func (f *FileStore) Set(name string, key []byte) error {
+	f.Lock()
+	defer f.Unlock()
+
+	f.keys[name] = make([]byte, len(key))
+	copy(f.keys[name], key)
+
+	return f.storeKeys()
+}
+
+// Get retrieves multiple keys
+func (f *FileStore) Get(name string) ([]byte, error) {
+	f.RLock()
+	defer f.RUnlock()
+
+	key, ok := f.keys[name]
+	if !ok {
+		return nil, ErrKeyNotFound
+	}
+
+	return key, nil
+}
+
+// TODO: Lock the file
+
+func (f *FileStore) loadKeys() error {
+	rawKeys, err := ioutil.ReadFile(f.filePath)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return nil
+		}
+		return errors.Wrap(err, "Load keys")
+	}
+
+	return json.Unmarshal(rawKeys, &(f).keys)
+}
+
+func (f *FileStore) storeKeys() error {
+	rawKeys, err := json.Marshal(f.keys)
+	if err != nil {
+		return err
+	}
+
+	// Get the file permissions
+	var perm os.FileMode
+	fi, err := os.Stat(f.filePath)
+	if err != nil {
+		if !os.IsNotExist(err) {
+			return errors.Wrap(err, "Get key file permissions")
+		}
+		perm = 0600
+	} else {
+		perm = fi.Mode().Perm()
+	}
+
+	if err := ioutil.WriteFile(f.filePath, rawKeys, perm); err != nil {
+		return errors.Wrap(err, "Store keys")
+	}
+
+	return nil
+}
diff --git a/libs/keystore/filestore_test.go b/libs/keystore/filestore_test.go
new file mode 100644
index 0000000..7e946dd
--- /dev/null
+++ b/libs/keystore/filestore_test.go
@@ -0,0 +1,85 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package keystore
+
+import (
+	"bytes"
+	"crypto/rand"
+	"fmt"
+	"os"
+	"path/filepath"
+	"testing"
+	"time"
+)
+
+func TestFileStore(t *testing.T) {
+	keys := map[string][]byte{"key1": []byte{1}, "key2": []byte{1, 2}, "key3": []byte{1, 2, 3}}
+
+	fn := tmpFileName()
+	defer func() {
+		if err := os.Remove(fn); err != nil {
+			t.Logf("Warning! Temp file could not be deleted (%v): %v", err, fn)
+		}
+	}()
+
+	fs, err := NewFileStore(fn)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Set keys
+	for k, v := range keys {
+		fs.Set(k, v)
+	}
+
+	// Get Keys
+	for name, v := range keys {
+		key, err := fs.Get(name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !bytes.Equal(v, key) {
+			t.Errorf("Key not match: %v. Expected: %v, Found: %v", name, v, key)
+		}
+
+	}
+
+	fs1, err := NewFileStore(fn)
+	if err != nil {
+		t.Fatal(err)
+	}
+	// Get Keys
+	for name, v := range keys {
+		key, err := fs1.Get(name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !bytes.Equal(v, key) {
+			t.Errorf("Key not match: %v. Expected: %v, Found: %v", name, v, key)
+		}
+
+	}
+}
+
+func tmpFileName() string {
+	rnd := make([]byte, 8)
+	rand.Read(rnd)
+	ts := time.Now().UnixNano()
+
+	return filepath.Join(os.TempDir(), fmt.Sprintf("keystore-%v-%x.tmp", ts, rnd))
+}
diff --git a/libs/keystore/keystore.go b/libs/keystore/keystore.go
new file mode 100644
index 0000000..8b321c7
--- /dev/null
+++ b/libs/keystore/keystore.go
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+/*
+Package keystore - keep secrets
+*/
+package keystore
+
+import "github.com/pkg/errors"
+
+var (
+	// ErrKeyNotFound is returned when a key is not found in the store
+	ErrKeyNotFound = errors.New("Key not found")
+)
+
+// Store is the keystore interface
+type Store interface {
+	// Set stores multiple keys at once
+	Set(name string, key []byte) error
+	// Get retrieves multiple keys
+	Get(name string) ([]byte, error)
+}
diff --git a/libs/keystore/memorystore.go b/libs/keystore/memorystore.go
new file mode 100644
index 0000000..484a45f
--- /dev/null
+++ b/libs/keystore/memorystore.go
@@ -0,0 +1,59 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package keystore
+
+import (
+	"sync"
+)
+
+// MemoryStore is the in-memory implementation of key store
+type MemoryStore struct {
+	sync.RWMutex
+	keys map[string][]byte
+}
+
+// NewMemoryStore creates a new MemoryStore
+func NewMemoryStore() (Store, error) {
+	return &MemoryStore{
+		keys: map[string][]byte{},
+	}, nil
+}
+
+// Set stores multiple keys at once
+func (f *MemoryStore) Set(name string, key []byte) error {
+	f.Lock()
+	defer f.Unlock()
+
+	f.keys[name] = make([]byte, len(key))
+	copy(f.keys[name], key)
+
+	return nil
+}
+
+// Get retrieves multiple keys
+func (f *MemoryStore) Get(name string) ([]byte, error) {
+	f.RLock()
+	defer f.RUnlock()
+
+	key, ok := f.keys[name]
+	if !ok {
+		return nil, ErrKeyNotFound
+	}
+
+	return key, nil
+}
diff --git a/libs/keystore/memorystore_test.go b/libs/keystore/memorystore_test.go
new file mode 100644
index 0000000..5dd92a2
--- /dev/null
+++ b/libs/keystore/memorystore_test.go
@@ -0,0 +1,46 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package keystore
+
+import (
+	"bytes"
+	"testing"
+)
+
+func TestMemoryStore(t *testing.T) {
+	keys := map[string][]byte{"key1": []byte{1}, "key2": []byte{1, 2}, "key3": []byte{1, 2, 3}}
+
+	ms, err := NewMemoryStore()
+	if err != nil {
+		t.Fatal(err)
+	}
+	for k, v := range keys {
+		ms.Set(k, v)
+	}
+
+	for name, v := range keys {
+		key, err := ms.Get(name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !bytes.Equal(v, key) {
+			t.Errorf("Key not match: %v. Expected: %v, Found: %v", name, v, key)
+		}
+
+	}
+}