github.com/mad-day/Yawning-crypto@v0.0.0-20190711051033-5a5f8cca32ec/bsaes/ghash/ghash_test.go (about) 1 // Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> 2 // Copyright (c) 2017 Yawning Angel <yawning at schwanenlied dot me> 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining 5 // a copy of this software and associated documentation files (the 6 // "Software"), to deal in the Software without restriction, including 7 // without limitation the rights to use, copy, modify, merge, publish, 8 // distribute, sublicense, and/or sell copies of the Software, and to 9 // permit persons to whom the Software is furnished to do so, subject to 10 // the following conditions: 11 // 12 // The above copyright notice and this permission notice shall be 13 // included in all copies or substantial portions of the Software. 14 // 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 // SOFTWARE. 23 24 package ghash 25 26 import ( 27 "bytes" 28 "crypto/rand" 29 "encoding/binary" 30 "encoding/hex" 31 "testing" 32 ) 33 34 // The test vectors are shamelessly stolen from "The Galois/Counter Mode of 35 // Operation (GCM)", which is what BearSSL does. 36 // 37 // http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf 38 39 var ghashVectors = []struct { 40 h string 41 a string 42 c string 43 y string 44 }{ 45 { 46 "66e94bd4ef8a2c3b884cfa59ca342b2e", 47 "", 48 "", 49 "00000000000000000000000000000000", 50 }, 51 { 52 "66e94bd4ef8a2c3b884cfa59ca342b2e", 53 "", 54 "0388dace60b6a392f328c2b971b2fe78", 55 "f38cbb1ad69223dcc3457ae5b6b0f885", 56 }, 57 { 58 "b83b533708bf535d0aa6e52980d53b78", 59 "", 60 "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985", 61 "7f1b32b81b820d02614f8895ac1d4eac", 62 }, 63 { 64 "b83b533708bf535d0aa6e52980d53b78", 65 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 66 "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091", 67 "698e57f70e6ecc7fd9463b7260a9ae5f", 68 }, 69 { 70 "b83b533708bf535d0aa6e52980d53b78", 71 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 72 "61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598", 73 "df586bb4c249b92cb6922877e444d37b", 74 }, 75 { 76 "b83b533708bf535d0aa6e52980d53b78", 77 "feedfacedeadbeeffeedfacedeadbeefabaddad2", 78 "8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5", 79 "1c5afe9760d3932f3c9a878aac3dc3de", 80 }, 81 } 82 83 func gcmGHASH(y, h *[blockSize]byte, a, c []byte) { 84 var p [blockSize]byte 85 Ghash(y, h, a) 86 Ghash(y, h, c) 87 binary.BigEndian.PutUint32(p[4:], uint32(len(a))<<3) 88 binary.BigEndian.PutUint32(p[12:], uint32(len(c))<<3) 89 Ghash(y, h, p[:]) 90 } 91 92 func TestGHASH(t *testing.T) { 93 for i, vec := range ghashVectors { 94 hh, err := hex.DecodeString(vec.h[:]) 95 if err != nil { 96 t.Fatal(err) 97 } 98 a, err := hex.DecodeString(vec.a[:]) 99 if err != nil { 100 t.Fatal(err) 101 } 102 c, err := hex.DecodeString(vec.c[:]) 103 if err != nil { 104 t.Fatal(err) 105 } 106 yy, err := hex.DecodeString(vec.y[:]) 107 if err != nil { 108 t.Fatal(err) 109 } 110 111 var h, y [blockSize]byte 112 copy(h[:], hh) 113 114 gcmGHASH(&y, &h, a, c) 115 assertEqual(t, i, yy[:], y[:]) 116 } 117 } 118 119 func assertEqual(t *testing.T, idx int, expected, actual []byte) { 120 if !bytes.Equal(expected, actual) { 121 for i, v := range actual { 122 if expected[i] != v { 123 t.Errorf("[%d] first mismatch at offset: %d (%02x != %02x)", idx, i, expected[i], v) 124 break 125 } 126 } 127 t.Errorf("expected: %s", hex.Dump(expected)) 128 t.Errorf("actual: %s", hex.Dump(actual)) 129 t.FailNow() 130 } 131 } 132 133 var ghashBenchOutput [blockSize]byte 134 135 func BenchmarkGHASH(b *testing.B) { 136 var y, h [blockSize]byte 137 var buf [8192]byte 138 139 if _, err := rand.Read(buf[:]); err != nil { 140 b.Error(err) 141 b.Fail() 142 } 143 if _, err := rand.Read(h[:]); err != nil { 144 b.Error(err) 145 b.Fail() 146 } 147 148 b.SetBytes(int64(len(buf))) 149 b.ResetTimer() 150 for i := 0; i < b.N; i++ { 151 Ghash(&y, &h, buf[:]) 152 } 153 b.StopTimer() 154 copy(ghashBenchOutput[:], y[:]) 155 }