github.com/mad-day/Yawning-crypto@v0.0.0-20190711051033-5a5f8cca32ec/morus/morus_test.go (about)

     1  // morus_test.go - MORUS tests
     2  //
     3  // To the extent possible under law, Yawning Angel has waived all copyright
     4  // and related or neighboring rights to the software, using the Creative
     5  // Commons "CC0" public domain dedication. See LICENSE or
     6  // <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
     7  
     8  package morus
     9  
    10  import (
    11  	"bytes"
    12  	"crypto/rand"
    13  	"fmt"
    14  	"testing"
    15  
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  var canAccelerate bool
    20  
    21  func mustInitHardwareAcceleration() {
    22  	initHardwareAcceleration()
    23  	if !IsHardwareAccelerated() {
    24  		panic("initHardwareAcceleration() failed")
    25  	}
    26  }
    27  
    28  func TestKAT(t *testing.T) {
    29  	forceDisableHardwareAcceleration()
    30  	impl := "_" + hardwareAccelImpl.name
    31  	t.Run("MORUS-1280-256_KAT"+impl, func(t *testing.T) { doTestKAT(t) })
    32  
    33  	if !canAccelerate {
    34  		t.Log("Hardware acceleration not supported on this host.")
    35  		return
    36  	}
    37  	mustInitHardwareAcceleration()
    38  	impl = "_" + hardwareAccelImpl.name
    39  	t.Run("MORUS-1280-256_KAT"+impl, func(t *testing.T) { doTestKAT(t) })
    40  }
    41  
    42  func doTestKAT(t *testing.T) {
    43  	require := require.New(t)
    44  
    45  	// There are no official test vectors, so the "known good" values used
    46  	// by this test were generated by combining `genkat.c` from the NORX
    47  	// source package and `supercop-20171218/crypto_aead/morus1280256v2/ref64`.
    48  
    49  	var w, h [256]byte
    50  	var k [32]byte
    51  	var n [16]byte
    52  
    53  	for i := range w {
    54  		w[i] = byte(255 & (i*197 + 123))
    55  	}
    56  	for i := range h {
    57  		h[i] = byte(255 & (i*193 + 123))
    58  	}
    59  	for i := range k {
    60  		k[i] = byte(255 & (i*191 + 123))
    61  	}
    62  	for i := range n {
    63  		n[i] = byte(255 & (i*181 + 123))
    64  	}
    65  
    66  	var katAcc []byte
    67  	katOff := 0
    68  
    69  	aead := New(k[:])
    70  	require.Equal(NonceSize, aead.NonceSize(), "NonceSize()")
    71  	require.Equal(TagSize, aead.Overhead(), "Overhead()")
    72  
    73  	for i := range w {
    74  		katAcc = aead.Seal(katAcc, n[:], w[:i], h[:i])
    75  		c := katAcc[katOff:]
    76  		require.Len(c, i+TagSize, "Seal(): len(c) %d", i)
    77  		require.Equal(kat1280256[katOff:katOff+len(c)], c, "Seal(): %d", i)
    78  
    79  		m, err := aead.Open(nil, n[:], c, h[:i])
    80  		require.NoError(err, "Open(): %d", i)
    81  		require.Len(m, i, "Open(): len(m) %d", i)
    82  		if len(m) != 0 {
    83  			require.Equal(m, w[:i], "Open(): m %d", i)
    84  		}
    85  		katOff += len(c)
    86  
    87  		// Test malformed ciphertext.
    88  		badC := append([]byte{}, c...)
    89  		badC[i] ^= 0x23
    90  		m, err = aead.Open(nil, n[:], badC, h[:i])
    91  		require.Error(err, "Open(Bad c): %d", i)
    92  		require.Nil(m, "Open(Bad c): len(m) %d", i)
    93  
    94  		// Test malformed AD.
    95  		if i > 0 {
    96  			badH := append([]byte{}, h[:i]...)
    97  			badH[i-1] ^= 0x23
    98  			m, err = aead.Open(nil, n[:], c, badH)
    99  			require.Error(err, "Open(Bad h): %d", i)
   100  			require.Nil(m, "Open(Bad h): len(m) %d", i)
   101  		}
   102  	}
   103  	require.Equal(kat1280256, katAcc, "Final concatenated cipher texts.")
   104  }
   105  
   106  func BenchmarkMORUS(b *testing.B) {
   107  	forceDisableHardwareAcceleration()
   108  	doBenchmarkMORUS(b)
   109  
   110  	if !canAccelerate {
   111  		b.Log("Hardware acceleration not supported on this host.")
   112  		return
   113  	}
   114  	mustInitHardwareAcceleration()
   115  	doBenchmarkMORUS(b)
   116  }
   117  
   118  func doBenchmarkMORUS(b *testing.B) {
   119  	benchSizes := []int{8, 32, 64, 576, 1536, 4096, 1024768}
   120  	impl := "_" + hardwareAccelImpl.name
   121  
   122  	for _, sz := range benchSizes {
   123  		bn := "MORUS-1280-256" + impl + "_"
   124  		sn := fmt.Sprintf("_%d", sz)
   125  		b.Run(bn+"Encrypt"+sn, func(b *testing.B) { doBenchmarkAEADEncrypt(b, sz) })
   126  		b.Run(bn+"Decrypt"+sn, func(b *testing.B) { doBenchmarkAEADDecrypt(b, sz) })
   127  	}
   128  }
   129  
   130  func doBenchmarkAEADEncrypt(b *testing.B, sz int) {
   131  	b.StopTimer()
   132  	b.SetBytes(int64(sz))
   133  
   134  	nonce, key := make([]byte, NonceSize), make([]byte, KeySize)
   135  	m, c := make([]byte, sz), make([]byte, 0, sz+TagSize)
   136  	rand.Read(nonce)
   137  	rand.Read(key)
   138  	rand.Read(m)
   139  
   140  	b.StartTimer()
   141  	for i := 0; i < b.N; i++ {
   142  		c = c[:0]
   143  
   144  		c = hardwareAccelImpl.aeadEncryptFn(c, m, nil, nonce, key)
   145  		if len(c) != sz+TagSize {
   146  			b.Fatalf("aeadEncrypt failed")
   147  		}
   148  	}
   149  }
   150  
   151  func doBenchmarkAEADDecrypt(b *testing.B, sz int) {
   152  	b.StopTimer()
   153  	b.SetBytes(int64(sz))
   154  
   155  	nonce, key := make([]byte, NonceSize), make([]byte, KeySize)
   156  	m, c, d := make([]byte, sz), make([]byte, 0, sz+TagSize), make([]byte, 0, sz)
   157  	rand.Read(nonce)
   158  	rand.Read(key)
   159  	rand.Read(m)
   160  
   161  	c = hardwareAccelImpl.aeadEncryptFn(c, m, nil, nonce, key)
   162  	b.StartTimer()
   163  	for i := 0; i < b.N; i++ {
   164  		d = d[:0]
   165  
   166  		var ok bool
   167  		d, ok = hardwareAccelImpl.aeadDecryptFn(d, c, nil, nonce, key)
   168  		if !ok {
   169  			b.Fatalf("aeadDecrypt failed")
   170  		}
   171  	}
   172  	b.StopTimer()
   173  
   174  	if !bytes.Equal(m, d) {
   175  		b.Fatalf("aeadDecrypt output mismatch")
   176  	}
   177  }
   178  
   179  func init() {
   180  	canAccelerate = IsHardwareAccelerated()
   181  }