norx_test.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // norx_test.go - NORX 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. package norx
  8. import (
  9. "bytes"
  10. "crypto/rand"
  11. "fmt"
  12. "testing"
  13. "github.com/stretchr/testify/require"
  14. )
  15. var (
  16. katCipherTexts = map[string][]byte{
  17. "NORX64-4-1": kat6441,
  18. "NORX64-6-1": kat6461,
  19. }
  20. testVectorCipherTexts = map[string][]byte{
  21. "NORX64-4-1": vec6441,
  22. "NORX64-6-1": vec6461,
  23. }
  24. canAccelerate bool
  25. )
  26. func mustInitHardwareAcceleration() {
  27. initHardwareAcceleration()
  28. if !IsHardwareAccelerated() {
  29. panic("initHardwareAcceleration() failed")
  30. }
  31. }
  32. func TestKAT(t *testing.T) {
  33. forceDisableHardwareAcceleration()
  34. doTestKAT(t)
  35. if !canAccelerate {
  36. t.Log("Hardware acceleration not supported on this host.")
  37. return
  38. }
  39. mustInitHardwareAcceleration()
  40. doTestKAT(t)
  41. }
  42. func doTestKAT(t *testing.T) {
  43. testRounds := []int{4, 6}
  44. impl := "_" + hardwareAccelImpl.name
  45. for _, l := range testRounds {
  46. n := fmt.Sprintf("NORX64-%d-1", l)
  47. t.Run(n+"_Vector"+impl, func(t *testing.T) { doTestVector(t, n, l) })
  48. t.Run(n+"_KAT"+impl, func(t *testing.T) { doTestKATFull(t, n, l) })
  49. }
  50. }
  51. func doTestVector(t *testing.T, vn string, l int) {
  52. require := require.New(t)
  53. var k, n [32]byte
  54. var a, m, z [128]byte
  55. for i := range k {
  56. k[i] = byte(i)
  57. n[i] = byte(i + 32)
  58. }
  59. for i := range a {
  60. a[i] = byte(i)
  61. m[i] = byte(i)
  62. z[i] = byte(i)
  63. }
  64. ctVec := testVectorCipherTexts[vn]
  65. if ctVec == nil {
  66. panic("missing test vector cipher text")
  67. }
  68. aead := newTestAEAD(k[:], l)
  69. require.Equal(NonceSize, aead.NonceSize(), "NonceSize()")
  70. require.Equal(TagSize, aead.Overhead(), "Overhead()")
  71. ct := aead.Seal(nil, n[:], m[:], a[:], z[:])
  72. require.Equal(ctVec, ct, "aeadSeal()")
  73. pt, err := aead.Open(nil, n[:], ct, a[:], z[:])
  74. require.NoError(err, "Open()")
  75. require.Equal(m[:], pt, "Open()")
  76. }
  77. func doTestKATFull(t *testing.T, vn string, l int) {
  78. require := require.New(t)
  79. var w, h [256]byte
  80. var k, n [32]byte
  81. for i := range w {
  82. w[i] = byte(255 & (i*197 + 123))
  83. }
  84. for i := range h {
  85. h[i] = byte(255 & (i*193 + 123))
  86. }
  87. for i := range k {
  88. k[i] = byte(255 & (i*191 + 123))
  89. }
  90. for i := range n {
  91. n[i] = byte(255 & (i*181 + 123))
  92. }
  93. var katAcc []byte
  94. kat := katCipherTexts[vn]
  95. katOff := 0
  96. if kat == nil {
  97. panic("missing KAT cipher texts")
  98. }
  99. aead := newTestAEAD(k[:], l).ToRuntime()
  100. require.Equal(NonceSize, aead.NonceSize(), "NonceSize()")
  101. require.Equal(TagSize, aead.Overhead(), "Overhead()")
  102. for i := range w {
  103. katAcc = aead.Seal(katAcc, n[:], w[:i], h[:i])
  104. c := katAcc[katOff:]
  105. require.Len(c, i+TagSize, "Seal(): len(c) %d", i)
  106. require.Equal(kat[katOff:katOff+len(c)], c)
  107. m, err := aead.Open(nil, n[:], c, h[:i])
  108. require.NoError(err, "Open(): %d", i)
  109. require.Len(m, i, "Open(): len(m) %d", i)
  110. if len(m) != 0 {
  111. require.Equal(m, w[:i], "Open(): m %d", i)
  112. }
  113. katOff += len(c)
  114. }
  115. require.Equal(kat, katAcc, "Final concatenated cipher texts.")
  116. }
  117. func newTestAEAD(k []byte, l int) *AEAD {
  118. switch l {
  119. case 4:
  120. return New6441(k[:])
  121. case 6:
  122. return New6461(k[:])
  123. default:
  124. panic("unsupported round parameter")
  125. }
  126. }
  127. func BenchmarkNORX(b *testing.B) {
  128. forceDisableHardwareAcceleration()
  129. doBenchmarkNORX(b)
  130. if !canAccelerate {
  131. b.Log("Hardware acceleration not supported on this host.")
  132. return
  133. }
  134. mustInitHardwareAcceleration()
  135. doBenchmarkNORX(b)
  136. }
  137. func doBenchmarkNORX(b *testing.B) {
  138. benchRounds := []int{4, 6}
  139. benchSizes := []int{8, 64, 576, 1536, 4096, 1024768}
  140. impl := "_" + hardwareAccelImpl.name
  141. for _, l := range benchRounds {
  142. n := fmt.Sprintf("NORX64-%d-1", l)
  143. for _, sz := range benchSizes {
  144. bn := n + impl + "_"
  145. sn := fmt.Sprintf("_%d", sz)
  146. b.Run(bn+"Encrypt"+sn, func(b *testing.B) { doBenchmarkAEADEncrypt(b, l, sz) })
  147. b.Run(bn+"Decrypt"+sn, func(b *testing.B) { doBenchmarkAEADDecrypt(b, l, sz) })
  148. }
  149. }
  150. }
  151. func doBenchmarkAEADEncrypt(b *testing.B, l, sz int) {
  152. b.StopTimer()
  153. b.SetBytes(int64(sz))
  154. nonce, key := make([]byte, NonceSize), make([]byte, KeySize)
  155. m, c := make([]byte, sz), make([]byte, 0, sz+TagSize)
  156. rand.Read(nonce)
  157. rand.Read(key)
  158. rand.Read(m)
  159. b.StartTimer()
  160. for i := 0; i < b.N; i++ {
  161. c = c[:0]
  162. c = aeadEncrypt(l, c, nil, m, nil, nonce, key)
  163. if len(c) != sz+TagSize {
  164. b.Fatalf("aeadEncrypt failed")
  165. }
  166. }
  167. }
  168. func doBenchmarkAEADDecrypt(b *testing.B, l, sz int) {
  169. b.StopTimer()
  170. b.SetBytes(int64(sz))
  171. nonce, key := make([]byte, NonceSize), make([]byte, KeySize)
  172. m, c, d := make([]byte, sz), make([]byte, 0, sz+TagSize), make([]byte, 0, sz)
  173. rand.Read(nonce)
  174. rand.Read(key)
  175. rand.Read(m)
  176. c = aeadEncrypt(l, c, nil, m, nil, nonce, key)
  177. b.StartTimer()
  178. for i := 0; i < b.N; i++ {
  179. d = d[:0]
  180. var ok bool
  181. d, ok = aeadDecrypt(l, d, nil, c, nil, nonce, key)
  182. if !ok {
  183. b.Fatalf("aeadDecrypt failed")
  184. }
  185. }
  186. b.StopTimer()
  187. if !bytes.Equal(m, d) {
  188. b.Fatalf("aeadDecrypt output mismatch")
  189. }
  190. }
  191. func init() {
  192. canAccelerate = IsHardwareAccelerated()
  193. }