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  }