You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
3.6 KiB

  1. package merkle
  2. // Copyright 2016 Google Inc. All Rights Reserved.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. // These tests were taken from https://github.com/google/trillian/blob/master/merkle/rfc6962/rfc6962_test.go,
  16. // and consequently fall under the above license.
  17. import (
  18. "bytes"
  19. "encoding/hex"
  20. "testing"
  21. "github.com/tendermint/tendermint/crypto/tmhash"
  22. )
  23. func TestRFC6962Hasher(t *testing.T) {
  24. _, leafHashTrail := trailsFromByteSlices([][]byte{[]byte("L123456")})
  25. leafHash := leafHashTrail.Hash
  26. _, leafHashTrail = trailsFromByteSlices([][]byte{{}})
  27. emptyLeafHash := leafHashTrail.Hash
  28. _, emptyHashTrail := trailsFromByteSlices([][]byte{})
  29. emptyTreeHash := emptyHashTrail.Hash
  30. for _, tc := range []struct {
  31. desc string
  32. got []byte
  33. want string
  34. }{
  35. // Check that empty trees return the hash of an empty string.
  36. // echo -n '' | sha256sum
  37. {
  38. desc: "RFC6962 Empty Tree",
  39. want: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"[:tmhash.Size*2],
  40. got: emptyTreeHash,
  41. },
  42. // Check that the empty hash is not the same as the hash of an empty leaf.
  43. // echo -n 00 | xxd -r -p | sha256sum
  44. {
  45. desc: "RFC6962 Empty Leaf",
  46. want: "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"[:tmhash.Size*2],
  47. got: emptyLeafHash,
  48. },
  49. // echo -n 004C313233343536 | xxd -r -p | sha256sum
  50. {
  51. desc: "RFC6962 Leaf",
  52. want: "395aa064aa4c29f7010acfe3f25db9485bbd4b91897b6ad7ad547639252b4d56"[:tmhash.Size*2],
  53. got: leafHash,
  54. },
  55. // echo -n 014E3132334E343536 | xxd -r -p | sha256sum
  56. {
  57. desc: "RFC6962 Node",
  58. want: "aa217fe888e47007fa15edab33c2b492a722cb106c64667fc2b044444de66bbb"[:tmhash.Size*2],
  59. got: innerHash([]byte("N123"), []byte("N456")),
  60. },
  61. } {
  62. tc := tc
  63. t.Run(tc.desc, func(t *testing.T) {
  64. wantBytes, err := hex.DecodeString(tc.want)
  65. if err != nil {
  66. t.Fatalf("hex.DecodeString(%x): %v", tc.want, err)
  67. }
  68. if got, want := tc.got, wantBytes; !bytes.Equal(got, want) {
  69. t.Errorf("got %x, want %x", got, want)
  70. }
  71. })
  72. }
  73. }
  74. func TestRFC6962HasherCollisions(t *testing.T) {
  75. // Check that different leaves have different hashes.
  76. leaf1, leaf2 := []byte("Hello"), []byte("World")
  77. _, leafHashTrail := trailsFromByteSlices([][]byte{leaf1})
  78. hash1 := leafHashTrail.Hash
  79. _, leafHashTrail = trailsFromByteSlices([][]byte{leaf2})
  80. hash2 := leafHashTrail.Hash
  81. if bytes.Equal(hash1, hash2) {
  82. t.Errorf("leaf hashes should differ, but both are %x", hash1)
  83. }
  84. // Compute an intermediate subtree hash.
  85. _, subHash1Trail := trailsFromByteSlices([][]byte{hash1, hash2})
  86. subHash1 := subHash1Trail.Hash
  87. // Check that this is not the same as a leaf hash of their concatenation.
  88. preimage := append(hash1, hash2...)
  89. _, forgedHashTrail := trailsFromByteSlices([][]byte{preimage})
  90. forgedHash := forgedHashTrail.Hash
  91. if bytes.Equal(subHash1, forgedHash) {
  92. t.Errorf("hasher is not second-preimage resistant")
  93. }
  94. // Swap the order of nodes and check that the hash is different.
  95. _, subHash2Trail := trailsFromByteSlices([][]byte{hash2, hash1})
  96. subHash2 := subHash2Trail.Hash
  97. if bytes.Equal(subHash1, subHash2) {
  98. t.Errorf("subtree hash does not depend on the order of leaves")
  99. }
  100. }