github.com/koko1123/flow-go-1@v0.29.6/fvm/crypto/hash_test.go (about)

     1  package crypto_test
     2  
     3  import (
     4  	"math/rand"
     5  	"testing"
     6  	"time"
     7  
     8  	"crypto/sha256"
     9  	"crypto/sha512"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  	"golang.org/x/crypto/sha3"
    14  
    15  	"github.com/onflow/flow-go/crypto/hash"
    16  	"github.com/koko1123/flow-go-1/fvm/crypto"
    17  	"github.com/koko1123/flow-go-1/model/flow"
    18  )
    19  
    20  // TestPrefixedHash is a specific test for prefixed hashing
    21  func TestPrefixedHash(t *testing.T) {
    22  
    23  	hashingAlgoToTestingAlgo := map[hash.HashingAlgorithm]func([]byte) []byte{
    24  		hash.SHA2_256: func(data []byte) []byte {
    25  			h := sha256.Sum256(data)
    26  			return h[:]
    27  		},
    28  		hash.SHA3_256: func(data []byte) []byte {
    29  			h := sha3.Sum256(data)
    30  			return h[:]
    31  		},
    32  		hash.SHA2_384: func(data []byte) []byte {
    33  			h := sha512.Sum384(data)
    34  			return h[:]
    35  		},
    36  		hash.SHA3_384: func(data []byte) []byte {
    37  			h := sha3.Sum384(data)
    38  			return h[:]
    39  		},
    40  		hash.Keccak_256: func(data []byte) []byte {
    41  			var output [hash.HashLenKeccak_256]byte
    42  			h := sha3.NewLegacyKeccak256()
    43  			h.Write(data)
    44  			return h.Sum(output[:0])[:]
    45  		},
    46  	}
    47  
    48  	r := time.Now().UnixNano()
    49  	rand.Seed(r)
    50  	t.Logf("math rand seed is %d", r)
    51  
    52  	for hashAlgo, testFunction := range hashingAlgoToTestingAlgo {
    53  		t.Run(hashAlgo.String()+" with a prefix", func(t *testing.T) {
    54  			for i := flow.DomainTagLength; i < 5000; i++ {
    55  				// first 32 bytes of data are the tag
    56  				data := make([]byte, i)
    57  				rand.Read(data)
    58  				expected := testFunction(data)
    59  
    60  				tag := string(data[:flow.DomainTagLength])
    61  				message := data[flow.DomainTagLength:]
    62  				hasher, err := crypto.NewPrefixedHashing(hashAlgo, tag)
    63  				require.NoError(t, err)
    64  				h := hasher.ComputeHash(message)
    65  				assert.Equal(t, expected, []byte(h))
    66  			}
    67  		})
    68  
    69  		t.Run(hashAlgo.String()+" without a prefix", func(t *testing.T) {
    70  			for i := 0; i < 5000; i++ {
    71  				data := make([]byte, i)
    72  				rand.Read(data)
    73  				expected := testFunction(data)
    74  
    75  				tag := ""
    76  				hasher, err := crypto.NewPrefixedHashing(hashAlgo, tag)
    77  				require.NoError(t, err)
    78  				h := hasher.ComputeHash(data)
    79  				assert.Equal(t, expected, []byte(h))
    80  			}
    81  		})
    82  
    83  		t.Run(hashAlgo.String()+" with tagged prefix", func(t *testing.T) {
    84  			data := make([]byte, 100) // data to hash
    85  			rand.Read(data)
    86  			tag := "tag" // tag to be padded
    87  
    88  			hasher, err := crypto.NewPrefixedHashing(hashAlgo, tag)
    89  			require.NoError(t, err)
    90  			expected := hasher.ComputeHash(data)
    91  			for i := len(tag); i < flow.DomainTagLength; i++ {
    92  				paddedTag := make([]byte, i)
    93  				copy(paddedTag, tag)
    94  				paddedHasher, err := crypto.NewPrefixedHashing(hashAlgo, string(paddedTag))
    95  				require.NoError(t, err)
    96  				h := paddedHasher.ComputeHash(data)
    97  
    98  				assert.Equal(t, expected, h)
    99  			}
   100  		})
   101  	}
   102  
   103  	t.Run("non supported algorithm", func(t *testing.T) {
   104  		_, err := crypto.NewPrefixedHashing(hash.KMAC128, "")
   105  		require.Error(t, err)
   106  	})
   107  }