github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/crypto/ledger_test.go (about) 1 package crypto 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 9 tmcrypto "github.com/fibonacci-chain/fbc/libs/tendermint/crypto" 10 cryptoAmino "github.com/fibonacci-chain/fbc/libs/tendermint/crypto/encoding/amino" 11 12 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/crypto/keys/hd" 13 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/tests" 14 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 15 ) 16 17 func TestLedgerErrorHandling(t *testing.T) { 18 // first, try to generate a key, must return an error 19 // (no panic) 20 path := *hd.NewParams(44, 555, 0, false, 0) 21 _, err := NewPrivKeyLedgerSecp256k1Unsafe(path) 22 require.Error(t, err) 23 } 24 25 func TestPublicKeyUnsafe(t *testing.T) { 26 path := *hd.NewFundraiserParams(0, sdk.CoinType, 0) 27 priv, err := NewPrivKeyLedgerSecp256k1Unsafe(path) 28 require.NoError(t, err) 29 require.NotNil(t, priv) 30 31 require.Equal(t, "eb5ae98721034fef9cd7c4c63588d3b03feb5281b9d232cba34d6f3d71aee59211ffbfe1fe87", 32 fmt.Sprintf("%x", priv.PubKey().Bytes()), 33 "Is your device using test mnemonic: %s ?", tests.TestMnemonic) 34 35 pubKeyAddr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, priv.PubKey()) 36 require.NoError(t, err) 37 require.Equal(t, "cosmospub1addwnpepqd87l8xhcnrrtzxnkql7k55ph8fr9jarf4hn6udwukfprlalu8lgw0urza0", 38 pubKeyAddr, "Is your device using test mnemonic: %s ?", tests.TestMnemonic) 39 40 addr := sdk.AccAddress(priv.PubKey().Address()).String() 41 require.Equal(t, "cosmos1w34k53py5v5xyluazqpq65agyajavep2rflq6h", 42 addr, "Is your device using test mnemonic: %s ?", tests.TestMnemonic) 43 } 44 45 func TestPublicKeyUnsafeHDPath(t *testing.T) { 46 expectedAnswers := []string{ 47 "cosmospub1addwnpepqd87l8xhcnrrtzxnkql7k55ph8fr9jarf4hn6udwukfprlalu8lgw0urza0", 48 "cosmospub1addwnpepqfsdqjr68h7wjg5wacksmqaypasnra232fkgu5sxdlnlu8j22ztxvlqvd65", 49 "cosmospub1addwnpepqw3xwqun6q43vtgw6p4qspq7srvxhcmvq4jrx5j5ma6xy3r7k6dtxmrkh3d", 50 "cosmospub1addwnpepqvez9lrp09g8w7gkv42y4yr5p6826cu28ydrhrujv862yf4njmqyyjr4pjs", 51 "cosmospub1addwnpepq06hw3enfrtmq8n67teytcmtnrgcr0yntmyt25kdukfjkerdc7lqg32rcz7", 52 "cosmospub1addwnpepqg3trf2gd0s2940nckrxherwqhgmm6xd5h4pcnrh4x7y35h6yafmcpk5qns", 53 "cosmospub1addwnpepqdm6rjpx6wsref8wjn7ym6ntejet430j4szpngfgc20caz83lu545vuv8hp", 54 "cosmospub1addwnpepqvdhtjzy2wf44dm03jxsketxc07vzqwvt3vawqqtljgsr9s7jvydjmt66ew", 55 "cosmospub1addwnpepqwystfpyxwcava7v3t7ndps5xzu6s553wxcxzmmnxevlzvwrlqpzz695nw9", 56 "cosmospub1addwnpepqw970u6gjqkccg9u3rfj99857wupj2z9fqfzy2w7e5dd7xn7kzzgkgqch0r", 57 } 58 59 const numIters = 10 60 61 privKeys := make([]tmcrypto.PrivKey, numIters) 62 63 // Check with device 64 for i := uint32(0); i < 10; i++ { 65 path := *hd.NewFundraiserParams(0, sdk.CoinType, i) 66 t.Logf("Checking keys at %v\n", path) 67 68 priv, err := NewPrivKeyLedgerSecp256k1Unsafe(path) 69 require.NoError(t, err) 70 require.NotNil(t, priv) 71 72 // Check other methods 73 require.NoError(t, priv.(PrivKeyLedgerSecp256k1).ValidateKey()) 74 tmp := priv.(PrivKeyLedgerSecp256k1) 75 (&tmp).AssertIsPrivKeyInner() 76 77 pubKeyAddr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, priv.PubKey()) 78 require.NoError(t, err) 79 require.Equal(t, 80 expectedAnswers[i], pubKeyAddr, 81 "Is your device using test mnemonic: %s ?", tests.TestMnemonic) 82 83 // Store and restore 84 serializedPk := priv.Bytes() 85 require.NotNil(t, serializedPk) 86 require.True(t, len(serializedPk) >= 50) 87 88 privKeys[i] = priv 89 } 90 91 // Now check equality 92 for i := 0; i < 10; i++ { 93 for j := 0; j < 10; j++ { 94 require.Equal(t, i == j, privKeys[i].Equals(privKeys[j])) 95 require.Equal(t, i == j, privKeys[j].Equals(privKeys[i])) 96 } 97 } 98 } 99 100 func TestPublicKeySafe(t *testing.T) { 101 path := *hd.NewFundraiserParams(0, sdk.CoinType, 0) 102 priv, addr, err := NewPrivKeyLedgerSecp256k1(path, "cosmos") 103 104 require.NoError(t, err) 105 require.NotNil(t, priv) 106 107 require.Equal(t, "eb5ae98721034fef9cd7c4c63588d3b03feb5281b9d232cba34d6f3d71aee59211ffbfe1fe87", 108 fmt.Sprintf("%x", priv.PubKey().Bytes()), 109 "Is your device using test mnemonic: %s ?", tests.TestMnemonic) 110 111 pubKeyAddr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, priv.PubKey()) 112 require.NoError(t, err) 113 require.Equal(t, "cosmospub1addwnpepqd87l8xhcnrrtzxnkql7k55ph8fr9jarf4hn6udwukfprlalu8lgw0urza0", 114 pubKeyAddr, "Is your device using test mnemonic: %s ?", tests.TestMnemonic) 115 116 require.Equal(t, "cosmos1w34k53py5v5xyluazqpq65agyajavep2rflq6h", 117 addr, "Is your device using test mnemonic: %s ?", tests.TestMnemonic) 118 119 addr2 := sdk.AccAddress(priv.PubKey().Address()).String() 120 require.Equal(t, addr, addr2) 121 } 122 123 func TestPublicKeyHDPath(t *testing.T) { 124 expectedPubKeys := []string{ 125 "cosmospub1addwnpepqd87l8xhcnrrtzxnkql7k55ph8fr9jarf4hn6udwukfprlalu8lgw0urza0", 126 "cosmospub1addwnpepqfsdqjr68h7wjg5wacksmqaypasnra232fkgu5sxdlnlu8j22ztxvlqvd65", 127 "cosmospub1addwnpepqw3xwqun6q43vtgw6p4qspq7srvxhcmvq4jrx5j5ma6xy3r7k6dtxmrkh3d", 128 "cosmospub1addwnpepqvez9lrp09g8w7gkv42y4yr5p6826cu28ydrhrujv862yf4njmqyyjr4pjs", 129 "cosmospub1addwnpepq06hw3enfrtmq8n67teytcmtnrgcr0yntmyt25kdukfjkerdc7lqg32rcz7", 130 "cosmospub1addwnpepqg3trf2gd0s2940nckrxherwqhgmm6xd5h4pcnrh4x7y35h6yafmcpk5qns", 131 "cosmospub1addwnpepqdm6rjpx6wsref8wjn7ym6ntejet430j4szpngfgc20caz83lu545vuv8hp", 132 "cosmospub1addwnpepqvdhtjzy2wf44dm03jxsketxc07vzqwvt3vawqqtljgsr9s7jvydjmt66ew", 133 "cosmospub1addwnpepqwystfpyxwcava7v3t7ndps5xzu6s553wxcxzmmnxevlzvwrlqpzz695nw9", 134 "cosmospub1addwnpepqw970u6gjqkccg9u3rfj99857wupj2z9fqfzy2w7e5dd7xn7kzzgkgqch0r", 135 } 136 137 expectedAddrs := []string{ 138 "cosmos1w34k53py5v5xyluazqpq65agyajavep2rflq6h", 139 "cosmos19ewxwemt6uahejvwf44u7dh6tq859tkyvarh2q", 140 "cosmos1a07dzdjgjsntxpp75zg7cgatgq0udh3pcdcxm3", 141 "cosmos1qvw52lmn9gpvem8welghrkc52m3zczyhlqjsl7", 142 "cosmos17m78ka80fqkkw2c4ww0v4xm5nsu2drgrlm8mn2", 143 "cosmos1ferh9ll9c452d2p8k2v7heq084guygkn43up9e", 144 "cosmos10vf3sxmjg96rqq36axcphzfsl74dsntuehjlw5", 145 "cosmos1cq83av8cmnar79h0rg7duh9gnr7wkh228a7fxg", 146 "cosmos1dszhfrt226jy5rsre7e48vw9tgwe90uerfyefa", 147 "cosmos1734d7qsylzrdt05muhqqtpd90j8mp4y6rzch8l", 148 } 149 150 const numIters = 10 151 152 privKeys := make([]tmcrypto.PrivKey, numIters) 153 154 // Check with device 155 for i := uint32(0); i < 10; i++ { 156 path := *hd.NewFundraiserParams(0, sdk.CoinType, i) 157 t.Logf("Checking keys at %s\n", path) 158 159 priv, addr, err := NewPrivKeyLedgerSecp256k1(path, "cosmos") 160 require.NoError(t, err) 161 require.NotNil(t, addr) 162 require.NotNil(t, priv) 163 164 addr2 := sdk.AccAddress(priv.PubKey().Address()).String() 165 require.Equal(t, addr2, addr) 166 require.Equal(t, 167 expectedAddrs[i], addr, 168 "Is your device using test mnemonic: %s ?", tests.TestMnemonic) 169 170 // Check other methods 171 require.NoError(t, priv.(PrivKeyLedgerSecp256k1).ValidateKey()) 172 tmp := priv.(PrivKeyLedgerSecp256k1) 173 (&tmp).AssertIsPrivKeyInner() 174 175 pubKeyAddr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, priv.PubKey()) 176 require.NoError(t, err) 177 require.Equal(t, 178 expectedPubKeys[i], pubKeyAddr, 179 "Is your device using test mnemonic: %s ?", tests.TestMnemonic) 180 181 // Store and restore 182 serializedPk := priv.Bytes() 183 require.NotNil(t, serializedPk) 184 require.True(t, len(serializedPk) >= 50) 185 186 privKeys[i] = priv 187 } 188 189 // Now check equality 190 for i := 0; i < 10; i++ { 191 for j := 0; j < 10; j++ { 192 require.Equal(t, i == j, privKeys[i].Equals(privKeys[j])) 193 require.Equal(t, i == j, privKeys[j].Equals(privKeys[i])) 194 } 195 } 196 } 197 198 func getFakeTx(accountNumber uint32) []byte { 199 tmp := fmt.Sprintf( 200 `{"account_number":"%d","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"5000"},"memo":"memo","msgs":[[""]],"sequence":"6"}`, 201 accountNumber) 202 203 return []byte(tmp) 204 } 205 206 func TestSignaturesHD(t *testing.T) { 207 for account := uint32(0); account < 100; account += 30 { 208 msg := getFakeTx(account) 209 210 path := *hd.NewFundraiserParams(account, sdk.CoinType, account/5) 211 t.Logf("Checking signature at %v --- PLEASE REVIEW AND ACCEPT IN THE DEVICE\n", path) 212 213 priv, err := NewPrivKeyLedgerSecp256k1Unsafe(path) 214 require.NoError(t, err) 215 216 pub := priv.PubKey() 217 sig, err := priv.Sign(msg) 218 require.NoError(t, err) 219 220 valid := pub.VerifyBytes(msg, sig) 221 require.True(t, valid, "Is your device using test mnemonic: %s ?", tests.TestMnemonic) 222 } 223 } 224 225 func TestRealLedgerSecp256k1(t *testing.T) { 226 msg := getFakeTx(50) 227 path := *hd.NewFundraiserParams(0, sdk.CoinType, 0) 228 priv, err := NewPrivKeyLedgerSecp256k1Unsafe(path) 229 require.NoError(t, err) 230 231 pub := priv.PubKey() 232 sig, err := priv.Sign(msg) 233 require.NoError(t, err) 234 235 valid := pub.VerifyBytes(msg, sig) 236 require.True(t, valid) 237 238 // now, let's serialize the public key and make sure it still works 239 bs := priv.PubKey().Bytes() 240 pub2, err := cryptoAmino.PubKeyFromBytes(bs) 241 require.Nil(t, err, "%+v", err) 242 243 // make sure we get the same pubkey when we load from disk 244 require.Equal(t, pub, pub2) 245 246 // signing with the loaded key should match the original pubkey 247 sig, err = priv.Sign(msg) 248 require.NoError(t, err) 249 valid = pub.VerifyBytes(msg, sig) 250 require.True(t, valid) 251 252 // make sure pubkeys serialize properly as well 253 bs = pub.Bytes() 254 bpub, err := cryptoAmino.PubKeyFromBytes(bs) 255 require.NoError(t, err) 256 require.Equal(t, pub, bpub) 257 }