github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/state/protocol/prg/prg_test.go (about)

     1  package prg
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rand"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func getRandomSource(t *testing.T) []byte {
    13  	seed := make([]byte, RandomSourceLength)
    14  	_, err := rand.Read(seed) // checking err is enough
    15  	require.NoError(t, err)
    16  	t.Logf("seed is %#x", seed)
    17  	return seed
    18  }
    19  
    20  func getRandoms(t *testing.T, seed, customizer, diversifier []byte, N int) []byte {
    21  	prg, err := New(seed, customizer, diversifier)
    22  	require.NoError(t, err)
    23  	rand := make([]byte, N)
    24  	prg.Read(rand)
    25  	return rand
    26  }
    27  
    28  // check PRGs created from the same source give the same outputs
    29  func TestDeterministic(t *testing.T) {
    30  	seed := getRandomSource(t)
    31  	customizer := []byte("cust test")
    32  	diversifier := []byte("div test")
    33  
    34  	rand1 := getRandoms(t, seed, customizer, diversifier, 100)
    35  	rand2 := getRandoms(t, seed, customizer, diversifier, 100)
    36  	assert.Equal(t, rand1, rand2)
    37  }
    38  
    39  // check different customizers lead to different randoms
    40  func TestDifferentInstances(t *testing.T) {
    41  	seed := getRandomSource(t)
    42  	customizer1 := []byte("cust test1")
    43  	customizer2 := []byte("cust test2")
    44  	diversifer1 := []byte("div test1")
    45  	diversifer2 := []byte("div test2")
    46  	// different customizers
    47  	rand1 := getRandoms(t, seed, customizer1, diversifer1, 2)
    48  	rand2 := getRandoms(t, seed, customizer2, diversifer1, 2)
    49  	assert.NotEqual(t, rand1, rand2)
    50  	// different customizers
    51  	rand1 = getRandoms(t, seed, customizer1, diversifer1, 2)
    52  	rand2 = getRandoms(t, seed, customizer1, diversifer2, 2)
    53  	assert.NotEqual(t, rand1, rand2)
    54  	// test no error is returned with empty customizer and diversifier
    55  	_ = getRandoms(t, seed, nil, nil, 2) // error is checked inside the call
    56  }
    57  
    58  // Sanity check that all customizers used by the Flow protocol
    59  // are different and are not prefixes of each other
    60  func TestProtocolConstants(t *testing.T) {
    61  	// include all sub-protocol customizers
    62  	customizers := [][]byte{
    63  		ConsensusLeaderSelection,
    64  		VerificationChunkAssignment,
    65  		ExecutionEnvironment,
    66  		ExecutionRandomSourceHistory,
    67  		customizerFromIndices(clusterLeaderSelectionPrefix...),
    68  	}
    69  
    70  	// go through all couples
    71  	for i, c := range customizers {
    72  		for j, other := range customizers {
    73  			if i == j {
    74  				continue
    75  			}
    76  			assert.False(t, bytes.HasPrefix(c, other))
    77  		}
    78  	}
    79  }