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  }