github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/network/p2p/translator/unstaked_translator_test.go (about) 1 package translator_test 2 3 import ( 4 "crypto/rand" 5 "testing" 6 7 "github.com/libp2p/go-libp2p/core/peer" 8 fcrypto "github.com/onflow/crypto" 9 "github.com/stretchr/testify/require" 10 11 "github.com/onflow/flow-go/network/p2p/keyutils" 12 "github.com/onflow/flow-go/network/p2p/translator" 13 ) 14 15 // For these test, refer to https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md for libp2p 16 // PeerID specifications and how they relate to keys. 17 18 // This test shows we can't use ECDSA P-256 keys for libp2p and expect PeerID <=> PublicKey bijections 19 func TestIDTranslationP256(t *testing.T) { 20 loops := 50 21 for i := 0; i < loops; i++ { 22 pID := createPeerIDFromAlgo(t, fcrypto.ECDSAP256) 23 24 // check that we can not extract the public key back 25 // This makes sense: the x509 serialization of ECDSA P-256 keys in uncompressed form is 64 + 2 bytes, 26 // and libp2p uses multihash.IDENTITY only on serializations of less than 42 bytes 27 _, err := pID.ExtractPublicKey() 28 require.NotNil(t, err) 29 30 } 31 } 32 33 // This test shows we can use ECDSA Secp256k1 keys for libp2p and expect PeerID <=> PublicKey bijections 34 func TestIDTranslationSecp256k1(t *testing.T) { 35 loops := 50 36 for i := 0; i < loops; i++ { 37 pID := createPeerIDFromAlgo(t, fcrypto.ECDSASecp256k1) 38 39 // check that we can extract the public key back 40 // This makes sense: the compressed serialization of ECDSA Secp256k1 keys is 33 + 2 bytes, 41 // and libp2p uses multihash.IDENTITY on serializations of less than 42 bytes 42 _, err := pID.ExtractPublicKey() 43 require.NoError(t, err) 44 45 } 46 } 47 48 func TestUnstakedTranslationRoundTrip(t *testing.T) { 49 max_iterations := 50 50 unstakedTranslator := translator.NewPublicNetworkIDTranslator() 51 52 tested_vectors := 0 53 54 for ok := true; ok; ok = tested_vectors < max_iterations { 55 pID := createPeerIDFromAlgo(t, fcrypto.ECDSASecp256k1) 56 57 pk, err := pID.ExtractPublicKey() 58 require.NoError(t, err) 59 60 // for a secp256k1 key, this is just the compressed representation 61 pkBytes, err := pk.Raw() 62 require.NoError(t, err) 63 64 // key is positive, roundtrip should be possible 65 if pkBytes[0] == 0x02 { 66 tested_vectors++ 67 68 flowID, err := unstakedTranslator.GetFlowID(pID) 69 require.NoError(t, err) 70 retrievedPeerID, err := unstakedTranslator.GetPeerID(flowID) 71 require.NoError(t, err) 72 require.Equal(t, pID, retrievedPeerID) 73 } 74 75 } 76 } 77 78 func createPeerIDFromAlgo(t *testing.T, sa fcrypto.SigningAlgorithm) peer.ID { 79 seed := createSeed(t) 80 81 // this matches GenerateNetworkingKeys, and is intended to validate the choices in cmd/bootstrap 82 key, err := fcrypto.GeneratePrivateKey(sa, seed) 83 require.NoError(t, err) 84 85 // get the public key 86 pubKey := key.PublicKey() 87 88 // extract the corresponding libp2p public Key 89 libp2pPubKey, err := keyutils.LibP2PPublicKeyFromFlow(pubKey) 90 require.NoError(t, err) 91 92 // obtain the PeerID based on libp2p's own rules 93 pID, err := peer.IDFromPublicKey(libp2pPubKey) 94 require.NoError(t, err) 95 96 return pID 97 } 98 99 func createSeed(t *testing.T) []byte { 100 const seedLen = fcrypto.KeyGenSeedMinLen 101 seed := make([]byte, seedLen) 102 n, err := rand.Read(seed) 103 require.NoError(t, err) 104 require.Equal(t, n, seedLen) 105 return seed 106 }