From f508750a30480e316259215e50bfe569918ad567 Mon Sep 17 00:00:00 2001 From: programmer10110 Date: Thu, 17 Sep 2020 15:03:10 +0300 Subject: [PATCH] WIP --- airgapped/airgapped.go | 24 ++++++++++---------- airgapped/dkg.go | 4 ++-- airgapped/encryption.go | 50 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 airgapped/encryption.go diff --git a/airgapped/airgapped.go b/airgapped/airgapped.go index bfe1968..9ae5571 100644 --- a/airgapped/airgapped.go +++ b/airgapped/airgapped.go @@ -67,7 +67,7 @@ func NewAirgappedMachine(dbPath string) (*AirgappedMachine, error) { return nil, fmt.Errorf("failed to open db file %s for keys: %w", dbPath, err) } - err = am.loadKeysFromDB(dbPath) + err = am.LoadKeysFromDB() if err != nil && err != leveldb.ErrNotFound { return nil, fmt.Errorf("failed to load keys from db %s: %w", dbPath, err) } @@ -76,7 +76,7 @@ func NewAirgappedMachine(dbPath string) (*AirgappedMachine, error) { am.secKey = am.suite.Scalar().Pick(am.suite.RandomStream()) am.pubKey = am.suite.Point().Mul(am.secKey, nil) - return am, am.saveKeysToDB(dbPath) + return am, am.SaveKeysToDB() } if err = am.loadAddressFromDB(dbPath); err != nil { @@ -95,13 +95,13 @@ func (am *AirgappedMachine) GetAddress() string { return am.ParticipantAddress } -func (am *AirgappedMachine) loadKeysFromDB(dbPath string) error { +func (am *AirgappedMachine) LoadKeysFromDB() error { pubKeyBz, err := am.db.Get([]byte(pubKeyDBKey), nil) if err != nil { if err == leveldb.ErrNotFound { return err } - return fmt.Errorf("failed to get public key from db %s: %w", dbPath, err) + return fmt.Errorf("failed to get public key from db: %w", err) } privateKeyBz, err := am.db.Get([]byte(privateKeyDBKey), nil) @@ -109,7 +109,7 @@ func (am *AirgappedMachine) loadKeysFromDB(dbPath string) error { if err == leveldb.ErrNotFound { return err } - return fmt.Errorf("failed to get private key from db %s: %w", dbPath, err) + return fmt.Errorf("failed to get private key from db: %w", err) } am.pubKey = am.suite.Point() @@ -140,7 +140,7 @@ func (am *AirgappedMachine) saveAddressToDB(address string) error { return am.db.Put([]byte(participantAddressKey), []byte(address), nil) } -func (am *AirgappedMachine) saveKeysToDB(dbPath string) error { +func (am *AirgappedMachine) SaveKeysToDB() error { pubKeyBz, err := am.pubKey.MarshalBinary() if err != nil { @@ -153,20 +153,20 @@ func (am *AirgappedMachine) saveKeysToDB(dbPath string) error { tx, err := am.db.OpenTransaction() if err != nil { - return fmt.Errorf("failed to open transcation for db %s: %w", dbPath, err) + return fmt.Errorf("failed to open transcation for db: %w", err) } defer tx.Discard() if err = tx.Put([]byte(pubKeyDBKey), pubKeyBz, nil); err != nil { - return fmt.Errorf("failed to put pub key into db %s: %w", dbPath, err) + return fmt.Errorf("failed to put pub key into db: %w", err) } if err = tx.Put([]byte(privateKeyDBKey), privateKeyBz, nil); err != nil { - return fmt.Errorf("failed to put private key into db %s: %w", dbPath, err) + return fmt.Errorf("failed to put private key into db: %w", err) } if err = tx.Commit(); err != nil { - return fmt.Errorf("failed to commit tx for saving keys into db %s: %w", dbPath, err) + return fmt.Errorf("failed to commit tx for saving keys into db: %w", err) } return nil } @@ -179,7 +179,7 @@ func (am *AirgappedMachine) getParticipantID(dkgIdentifier string) (int, error) return dkgInstance.ParticipantID, nil } -func (am *AirgappedMachine) encryptData(dkgIdentifier, to string, data []byte) ([]byte, error) { +func (am *AirgappedMachine) encryptDataForParticipant(dkgIdentifier, to string, data []byte) ([]byte, error) { dkgInstance, ok := am.dkgInstances[dkgIdentifier] if !ok { return nil, fmt.Errorf("invalid dkg identifier: %s", dkgIdentifier) @@ -197,7 +197,7 @@ func (am *AirgappedMachine) encryptData(dkgIdentifier, to string, data []byte) ( return encryptedData, nil } -func (am *AirgappedMachine) decryptData(data []byte) ([]byte, error) { +func (am *AirgappedMachine) decryptDataFromParticipant(data []byte) ([]byte, error) { decryptedData, err := ecies.Decrypt(am.suite, am.secKey, data, am.suite.Hash) if err != nil { return nil, fmt.Errorf("failed to decrypt data: %w", err) diff --git a/airgapped/dkg.go b/airgapped/dkg.go index fb93124..233b169 100644 --- a/airgapped/dkg.go +++ b/airgapped/dkg.go @@ -177,7 +177,7 @@ func (am *AirgappedMachine) handleStateDkgDealsAwaitConfirmations(o *client.Oper return fmt.Errorf("failed to marshal deal: %w", err) } toParticipant := dkgInstance.GetParticipantByIndex(index) - encryptedDeal, err := am.encryptData(o.DKGIdentifier, toParticipant, dealBz) + encryptedDeal, err := am.encryptDataForParticipant(o.DKGIdentifier, toParticipant, dealBz) if err != nil { return fmt.Errorf("failed to encrypt deal: %w", err) } @@ -213,7 +213,7 @@ func (am *AirgappedMachine) handleStateDkgResponsesAwaitConfirmations(o *client. } for _, entry := range payload { - decryptedDealBz, err := am.decryptData(entry.DkgDeal) + decryptedDealBz, err := am.decryptDataFromParticipant(entry.DkgDeal) if err != nil { return fmt.Errorf("failed to decrypt deal: %w", err) } diff --git a/airgapped/encryption.go b/airgapped/encryption.go new file mode 100644 index 0000000..05a1bd7 --- /dev/null +++ b/airgapped/encryption.go @@ -0,0 +1,50 @@ +package airgapped + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "fmt" + "golang.org/x/crypto/scrypt" + "io" +) + +func encrypt(key, data []byte) ([]byte, error) { + //TODO: salt + derivedKey, err := scrypt.Key(key, nil, 32768, 8, 1, 32) + block, err := aes.NewCipher(derivedKey) + if err != nil { + return nil, err + } + + cipherData := make([]byte, aes.BlockSize+len(data)) + iv := cipherData[:aes.BlockSize] + if _, err = io.ReadFull(rand.Reader, iv); err != nil { + return nil, err + } + + stream := cipher.NewCFBEncrypter(block, iv) + stream.XORKeyStream(cipherData[aes.BlockSize:], data) + return cipherData, nil +} + +func decrypt(key, data []byte) ([]byte, error) { + //TODO: salt + derivedKey, err := scrypt.Key(key, nil, 32768, 8, 1, 32) + block, err := aes.NewCipher(derivedKey) + if err != nil { + return nil, err + } + + if len(data) < aes.BlockSize { + return nil, fmt.Errorf("ciphertext block size is too short") + } + + iv := data[:aes.BlockSize] + data = data[aes.BlockSize:] + + stream := cipher.NewCFBDecrypter(block, iv) + stream.XORKeyStream(data, data) + + return data, nil +}