mirror of https://github.com/certusone/dc4bc.git
WIP
This commit is contained in:
parent
3db687fbeb
commit
f508750a30
|
@ -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)
|
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 {
|
if err != nil && err != leveldb.ErrNotFound {
|
||||||
return nil, fmt.Errorf("failed to load keys from db %s: %w", dbPath, err)
|
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.secKey = am.suite.Scalar().Pick(am.suite.RandomStream())
|
||||||
am.pubKey = am.suite.Point().Mul(am.secKey, nil)
|
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 {
|
if err = am.loadAddressFromDB(dbPath); err != nil {
|
||||||
|
@ -95,13 +95,13 @@ func (am *AirgappedMachine) GetAddress() string {
|
||||||
return am.ParticipantAddress
|
return am.ParticipantAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *AirgappedMachine) loadKeysFromDB(dbPath string) error {
|
func (am *AirgappedMachine) LoadKeysFromDB() error {
|
||||||
pubKeyBz, err := am.db.Get([]byte(pubKeyDBKey), nil)
|
pubKeyBz, err := am.db.Get([]byte(pubKeyDBKey), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == leveldb.ErrNotFound {
|
if err == leveldb.ErrNotFound {
|
||||||
return err
|
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)
|
privateKeyBz, err := am.db.Get([]byte(privateKeyDBKey), nil)
|
||||||
|
@ -109,7 +109,7 @@ func (am *AirgappedMachine) loadKeysFromDB(dbPath string) error {
|
||||||
if err == leveldb.ErrNotFound {
|
if err == leveldb.ErrNotFound {
|
||||||
return err
|
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()
|
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)
|
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()
|
pubKeyBz, err := am.pubKey.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -153,20 +153,20 @@ func (am *AirgappedMachine) saveKeysToDB(dbPath string) error {
|
||||||
|
|
||||||
tx, err := am.db.OpenTransaction()
|
tx, err := am.db.OpenTransaction()
|
||||||
if err != nil {
|
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()
|
defer tx.Discard()
|
||||||
|
|
||||||
if err = tx.Put([]byte(pubKeyDBKey), pubKeyBz, nil); err != nil {
|
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 {
|
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 {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ func (am *AirgappedMachine) getParticipantID(dkgIdentifier string) (int, error)
|
||||||
return dkgInstance.ParticipantID, nil
|
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]
|
dkgInstance, ok := am.dkgInstances[dkgIdentifier]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("invalid dkg identifier: %s", dkgIdentifier)
|
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
|
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)
|
decryptedData, err := ecies.Decrypt(am.suite, am.secKey, data, am.suite.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to decrypt data: %w", err)
|
return nil, fmt.Errorf("failed to decrypt data: %w", err)
|
||||||
|
|
|
@ -177,7 +177,7 @@ func (am *AirgappedMachine) handleStateDkgDealsAwaitConfirmations(o *client.Oper
|
||||||
return fmt.Errorf("failed to marshal deal: %w", err)
|
return fmt.Errorf("failed to marshal deal: %w", err)
|
||||||
}
|
}
|
||||||
toParticipant := dkgInstance.GetParticipantByIndex(index)
|
toParticipant := dkgInstance.GetParticipantByIndex(index)
|
||||||
encryptedDeal, err := am.encryptData(o.DKGIdentifier, toParticipant, dealBz)
|
encryptedDeal, err := am.encryptDataForParticipant(o.DKGIdentifier, toParticipant, dealBz)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to encrypt deal: %w", err)
|
return fmt.Errorf("failed to encrypt deal: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ func (am *AirgappedMachine) handleStateDkgResponsesAwaitConfirmations(o *client.
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, entry := range payload {
|
for _, entry := range payload {
|
||||||
decryptedDealBz, err := am.decryptData(entry.DkgDeal)
|
decryptedDealBz, err := am.decryptDataFromParticipant(entry.DkgDeal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to decrypt deal: %w", err)
|
return fmt.Errorf("failed to decrypt deal: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue