1package multihash 2 3import ( 4 "bytes" 5 "encoding/hex" 6 "fmt" 7 "runtime" 8 "testing" 9) 10 11type SumTestCase struct { 12 code uint64 13 length int 14 input string 15 hex string 16} 17 18var sumTestCases = []SumTestCase{ 19 {ID, 3, "foo", "0003666f6f"}, 20 {ID, -1, "foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo", "0030666f6f666f6f666f6f666f6f666f6f666f6f666f6f666f6f666f6f666f6f666f6f666f6f666f6f666f6f666f6f666f6f"}, 21 {SHA1, -1, "foo", "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"}, 22 {SHA1, 10, "foo", "110a0beec7b5ea3f0fdbc95d"}, 23 {SHA2_256, -1, "foo", "12202c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"}, 24 {SHA2_256, 31, "foo", "121f2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7"}, 25 {SHA2_256, 32, "foo", "12202c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"}, 26 {SHA2_256, 16, "foo", "12102c26b46b68ffc68ff99b453c1d304134"}, 27 {SHA2_512, -1, "foo", "1340f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7"}, 28 {SHA2_512, 32, "foo", "1320f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc663832"}, 29 {SHA3, 32, "foo", "14204bca2b137edc580fe50a88983ef860ebaca36c857b1f492839d6d7392452a63c"}, 30 {SHA3_512, 16, "foo", "14104bca2b137edc580fe50a88983ef860eb"}, 31 {SHA3_512, -1, "foo", "14404bca2b137edc580fe50a88983ef860ebaca36c857b1f492839d6d7392452a63c82cbebc68e3b70a2a1480b4bb5d437a7cba6ecf9d89f9ff3ccd14cd6146ea7e7"}, 32 {SHA3_224, -1, "beep boop", "171c0da73a89549018df311c0a63250e008f7be357f93ba4e582aaea32b8"}, 33 {SHA3_224, 16, "beep boop", "17100da73a89549018df311c0a63250e008f"}, 34 {SHA3_256, -1, "beep boop", "1620828705da60284b39de02e3599d1f39e6c1df001f5dbf63c9ec2d2c91a95a427f"}, 35 {SHA3_256, 16, "beep boop", "1610828705da60284b39de02e3599d1f39e6"}, 36 {SHA3_384, -1, "beep boop", "153075a9cff1bcfbe8a7025aa225dd558fb002769d4bf3b67d2aaf180459172208bea989804aefccf060b583e629e5f41e8d"}, 37 {SHA3_384, 16, "beep boop", "151075a9cff1bcfbe8a7025aa225dd558fb0"}, 38 {DBL_SHA2_256, 32, "foo", "5620c7ade88fc7a21498a6a5e5c385e1f68bed822b72aa63c4a9a48a02c2466ee29e"}, 39 {BLAKE2B_MAX, -1, "foo", "c0e40240ca002330e69d3e6b84a46a56a6533fd79d51d97a3bb7cad6c2ff43b354185d6dc1e723fb3db4ae0737e120378424c714bb982d9dc5bbd7a0ab318240ddd18f8d"}, 40 {BLAKE2B_MAX, 64, "foo", "c0e40240ca002330e69d3e6b84a46a56a6533fd79d51d97a3bb7cad6c2ff43b354185d6dc1e723fb3db4ae0737e120378424c714bb982d9dc5bbd7a0ab318240ddd18f8d"}, 41 {BLAKE2B_MAX - 32, -1, "foo", "a0e40220b8fe9f7f6255a6fa08f668ab632a8d081ad87983c77cd274e48ce450f0b349fd"}, 42 {BLAKE2B_MAX - 32, 32, "foo", "a0e40220b8fe9f7f6255a6fa08f668ab632a8d081ad87983c77cd274e48ce450f0b349fd"}, 43 {BLAKE2B_MAX - 19, -1, "foo", "ade4022dca82ab956d5885e3f5db10cca94182f01a6ca2c47f9f4228497dcc9f4a0121c725468b852a71ec21fcbeb725df"}, 44 {BLAKE2B_MAX - 19, 45, "foo", "ade4022dca82ab956d5885e3f5db10cca94182f01a6ca2c47f9f4228497dcc9f4a0121c725468b852a71ec21fcbeb725df"}, 45 {BLAKE2B_MAX - 16, -1, "foo", "b0e40230e629ee880953d32c8877e479e3b4cb0a4c9d5805e2b34c675b5a5863c4ad7d64bb2a9b8257fac9d82d289b3d39eb9cc2"}, 46 {BLAKE2B_MAX - 16, 48, "foo", "b0e40230e629ee880953d32c8877e479e3b4cb0a4c9d5805e2b34c675b5a5863c4ad7d64bb2a9b8257fac9d82d289b3d39eb9cc2"}, 47 {BLAKE2B_MIN + 19, -1, "foo", "94e40214983ceba2afea8694cc933336b27b907f90c53a88"}, 48 {BLAKE2B_MIN + 19, 20, "foo", "94e40214983ceba2afea8694cc933336b27b907f90c53a88"}, 49 {BLAKE2B_MIN, -1, "foo", "81e4020152"}, 50 {BLAKE2B_MIN, 1, "foo", "81e4020152"}, 51 {BLAKE2S_MAX, 32, "foo", "e0e4022008d6cad88075de8f192db097573d0e829411cd91eb6ec65e8fc16c017edfdb74"}, 52 {MURMUR3_128, 4, "beep boop", "2204243ddb9e"}, 53 {KECCAK_256, 32, "foo", "1b2041b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d"}, 54 {KECCAK_512, -1, "beep boop", "1d40e161c54798f78eba3404ac5e7e12d27555b7b810e7fd0db3f25ffa0c785c438331b0fbb6156215f69edf403c642e5280f4521da9bd767296ec81f05100852e78"}, 55 {SHAKE_128, 32, "foo", "1820f84e95cb5fbd2038863ab27d3cdeac295ad2d4ab96ad1f4b070c0bf36078ef08"}, 56 {SHAKE_256, 64, "foo", "19401af97f7818a28edfdfce5ec66dbdc7e871813816d7d585fe1f12475ded5b6502b7723b74e2ee36f2651a10a8eaca72aa9148c3c761aaceac8f6d6cc64381ed39"}, 57 {MD5, -1, "foo", "d50110acbd18db4cc2f85cedef654fccc4a4d8"}, 58} 59 60func TestSum(t *testing.T) { 61 62 for _, tc := range sumTestCases { 63 64 m1, err := FromHexString(tc.hex) 65 if err != nil { 66 t.Error(err) 67 continue 68 } 69 70 m2, err := Sum([]byte(tc.input), tc.code, tc.length) 71 if err != nil { 72 t.Error(tc.code, "sum failed.", err) 73 continue 74 } 75 76 if !bytes.Equal(m1, m2) { 77 t.Error(tc.code, Codes[tc.code], "sum failed.", m1, m2) 78 t.Error(hex.EncodeToString(m2)) 79 } 80 81 s1 := m1.HexString() 82 if s1 != tc.hex { 83 t.Error("hex strings not the same") 84 } 85 86 s2 := m1.B58String() 87 m3, err := FromB58String(s2) 88 if err != nil { 89 t.Error("failed to decode b58") 90 } else if !bytes.Equal(m3, m1) { 91 t.Error("b58 failing bytes") 92 } else if s2 != m3.B58String() { 93 t.Error("b58 failing string") 94 } 95 } 96} 97 98func BenchmarkSum(b *testing.B) { 99 tc := sumTestCases[0] 100 for i := 0; i < b.N; i++ { 101 Sum([]byte(tc.input), tc.code, tc.length) 102 } 103} 104 105func BenchmarkBlake2B(b *testing.B) { 106 sizes := []uint64{128, 129, 130, 255, 256, 257, 386, 512} 107 for _, s := range sizes { 108 func(si uint64) { 109 b.Run(fmt.Sprintf("blake2b-%d", s), func(b *testing.B) { 110 arr := []byte("test data for some hashing, this is broken") 111 b.ResetTimer() 112 b.ReportAllocs() 113 for i := 0; i < b.N; i++ { 114 m, err := Sum(arr, BLAKE2B_MIN+si/8-1, -1) 115 if err != nil { 116 b.Fatal(err) 117 } 118 runtime.KeepAlive(m) 119 } 120 }) 121 }(s) 122 } 123} 124 125// Test that the identity hash function checks 126// its `length` arguemnt for values that are 127// different to its `data` length. 128func TestSmallerLengthHashID(t *testing.T) { 129 130 data := []byte("Identity hash input data.") 131 dataLength := len(data) 132 133 // Normal case: `length == len(data)`. 134 _, err := sumID(data, dataLength) 135 if err != nil { 136 t.Fatal(err) 137 } 138 139 // Unconstrained length (-1): also allowed. 140 _, err = sumID(data, -1) 141 if err != nil { 142 t.Fatal(err) 143 } 144 145 // Any other variation of those two scenarios should fail. 146 for l := (dataLength - 1); l >= 0; l-- { 147 _, err = sumID(data, l) 148 if err == nil { 149 t.Fatal(fmt.Sprintf("identity hash of length %d smaller than data length %d didn't fail", 150 l, dataLength)) 151 } 152 } 153} 154 155// Ensure that invalid codecs can't be registered, and existing hash funcs 156// won't be overwritten. 157func TestRegisterHashFunc(t *testing.T) { 158 tests := []struct { 159 code uint64 160 shouldErr bool 161 }{ 162 {9999, true}, 163 {SHA1, true}, 164 } 165 166 doesNothing := func(data []byte, length int) ([]byte, error) { 167 return []byte{}, nil 168 } 169 170 for _, tt := range tests { 171 err := RegisterHashFunc(tt.code, doesNothing) 172 if err != nil && !tt.shouldErr { 173 t.Error(err) 174 } 175 } 176} 177 178func TestTooLargeLength(t *testing.T) { 179 _, err := Sum([]byte("test"), SHA2_256, 33) 180 if err != ErrLenTooLarge { 181 t.Fatal("bad error", err) 182 } 183} 184 185func TestBasicSum(t *testing.T) { 186 for code, name := range Codes { 187 defaultLen, ok := DefaultLengths[code] 188 if !ok { 189 defaultLen = 32 190 } 191 _, err := Sum([]byte("test"), code, defaultLen) 192 switch err { 193 case ErrSumNotSupported, nil: 194 default: 195 t.Errorf("unexpected error for %s: %s", name, err) 196 } 197 } 198} 199