github.com/icodeface/tls@v0.0.0-20230910023335-34df9250cd12/internal/x/crypto/hkdf/hkdf_test.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  package hkdf
     5  
     6  import (
     7  	"bytes"
     8  	"crypto/md5"
     9  	"crypto/sha1"
    10  	"crypto/sha256"
    11  	"crypto/sha512"
    12  	"hash"
    13  	"io"
    14  	"testing"
    15  )
    16  
    17  type hkdfTest struct {
    18  	hash   func() hash.Hash
    19  	master []byte
    20  	salt   []byte
    21  	prk    []byte
    22  	info   []byte
    23  	out    []byte
    24  }
    25  
    26  var hkdfTests = []hkdfTest{
    27  	// Tests from RFC 5869
    28  	{
    29  		sha256.New,
    30  		[]byte{
    31  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
    32  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
    33  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
    34  		},
    35  		[]byte{
    36  			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    37  			0x08, 0x09, 0x0a, 0x0b, 0x0c,
    38  		},
    39  		[]byte{
    40  			0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf,
    41  			0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
    42  			0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
    43  			0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5,
    44  		},
    45  		[]byte{
    46  			0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
    47  			0xf8, 0xf9,
    48  		},
    49  		[]byte{
    50  			0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a,
    51  			0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a,
    52  			0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
    53  			0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf,
    54  			0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18,
    55  			0x58, 0x65,
    56  		},
    57  	},
    58  	{
    59  		sha256.New,
    60  		[]byte{
    61  			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    62  			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    63  			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    64  			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    65  			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    66  			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    67  			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    68  			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
    69  			0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
    70  			0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
    71  		},
    72  		[]byte{
    73  			0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
    74  			0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
    75  			0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
    76  			0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
    77  			0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    78  			0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
    79  			0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
    80  			0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
    81  			0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
    82  			0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
    83  		},
    84  		[]byte{
    85  			0x06, 0xa6, 0xb8, 0x8c, 0x58, 0x53, 0x36, 0x1a,
    86  			0x06, 0x10, 0x4c, 0x9c, 0xeb, 0x35, 0xb4, 0x5c,
    87  			0xef, 0x76, 0x00, 0x14, 0x90, 0x46, 0x71, 0x01,
    88  			0x4a, 0x19, 0x3f, 0x40, 0xc1, 0x5f, 0xc2, 0x44,
    89  		},
    90  		[]byte{
    91  			0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
    92  			0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
    93  			0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
    94  			0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
    95  			0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
    96  			0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
    97  			0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
    98  			0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
    99  			0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
   100  			0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
   101  		},
   102  		[]byte{
   103  			0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1,
   104  			0xc8, 0xe7, 0xf7, 0x8c, 0x59, 0x6a, 0x49, 0x34,
   105  			0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
   106  			0xa0, 0x50, 0xcc, 0x4c, 0x19, 0xaf, 0xa9, 0x7c,
   107  			0x59, 0x04, 0x5a, 0x99, 0xca, 0xc7, 0x82, 0x72,
   108  			0x71, 0xcb, 0x41, 0xc6, 0x5e, 0x59, 0x0e, 0x09,
   109  			0xda, 0x32, 0x75, 0x60, 0x0c, 0x2f, 0x09, 0xb8,
   110  			0x36, 0x77, 0x93, 0xa9, 0xac, 0xa3, 0xdb, 0x71,
   111  			0xcc, 0x30, 0xc5, 0x81, 0x79, 0xec, 0x3e, 0x87,
   112  			0xc1, 0x4c, 0x01, 0xd5, 0xc1, 0xf3, 0x43, 0x4f,
   113  			0x1d, 0x87,
   114  		},
   115  	},
   116  	{
   117  		sha256.New,
   118  		[]byte{
   119  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
   120  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
   121  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
   122  		},
   123  		[]byte{},
   124  		[]byte{
   125  			0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16,
   126  			0x7f, 0x33, 0xa9, 0x1d, 0x6f, 0x64, 0x8b, 0xdf,
   127  			0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77,
   128  			0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04,
   129  		},
   130  		[]byte{},
   131  		[]byte{
   132  			0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f,
   133  			0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
   134  			0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
   135  			0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
   136  			0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a,
   137  			0x96, 0xc8,
   138  		},
   139  	},
   140  	{
   141  		sha256.New,
   142  		[]byte{
   143  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
   144  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
   145  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
   146  		},
   147  		nil,
   148  		[]byte{
   149  			0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16,
   150  			0x7f, 0x33, 0xa9, 0x1d, 0x6f, 0x64, 0x8b, 0xdf,
   151  			0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77,
   152  			0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04,
   153  		},
   154  		nil,
   155  		[]byte{
   156  			0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f,
   157  			0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
   158  			0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
   159  			0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
   160  			0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a,
   161  			0x96, 0xc8,
   162  		},
   163  	},
   164  	{
   165  		sha1.New,
   166  		[]byte{
   167  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
   168  			0x0b, 0x0b, 0x0b,
   169  		},
   170  		[]byte{
   171  			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
   172  			0x08, 0x09, 0x0a, 0x0b, 0x0c,
   173  		},
   174  		[]byte{
   175  			0x9b, 0x6c, 0x18, 0xc4, 0x32, 0xa7, 0xbf, 0x8f,
   176  			0x0e, 0x71, 0xc8, 0xeb, 0x88, 0xf4, 0xb3, 0x0b,
   177  			0xaa, 0x2b, 0xa2, 0x43,
   178  		},
   179  		[]byte{
   180  			0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
   181  			0xf8, 0xf9,
   182  		},
   183  		[]byte{
   184  			0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69,
   185  			0x33, 0x06, 0x8b, 0x56, 0xef, 0xa5, 0xad, 0x81,
   186  			0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15,
   187  			0x68, 0xa9, 0xcd, 0xd4, 0xf1, 0x55, 0xfd, 0xa2,
   188  			0xc2, 0x2e, 0x42, 0x24, 0x78, 0xd3, 0x05, 0xf3,
   189  			0xf8, 0x96,
   190  		},
   191  	},
   192  	{
   193  		sha1.New,
   194  		[]byte{
   195  			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
   196  			0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   197  			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
   198  			0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
   199  			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
   200  			0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   201  			0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
   202  			0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
   203  			0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
   204  			0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
   205  		},
   206  		[]byte{
   207  			0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
   208  			0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
   209  			0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
   210  			0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
   211  			0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
   212  			0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
   213  			0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
   214  			0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
   215  			0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
   216  			0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
   217  		},
   218  		[]byte{
   219  			0x8a, 0xda, 0xe0, 0x9a, 0x2a, 0x30, 0x70, 0x59,
   220  			0x47, 0x8d, 0x30, 0x9b, 0x26, 0xc4, 0x11, 0x5a,
   221  			0x22, 0x4c, 0xfa, 0xf6,
   222  		},
   223  		[]byte{
   224  			0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
   225  			0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
   226  			0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
   227  			0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
   228  			0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
   229  			0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
   230  			0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
   231  			0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
   232  			0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
   233  			0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
   234  		},
   235  		[]byte{
   236  			0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7,
   237  			0xc9, 0xf1, 0x2c, 0xd5, 0x91, 0x2a, 0x06, 0xeb,
   238  			0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19,
   239  			0x1f, 0xe4, 0x30, 0x56, 0x73, 0xba, 0x2f, 0xfe,
   240  			0x8f, 0xa3, 0xf1, 0xa4, 0xe5, 0xad, 0x79, 0xf3,
   241  			0xf3, 0x34, 0xb3, 0xb2, 0x02, 0xb2, 0x17, 0x3c,
   242  			0x48, 0x6e, 0xa3, 0x7c, 0xe3, 0xd3, 0x97, 0xed,
   243  			0x03, 0x4c, 0x7f, 0x9d, 0xfe, 0xb1, 0x5c, 0x5e,
   244  			0x92, 0x73, 0x36, 0xd0, 0x44, 0x1f, 0x4c, 0x43,
   245  			0x00, 0xe2, 0xcf, 0xf0, 0xd0, 0x90, 0x0b, 0x52,
   246  			0xd3, 0xb4,
   247  		},
   248  	},
   249  	{
   250  		sha1.New,
   251  		[]byte{
   252  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
   253  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
   254  			0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
   255  		},
   256  		[]byte{},
   257  		[]byte{
   258  			0xda, 0x8c, 0x8a, 0x73, 0xc7, 0xfa, 0x77, 0x28,
   259  			0x8e, 0xc6, 0xf5, 0xe7, 0xc2, 0x97, 0x78, 0x6a,
   260  			0xa0, 0xd3, 0x2d, 0x01,
   261  		},
   262  		[]byte{},
   263  		[]byte{
   264  			0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61,
   265  			0xd1, 0xe5, 0x52, 0x98, 0xda, 0x9d, 0x05, 0x06,
   266  			0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06,
   267  			0xe0, 0x7b, 0x6b, 0x87, 0xe8, 0xdf, 0x21, 0xd0,
   268  			0xea, 0x00, 0x03, 0x3d, 0xe0, 0x39, 0x84, 0xd3,
   269  			0x49, 0x18,
   270  		},
   271  	},
   272  	{
   273  		sha1.New,
   274  		[]byte{
   275  			0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
   276  			0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
   277  			0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
   278  		},
   279  		nil,
   280  		[]byte{
   281  			0x2a, 0xdc, 0xca, 0xda, 0x18, 0x77, 0x9e, 0x7c,
   282  			0x20, 0x77, 0xad, 0x2e, 0xb1, 0x9d, 0x3f, 0x3e,
   283  			0x73, 0x13, 0x85, 0xdd,
   284  		},
   285  		nil,
   286  		[]byte{
   287  			0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3,
   288  			0x50, 0x0d, 0x63, 0x6a, 0x62, 0xf6, 0x4f, 0x0a,
   289  			0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, 0xd4, 0x23,
   290  			0xb0, 0xd1, 0xf2, 0x7e, 0xbb, 0xa6, 0xf5, 0xe5,
   291  			0x67, 0x3a, 0x08, 0x1d, 0x70, 0xcc, 0xe7, 0xac,
   292  			0xfc, 0x48,
   293  		},
   294  	},
   295  }
   296  
   297  func TestHKDF(t *testing.T) {
   298  	for i, tt := range hkdfTests {
   299  		prk := Extract(tt.hash, tt.master, tt.salt)
   300  		if !bytes.Equal(prk, tt.prk) {
   301  			t.Errorf("test %d: incorrect PRK: have %v, need %v.", i, prk, tt.prk)
   302  		}
   303  
   304  		hkdf := New(tt.hash, tt.master, tt.salt, tt.info)
   305  		out := make([]byte, len(tt.out))
   306  
   307  		n, err := io.ReadFull(hkdf, out)
   308  		if n != len(tt.out) || err != nil {
   309  			t.Errorf("test %d: not enough output bytes: %d.", i, n)
   310  		}
   311  
   312  		if !bytes.Equal(out, tt.out) {
   313  			t.Errorf("test %d: incorrect output: have %v, need %v.", i, out, tt.out)
   314  		}
   315  
   316  		hkdf = Expand(tt.hash, prk, tt.info)
   317  
   318  		n, err = io.ReadFull(hkdf, out)
   319  		if n != len(tt.out) || err != nil {
   320  			t.Errorf("test %d: not enough output bytes from Expand: %d.", i, n)
   321  		}
   322  
   323  		if !bytes.Equal(out, tt.out) {
   324  			t.Errorf("test %d: incorrect output from Expand: have %v, need %v.", i, out, tt.out)
   325  		}
   326  	}
   327  }
   328  
   329  func TestHKDFMultiRead(t *testing.T) {
   330  	for i, tt := range hkdfTests {
   331  		hkdf := New(tt.hash, tt.master, tt.salt, tt.info)
   332  		out := make([]byte, len(tt.out))
   333  
   334  		for b := 0; b < len(tt.out); b++ {
   335  			n, err := io.ReadFull(hkdf, out[b:b+1])
   336  			if n != 1 || err != nil {
   337  				t.Errorf("test %d.%d: not enough output bytes: have %d, need %d .", i, b, n, len(tt.out))
   338  			}
   339  		}
   340  
   341  		if !bytes.Equal(out, tt.out) {
   342  			t.Errorf("test %d: incorrect output: have %v, need %v.", i, out, tt.out)
   343  		}
   344  	}
   345  }
   346  
   347  func TestHKDFLimit(t *testing.T) {
   348  	hash := sha1.New
   349  	master := []byte{0x00, 0x01, 0x02, 0x03}
   350  	info := []byte{}
   351  
   352  	hkdf := New(hash, master, nil, info)
   353  	limit := hash().Size() * 255
   354  	out := make([]byte, limit)
   355  
   356  	// The maximum output bytes should be extractable
   357  	n, err := io.ReadFull(hkdf, out)
   358  	if n != limit || err != nil {
   359  		t.Errorf("not enough output bytes: %d, %v.", n, err)
   360  	}
   361  
   362  	// Reading one more should fail
   363  	n, err = io.ReadFull(hkdf, make([]byte, 1))
   364  	if n > 0 || err == nil {
   365  		t.Errorf("key expansion overflowed: n = %d, err = %v", n, err)
   366  	}
   367  }
   368  
   369  func Benchmark16ByteMD5Single(b *testing.B) {
   370  	benchmarkHKDFSingle(md5.New, 16, b)
   371  }
   372  
   373  func Benchmark20ByteSHA1Single(b *testing.B) {
   374  	benchmarkHKDFSingle(sha1.New, 20, b)
   375  }
   376  
   377  func Benchmark32ByteSHA256Single(b *testing.B) {
   378  	benchmarkHKDFSingle(sha256.New, 32, b)
   379  }
   380  
   381  func Benchmark64ByteSHA512Single(b *testing.B) {
   382  	benchmarkHKDFSingle(sha512.New, 64, b)
   383  }
   384  
   385  func Benchmark8ByteMD5Stream(b *testing.B) {
   386  	benchmarkHKDFStream(md5.New, 8, b)
   387  }
   388  
   389  func Benchmark16ByteMD5Stream(b *testing.B) {
   390  	benchmarkHKDFStream(md5.New, 16, b)
   391  }
   392  
   393  func Benchmark8ByteSHA1Stream(b *testing.B) {
   394  	benchmarkHKDFStream(sha1.New, 8, b)
   395  }
   396  
   397  func Benchmark20ByteSHA1Stream(b *testing.B) {
   398  	benchmarkHKDFStream(sha1.New, 20, b)
   399  }
   400  
   401  func Benchmark8ByteSHA256Stream(b *testing.B) {
   402  	benchmarkHKDFStream(sha256.New, 8, b)
   403  }
   404  
   405  func Benchmark32ByteSHA256Stream(b *testing.B) {
   406  	benchmarkHKDFStream(sha256.New, 32, b)
   407  }
   408  
   409  func Benchmark8ByteSHA512Stream(b *testing.B) {
   410  	benchmarkHKDFStream(sha512.New, 8, b)
   411  }
   412  
   413  func Benchmark64ByteSHA512Stream(b *testing.B) {
   414  	benchmarkHKDFStream(sha512.New, 64, b)
   415  }
   416  
   417  func benchmarkHKDFSingle(hasher func() hash.Hash, block int, b *testing.B) {
   418  	master := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}
   419  	salt := []byte{0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}
   420  	info := []byte{0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27}
   421  	out := make([]byte, block)
   422  
   423  	b.SetBytes(int64(block))
   424  	b.ResetTimer()
   425  
   426  	for i := 0; i < b.N; i++ {
   427  		hkdf := New(hasher, master, salt, info)
   428  		io.ReadFull(hkdf, out)
   429  	}
   430  }
   431  
   432  func benchmarkHKDFStream(hasher func() hash.Hash, block int, b *testing.B) {
   433  	master := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}
   434  	salt := []byte{0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}
   435  	info := []byte{0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27}
   436  	out := make([]byte, block)
   437  
   438  	b.SetBytes(int64(block))
   439  	b.ResetTimer()
   440  
   441  	hkdf := New(hasher, master, salt, info)
   442  	for i := 0; i < b.N; i++ {
   443  		_, err := io.ReadFull(hkdf, out)
   444  		if err != nil {
   445  			hkdf = New(hasher, master, salt, info)
   446  			i--
   447  		}
   448  	}
   449  }