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  }