package pseudohsm import ( "fmt" "io/ioutil" "os" "strings" "testing" "github.com/vapor/crypto/ed25519" "github.com/vapor/errors" ) const dirPath = "testdata/pseudo" func TestCreateKeyWithUpperCase(t *testing.T) { hsm, _ := New(dirPath) alias := "UPPER" xpub, _, err := hsm.XCreate(alias, "password", "en") if err != nil { t.Fatal(err) } if xpub.Alias != strings.ToLower(alias) { t.Fatal("the created key alias should be lowercase") } err = hsm.XDelete(xpub.XPub, "password") if err != nil { t.Fatal(err) } } func TestCreateKeyWithWhiteSpaceTrimed(t *testing.T) { hsm, _ := New(dirPath) alias := " with space surrounding " xpub, _, err := hsm.XCreate(alias, "password", "en") if err != nil { t.Fatal(err) } if xpub.Alias != strings.TrimSpace(alias) { t.Fatal("the created key alias should be lowercase") } if err = hsm.XDelete(xpub.XPub, "password"); err != nil { t.Fatal(err) } } func TestUpdateKeyAlias(t *testing.T) { hsm, _ := New(dirPath) oldAlias := "old_alias" newAlias := "new_alias" xpub, _, err := hsm.XCreate(oldAlias, "password", "en") if err != nil { t.Fatal(err) } if xpub.Alias != strings.TrimSpace(oldAlias) { t.Fatal("the created key alias should be lowercase") } if err = hsm.UpdateKeyAlias(xpub.XPub, oldAlias); err != ErrDuplicateKeyAlias { t.Fatal("got error:", err, "want error:", ErrDuplicateKeyAlias) } if err = hsm.UpdateKeyAlias(xpub.XPub, newAlias); err != nil { t.Fatal(err) } if err = hsm.XDelete(xpub.XPub, "password"); err != nil { t.Fatal(err) } } func TestPseudoHSMChainKDKeys(t *testing.T) { hsm, _ := New(dirPath) xpub, _, err := hsm.XCreate("bbs", "password", "en") if err != nil { t.Fatal(err) } xpub2, _, err := hsm.XCreate("bytom", "nopassword", "en") if err != nil { t.Fatal(err) } msg := []byte("In the face of ignorance and resistance I wrote financial systems into existence") sig, err := hsm.XSign(xpub.XPub, nil, msg, "password") if err != nil { t.Fatal(err) } if !xpub.XPub.Verify(msg, sig) { t.Error("expected verify to succeed") } if xpub2.XPub.Verify(msg, sig) { t.Error("expected verify with wrong pubkey to fail") } path := [][]byte{{3, 2, 6, 3, 8, 2, 7}} sig, err = hsm.XSign(xpub2.XPub, path, msg, "nopassword") if err != nil { t.Fatal(err) } if xpub2.XPub.Verify(msg, sig) { t.Error("expected verify with underived pubkey of sig from derived privkey to fail") } if !xpub2.XPub.Derive(path).Verify(msg, sig) { t.Error("expected verify with derived pubkey of sig from derived privkey to succeed") } xpubs := hsm.ListKeys() if len(xpubs) != 2 { t.Error("expected 2 entries in the db") } err = hsm.ResetPassword(xpub2.XPub, "nopassword", "1password") if err != nil { t.Fatal(err) } err = hsm.XDelete(xpub.XPub, "password") if err != nil { t.Fatal(err) } err = hsm.XDelete(xpub2.XPub, "1password") if err != nil { t.Fatal(err) } } func TestKeyWithEmptyAlias(t *testing.T) { hsm, _ := New(dirPath) for i := 0; i < 2; i++ { xpub, _, err := hsm.XCreate(fmt.Sprintf("xx%d", i), "xx", "en") if errors.Root(err) != nil { t.Fatal(err) } err = hsm.XDelete(xpub.XPub, "xx") if err != nil { t.Fatal(err) } } } func TestSignAndVerifyMessage(t *testing.T) { hsm, _ := New(dirPath) xpub, _, err := hsm.XCreate("TESTKEY", "password", "en") if err != nil { t.Fatal(err) } path := [][]byte{{3, 2, 6, 3, 8, 2, 7}} derivedXPub := xpub.XPub.Derive(path) msg := "this is a test message" sig, err := hsm.XSign(xpub.XPub, path, []byte(msg), "password") if err != nil { t.Fatal(err) } // derivedXPub verify success if !ed25519.Verify(derivedXPub.PublicKey(), []byte(msg), sig) { t.Fatal("right derivedXPub verify sign failed") } // rootXPub verify failed if ed25519.Verify(xpub.XPub.PublicKey(), []byte(msg), sig) { t.Fatal("right rootXPub verify derivedXPub sign succeed") } err = hsm.XDelete(xpub.XPub, "password") if err != nil { t.Fatal(err) } } func TestImportKeyFromMnemonic(t *testing.T) { dirPath, err := ioutil.TempDir(".", "") if err != nil { t.Fatal(err) } defer os.RemoveAll(dirPath) hsm, _ := New(dirPath) supportLanguage := []string{"zh_CN", "zh_TW", "en", "it", "ja", "ko", "es"} for i, language := range supportLanguage { key := fmt.Sprintf("TESTKEY%x", i) xpub, mnemonic, err := hsm.XCreate(key, "password", language) if err != nil { t.Fatal(err) } importKey := fmt.Sprintf("IMPORTKEY%x", i) newXPub, err := hsm.ImportKeyFromMnemonic(importKey, "password", *mnemonic, language) if err != nil { t.Fatal(err) } if xpub.XPub != newXPub.XPub { t.Fatal("import key from mnemonic failed") } } } func BenchmarkSign(b *testing.B) { b.StopTimer() auth := "nowpasswd" hsm, _ := New(dirPath) xpub, _, err := hsm.XCreate("TESTKEY", auth, "en") if err != nil { b.Fatal(err) } msg := []byte("In the face of ignorance and resistance I wrote financial systems into existence") b.StartTimer() for i := 0; i < b.N; i++ { _, err := hsm.XSign(xpub.XPub, nil, msg, auth) if err != nil { b.Fatal(err) } } err = hsm.XDelete(xpub.XPub, auth) if err != nil { b.Fatal(err) } }