github.com/letsencrypt/trillian@v1.1.2-0.20180615153820-ae375a99d36a/merkle/map_verifier_test.go (about) 1 // Copyright 2016 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package merkle 16 17 import ( 18 "testing" 19 20 "github.com/google/trillian/merkle/coniks" 21 "github.com/google/trillian/merkle/maphasher" 22 "github.com/google/trillian/testonly" 23 ) 24 25 var h2b = testonly.MustHexDecode 26 27 func TestConiksHasherTestVectors(t *testing.T) { 28 // Test vectors were obtained by copying values from 29 // github.com/google/keytransparency/core/client/kt/verify_test.go 30 31 h := coniks.Default 32 for _, tc := range []struct { 33 desc string 34 index []byte 35 proof [][]byte 36 root []byte 37 leaf []byte 38 treeID int64 39 }{ 40 { 41 desc: "Empty proof", 42 index: []byte{0xa5, 0xd1, 0x37, 0xb4, 0x39, 0x38, 0xce, 0x3f, 0x28, 0x69, 0x55, 0x42, 0x6, 0xb1, 0x96, 0x4b, 0x84, 0x95, 0xda, 0xa2, 0x54, 0x8, 0xf2, 0x75, 0x75, 0x80, 0x1a, 0xc0, 0x71, 0xba, 0xed, 0xa7}, 43 proof: make([][]byte, 256), 44 root: []byte{0x0e, 0xfc, 0x54, 0xad, 0xe0, 0xfc, 0xe8, 0x76, 0x55, 0x8c, 0x97, 0x38, 0xf5, 0xaa, 0x89, 0xe4, 0xd9, 0x9c, 0x0b, 0x8b, 0x6f, 0xe0, 0xb6, 0x2d, 0xbf, 0x63, 0x59, 0xcf, 0xc2, 0xad, 0xbb, 0xd7}, 45 treeID: 9175411803742040796, 46 }, 47 { 48 desc: "One item, empty proof", 49 index: []byte{0xb7, 0x57, 0x2d, 0xf6, 0xe1, 0x9, 0x1f, 0xc0, 0x6, 0x9e, 0x4, 0xbf, 0x80, 0x98, 0x75, 0x25, 0xe7, 0x7a, 0xc9, 0xa6, 0xc2, 0x94, 0xd2, 0x8d, 0xb7, 0xf4, 0xe3, 0x60, 0x25, 0x1d, 0x83, 0xbf}, 50 proof: append(make([][]byte, 255), []byte{ 51 92, 215, 13, 113, 97, 138, 214, 158, 13, 29, 227, 67, 236, 34, 215, 4, 76, 188, 79, 247, 149, 223, 227, 147, 86, 214, 90, 126, 192, 212, 113, 64, 52 }), 53 root: []byte{0x2c, 0x27, 0x03, 0xe0, 0x34, 0xf4, 0x00, 0x2f, 0x94, 0x1d, 0xfc, 0xea, 0x7a, 0x4e, 0x16, 0x03, 0xee, 0x8b, 0x4e, 0xe3, 0x75, 0xbd, 0xf8, 0x72, 0x5e, 0xb8, 0xaf, 0x04, 0xbf, 0xa3, 0xd1, 0x56}, 54 treeID: 2595744899657020594, 55 }, 56 { 57 desc: "One item, exists proof", 58 index: h2b("6e39bd1b2aec80f29204d63b9aff74b17cc0255b8e9d6a8fc4c069cfefc01ce9"), 59 proof: make([][]byte, 256), 60 leaf: h2b("1290010a4030393264343162666564666665666639376261313963653430356165633433383631333766373435376439303234633537663361333439366630303938366538124c080410031a463044022064cf8e276381a5fc993e471e29463dbebf99b7e361a389024a92c3cb0fa1571402200bb9af4bd2e61fa5e2ea46cd1e653ee0f264703293d4ddd6bc88fc2cde5049181a206e39bd1b2aec80f29204d63b9aff74b17cc0255b8e9d6a8fc4c069cfefc01ce932200f30aff51b696d25d423f0d0fa208efe6038d83133cdc58b8d68f9d30e029efc3a5d0a5b3059301306072a8648ce3d020106082a8648ce3d03010703420004fb154e7698647e912d97b385f280b2bd6c37d5d57886719b5c33db74594bd6799aca19eac847d1757365a414f653d857712c6588a235ac7ac02450f1de772db442201b16b1df538ba12dc3f97edbb85caa7050d46c148134290feba80f8236c83db9"), 61 root: h2b("9986cc7a6ede7443a877cb8b971bb4cf8628ba30f41a002f6eb231fd093bb49f"), 62 treeID: 6099875953263526152, 63 }, 64 } { 65 t.Run(tc.desc, func(t *testing.T) { 66 if err := VerifyMapInclusionProof(tc.treeID, tc.index, tc.leaf, tc.root, tc.proof, h); err != nil { 67 t.Errorf("VerifyMapInclusionProof failed: %v", err) 68 } 69 }) 70 } 71 } 72 73 func TestMapHasherTestVectors(t *testing.T) { 74 // Test vectors were copied from a python implementation. 75 h := maphasher.Default 76 tv := struct { 77 Index []byte 78 Value []byte 79 Proof [][]byte 80 ExpectedRoot []byte 81 }{ 82 83 testonly.HashKey("key-0-848"), 84 []byte("value-0-848"), 85 [][]byte{ 86 // 246 x nil 87 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 88 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 89 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 90 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 91 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 92 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 93 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 94 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 95 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 96 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 97 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 98 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 99 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 100 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 101 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 102 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 103 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 104 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 105 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 106 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 107 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 108 nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 109 nil, nil, nil, nil, 110 testonly.MustDecodeBase64("vMWPHFclXXchQbAGJr6pcB002vQZYHnJTfOC42E1iT8="), 111 nil, 112 testonly.MustDecodeBase64("C3VKkaOliXmuHXM0zrkSulYX6ORaNG8qWHez/dyQkQs="), 113 testonly.MustDecodeBase64("7vmVXjPm0XhOMJlnpxJa/ZKn8eeK0PIthOOy74w+sJc="), 114 testonly.MustDecodeBase64("vEWXkf+9ZJQ/oxyyOaQdIfZfsx2GCA/NldZ+UopQF6Y="), 115 testonly.MustDecodeBase64("lrGGFxtBKRdE53Dl6p0GeFgM6VomF9Fx5k/6+aIzMWc="), 116 testonly.MustDecodeBase64("I5nVuy9wljpxbgv/aE9ivo854GhFRdsAWwmmEXDjaxE="), 117 testonly.MustDecodeBase64("yAxifDRQUd+vjc6RaHG9f8tCWSa0mzV4rry50khiD3M="), 118 testonly.MustDecodeBase64("YmUpJx/UagsoBYv6PnFRaVYw3x6kAx3N3OOSyiXsGtg="), 119 testonly.MustDecodeBase64("CtC2GCsc3/zFn1DNkoUThUnn7k+DMotaNXvmceKIL4Y="), 120 }, 121 testonly.MustDecodeBase64("U6ANU1en3BSbbnWqhV2nTGtQ+scBlaZf9kRPEEDZsHM="), 122 } 123 124 // Copy the bad proof so we don't mess up the good proof. 125 badProof := make([][]byte, len(tv.Proof)) 126 for i := range badProof { 127 badProof[i] = make([]byte, len(tv.Proof[i])) 128 copy(badProof[i], tv.Proof[i]) 129 } 130 badProof[250][15] ^= 0x10 131 132 for _, tc := range []struct { 133 desc string 134 index, leaf, root []byte 135 proof [][]byte 136 want bool 137 }{ 138 {"correct", tv.Index, tv.Value, tv.ExpectedRoot, tv.Proof, true}, 139 {"incorrect key", []byte("w"), tv.Value, tv.ExpectedRoot, tv.Proof, false}, 140 {"incorrect value", tv.Index, []byte("w"), tv.ExpectedRoot, tv.Proof, false}, 141 {"incorrect root", tv.Index, tv.Value, []byte("w"), tv.Proof, false}, 142 {"incorrect proof", tv.Index, tv.Value, tv.ExpectedRoot, badProof, false}, 143 {"short proof", tv.Index, tv.Value, tv.ExpectedRoot, [][]byte{[]byte("shorty")}, false}, 144 {"excess proof", tv.Index, tv.Value, tv.ExpectedRoot, make([][]byte, h.Size()*8+1), false}, 145 } { 146 err := VerifyMapInclusionProof(treeID, tc.index, tc.leaf, tc.root, tc.proof, h) 147 if got := err == nil; got != tc.want { 148 t.Errorf("%v: VerifyMapInclusionProof(): %v, want %v", tc.desc, err, tc.want) 149 } 150 } 151 }