Skip to content
Snippets Groups Projects
Commit b6bb1336 authored by Richard T. Carback III's avatar Richard T. Carback III
Browse files

Add SIDH util functions with some corresponding tests

parent a16cd8d8
No related branches found
No related tags found
2 merge requests!117Release,!73Quantum secure xx messenger key negotiation
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)
}
///////////////////////////////////////////////////////////////////////////////
// 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)
}
///////////////////////////////////////////////////////////////////////////////
// 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()
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment