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