From b6bb1336d1cc92b12d215a78df7d7f8cf4682e8f Mon Sep 17 00:00:00 2001 From: "Richard T. Carback III" <rick.carback@gmail.com> Date: Fri, 3 Dec 2021 17:48:41 +0000 Subject: [PATCH] Add SIDH util functions with some corresponding tests --- storage/utility/sidH.go | 45 ----------- storage/utility/sidh.go | 149 +++++++++++++++++++++++++++++++++++ storage/utility/sidh_test.go | 146 ++++++++++++++++++++++++++++++++++ 3 files changed, 295 insertions(+), 45 deletions(-) delete mode 100644 storage/utility/sidH.go create mode 100644 storage/utility/sidh.go create mode 100644 storage/utility/sidh_test.go diff --git a/storage/utility/sidH.go b/storage/utility/sidH.go deleted file mode 100644 index 85a23c9cb..000000000 --- a/storage/utility/sidH.go +++ /dev/null @@ -1,45 +0,0 @@ -package utility - -import ( - "fmt" - "github.com/cloudflare/circl/dh/sidh" - sidhinterface "gitlab.com/elixxir/client/interfaces/sidh" - "gitlab.com/elixxir/client/storage/versioned" - "gitlab.com/xx_network/primitives/id" - "gitlab.com/xx_network/primitives/netTime" -) - -const currentSidHPubKeyAVersion = 0 - -func StoreSidHPubKeyA(kv *versioned.KV, id *id.ID, sidH *sidh.PublicKey) error { - now := netTime.Now() - - sidHBytes := make([]byte, sidH.Size()) - sidH.Export(sidHBytes) - - obj := versioned.Object{ - Version: currentSidHPubKeyAVersion, - Timestamp: now, - Data: sidHBytes, - } - - return kv.Set(makeSidHtKeyA(id), currentSidHPubKeyAVersion, &obj) -} - -func LoadSidHPubKeyA(kv *versioned.KV, cid *id.ID) (*sidh.PublicKey, error) { - vo, err := kv.Get(makeSidHtKeyA(cid), currentSidHPubKeyAVersion) - if err != nil { - return nil, err - } - - sidHPubkey := sidh.NewPublicKey(sidhinterface.SidHKeyId, sidh.KeyVariantSidhA) - return sidHPubkey, sidHPubkey.Import(vo.Data) -} - -func DeleteSidHPubKeyA(kv *versioned.KV, cid *id.ID) error { - return kv.Delete(makeSidHtKeyA(cid), currentSidHPubKeyAVersion) -} - -func makeSidHtKeyA(cid *id.ID) string { - return fmt.Sprintf("SidKPubKeyA:%s", cid) -} diff --git a/storage/utility/sidh.go b/storage/utility/sidh.go new file mode 100644 index 000000000..684b65901 --- /dev/null +++ b/storage/utility/sidh.go @@ -0,0 +1,149 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright © 2020 xx network SEZC // +// // +// Use of this source code is governed by a license that can be found in the // +// LICENSE file // +/////////////////////////////////////////////////////////////////////////////// + +package utility + +import ( + "gitlab.com/elixxir/client/storage/versioned" + "gitlab.com/xx_network/primitives/netTime" + "github.com/cloudflare/circl/dh/sidh" + "encoding/base64" + sidhinterface "gitlab.com/elixxir/client/interfaces/sidh" + "gitlab.com/xx_network/primitives/id" + "fmt" +) + +const currentSIDHVersion = 0 + +// NewSIDHPUblicKey is a helper which returns a proper new SIDH public key +// Right now this is set to Fp434 but it could change. +func NewSIDHPublicKey(variant sidh.KeyVariant) *sidh.PublicKey { + return sidh.NewPublicKey(sidhinterface.KeyId, variant) +} + +// NewSIDHPUblicKey is a helper which returns a proper new SIDH public key +// Right now this is set to Fp434 but it could change. +func NewSIDHPrivateKey(variant sidh.KeyVariant) *sidh.PrivateKey { + return sidh.NewPrivateKey(sidhinterface.KeyId, variant) +} + +// GetSIDHVariant returns the variant opposite the otherVariant +func GetSIDHVariant(otherVariant sidh.KeyVariant) sidh.KeyVariant { + // Note -- this is taken from inside the sidh lib to look for the A flag + if (otherVariant & sidh.KeyVariantSidhA) == sidh.KeyVariantSidhA { + return sidh.KeyVariantSidhB + } + return sidh.KeyVariantSidhA +} + +// String interface impl to dump the contents of the public key as b64 string +func StringSIDHPubKey(k *sidh.PublicKey) string { + kBytes := make([]byte, k.Size()) + k.Export(kBytes) + return base64.StdEncoding.EncodeToString(kBytes) +} + +// String interface to dump the contents of the public key as b64 string +// NOTE: public key, not the private. We don't ever want to drop a +// private key into a log somewhere. +func StringSIDHPrivKey(k *sidh.PrivateKey) string { + pubK := NewSIDHPublicKey(k.Variant()) + k.GeneratePublicKey(pubK) + return StringSIDHPubKey(pubK) +} + + + +//// +// Public Key Storage utility functions +//// + +const currentSIDHPubKeyVersion = 0 + +// StoreSIDHPubKeyA is a helper to store the requestor public key (which is +// always of type A) +func StoreSIDHPublicKey(kv *versioned.KV, sidH *sidh.PublicKey, key string) error { + now := netTime.Now() + + sidHBytes := make([]byte, sidH.Size()+1) + sidHBytes[0] = byte(sidH.Variant()) + sidH.Export(sidHBytes[1:]) + + obj := versioned.Object{ + Version: currentSIDHPubKeyVersion, + Timestamp: now, + Data: sidHBytes, + } + + return kv.Set(key, currentSIDHPubKeyVersion, &obj) +} + +// LoadSIDHPubKeyA loads a public key from storage. +func LoadSIDHPublicKey(kv *versioned.KV, key string) (*sidh.PublicKey, error) { + vo, err := kv.Get(key, currentSIDHPubKeyVersion) + if err != nil { + return nil, err + } + + variant := sidh.KeyVariant(vo.Data[0]) + sidHPubkey := NewSIDHPublicKey(variant) + return sidHPubkey, sidHPubkey.Import(vo.Data[1:]) +} + +// DeleteSIDHPubKey removes the key from the store +func DeleteSIDHPublicKey(kv *versioned.KV, key string) error { + return kv.Delete(key, currentSIDHPubKeyVersion) +} + +func makeSIDHPublicKey(cid *id.ID) string { + return fmt.Sprintf("SIDHPubKey:%s", cid) +} + +//// +// Private Key Storage utility functions +//// + +const currentSIDHPrivKeyVersion = 0 + +// StoreSIDHPrivateKeyA is a helper to store the requestor public key (which is +// always of type A) +func StoreSIDHPrivateKey(kv *versioned.KV, sidH *sidh.PrivateKey, key string) error { + now := netTime.Now() + + sidHBytes := make([]byte, sidH.Size()+1) + sidHBytes[0] = byte(sidH.Variant()) + sidH.Export(sidHBytes[1:]) + + obj := versioned.Object{ + Version: currentSIDHPrivKeyVersion, + Timestamp: now, + Data: sidHBytes, + } + + return kv.Set(key, currentSIDHPrivKeyVersion, &obj) +} + +// LoadSIDHPrivateKeyA loads a public key from storage. +func LoadSIDHPrivateKey(kv *versioned.KV, key string) (*sidh.PrivateKey, error) { + vo, err := kv.Get(key, currentSIDHPrivKeyVersion) + if err != nil { + return nil, err + } + + variant := sidh.KeyVariant(vo.Data[0]) + sidHPrivkey := NewSIDHPrivateKey(variant) + return sidHPrivkey, sidHPrivkey.Import(vo.Data[1:]) +} + +// DeleteSIDHPrivateKey removes the key from the store +func DeleteSIDHPrivateKey(kv *versioned.KV, key string) error { + return kv.Delete(key, currentSIDHPrivKeyVersion) +} + +func makeSIDHPrivateKey(cid *id.ID) string { + return fmt.Sprintf("SIDHPrivKey:%s", cid) +} diff --git a/storage/utility/sidh_test.go b/storage/utility/sidh_test.go new file mode 100644 index 000000000..f2245cd86 --- /dev/null +++ b/storage/utility/sidh_test.go @@ -0,0 +1,146 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright © 2020 xx network SEZC // +// // +// Use of this source code is governed by a license that can be found in the // +// LICENSE file // +/////////////////////////////////////////////////////////////////////////////// + +package utility + +import ( + "gitlab.com/elixxir/client/storage/versioned" + "gitlab.com/xx_network/crypto/csprng" + "gitlab.com/elixxir/crypto/fastRNG" + "gitlab.com/elixxir/ekv" + "testing" + "github.com/cloudflare/circl/dh/sidh" +) + +// TestStoreLoadDeleteSIDHPublicKey tests the load/store/delete functions +// for SIDH Public Keys +func TestStoreLoadDeleteSIDHPublicKey(t *testing.T) { + kv := make(ekv.Memstore) + vkv := versioned.NewKV(kv) + rng := fastRNG.NewStreamGenerator(1, 3, csprng.NewSystemRNG) + myRng := rng.GetStream() + x1 := NewSIDHPublicKey(sidh.KeyVariantSidhA) + p1 := NewSIDHPrivateKey(sidh.KeyVariantSidhA) + p1.Generate(myRng) + p1.GeneratePublicKey(x1) + + k1 := "testKey1" + err := StoreSIDHPublicKey(vkv, x1, k1) + if err != nil { + t.Errorf("Failed to store key: %+v", err) + } + loaded1, err := LoadSIDHPublicKey(vkv, k1) + if err != nil { + t.Errorf("Failed to load key: %+v", err) + } + if StringSIDHPubKey(x1) != StringSIDHPubKey(loaded1) { + t.Errorf("Stored key did not match loaded:\n\t%s\n\t%s\n", + StringSIDHPubKey(x1), StringSIDHPubKey(loaded1)) + } + err = DeleteSIDHPublicKey(vkv, k1) + if err != nil { + t.Fatalf("DeleteSIDHPublicKey returned an error: %v", err) + } + _, err = LoadSIDHPublicKey(vkv, k1) + if err == nil { + t.Errorf("Should not load deleted key: %+v", err) + } + + // Now do the same for Type B keys + + x2 := NewSIDHPublicKey(sidh.KeyVariantSidhB) + p2 := NewSIDHPrivateKey(sidh.KeyVariantSidhB) + p2.Generate(myRng) + p2.GeneratePublicKey(x2) + + k2 := "testKey2" + err = StoreSIDHPublicKey(vkv, x2, k2) + if err != nil { + t.Errorf("Failed to store key: %+v", err) + } + loaded2, err := LoadSIDHPublicKey(vkv, k2) + if err != nil { + t.Errorf("Failed to load key: %+v", err) + } + if StringSIDHPubKey(x2) != StringSIDHPubKey(loaded2) { + t.Errorf("Stored key did not match loaded:\n\t%s\n\t%s\n", + StringSIDHPubKey(x2), StringSIDHPubKey(loaded2)) + } + err = DeleteSIDHPublicKey(vkv, k2) + if err != nil { + t.Fatalf("DeleteSIDHPublicKey returned an error: %v", err) + } + _, err = LoadSIDHPublicKey(vkv, k2) + if err == nil { + t.Errorf("Should not load deleted key: %+v", err) + } + + myRng.Close() +} + + +// TestStoreLoadDeleteSIDHPublicKey tests the load/store/delete functions +// for SIDH Private Keys +func TestStoreLoadDeleteSIDHPrivateKey(t *testing.T) { + kv := make(ekv.Memstore) + vkv := versioned.NewKV(kv) + rng := fastRNG.NewStreamGenerator(1, 3, csprng.NewSystemRNG) + myRng := rng.GetStream() + p1 := NewSIDHPrivateKey(sidh.KeyVariantSidhA) + p1.Generate(myRng) + + k1 := "testKey1" + err := StoreSIDHPrivateKey(vkv, p1, k1) + if err != nil { + t.Errorf("Failed to store key: %+v", err) + } + loaded1, err := LoadSIDHPrivateKey(vkv, k1) + if err != nil { + t.Errorf("Failed to load key: %+v", err) + } + if StringSIDHPrivKey(p1) != StringSIDHPrivKey(loaded1) { + t.Errorf("Stored key did not match loaded:\n\t%s\n\t%s\n", + StringSIDHPrivKey(p1), StringSIDHPrivKey(loaded1)) + } + err = DeleteSIDHPrivateKey(vkv, k1) + if err != nil { + t.Fatalf("DeleteSIDHPrivateKey returned an error: %v", err) + } + _, err = LoadSIDHPrivateKey(vkv, k1) + if err == nil { + t.Errorf("Should not load deleted key: %+v", err) + } + + // Now do the same for Type B keys + + p2 := NewSIDHPrivateKey(sidh.KeyVariantSidhB) + p2.Generate(myRng) + + k2 := "testKey2" + err = StoreSIDHPrivateKey(vkv, p2, k2) + if err != nil { + t.Errorf("Failed to store key: %+v", err) + } + loaded2, err := LoadSIDHPrivateKey(vkv, k2) + if err != nil { + t.Errorf("Failed to load key: %+v", err) + } + if StringSIDHPrivKey(p2) != StringSIDHPrivKey(loaded2) { + t.Errorf("Stored key did not match loaded:\n\t%s\n\t%s\n", + StringSIDHPrivKey(p2), StringSIDHPrivKey(loaded2)) + } + err = DeleteSIDHPrivateKey(vkv, k2) + if err != nil { + t.Fatalf("DeleteSIDHPrivateKey returned an error: %v", err) + } + _, err = LoadSIDHPrivateKey(vkv, k2) + if err == nil { + t.Errorf("Should not load deleted key: %+v", err) + } + + myRng.Close() +} -- GitLab