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

     1  // Copyright 2016 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  
     5  package chacha20poly1305
     6  
     7  import (
     8  	"bytes"
     9  	cr "crypto/rand"
    10  	"encoding/hex"
    11  	mr "math/rand"
    12  	"testing"
    13  )
    14  
    15  func TestVectors(t *testing.T) {
    16  	for i, test := range chacha20Poly1305Tests {
    17  		key, _ := hex.DecodeString(test.key)
    18  		nonce, _ := hex.DecodeString(test.nonce)
    19  		ad, _ := hex.DecodeString(test.aad)
    20  		plaintext, _ := hex.DecodeString(test.plaintext)
    21  
    22  		aead, err := New(key)
    23  		if err != nil {
    24  			t.Fatal(err)
    25  		}
    26  
    27  		ct := aead.Seal(nil, nonce, plaintext, ad)
    28  		if ctHex := hex.EncodeToString(ct); ctHex != test.out {
    29  			t.Errorf("#%d: got %s, want %s", i, ctHex, test.out)
    30  			continue
    31  		}
    32  
    33  		plaintext2, err := aead.Open(nil, nonce, ct, ad)
    34  		if err != nil {
    35  			t.Errorf("#%d: Open failed", i)
    36  			continue
    37  		}
    38  
    39  		if !bytes.Equal(plaintext, plaintext2) {
    40  			t.Errorf("#%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext)
    41  			continue
    42  		}
    43  
    44  		if len(ad) > 0 {
    45  			alterAdIdx := mr.Intn(len(ad))
    46  			ad[alterAdIdx] ^= 0x80
    47  			if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
    48  				t.Errorf("#%d: Open was successful after altering additional data", i)
    49  			}
    50  			ad[alterAdIdx] ^= 0x80
    51  		}
    52  
    53  		alterNonceIdx := mr.Intn(aead.NonceSize())
    54  		nonce[alterNonceIdx] ^= 0x80
    55  		if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
    56  			t.Errorf("#%d: Open was successful after altering nonce", i)
    57  		}
    58  		nonce[alterNonceIdx] ^= 0x80
    59  
    60  		alterCtIdx := mr.Intn(len(ct))
    61  		ct[alterCtIdx] ^= 0x80
    62  		if _, err := aead.Open(nil, nonce, ct, ad); err == nil {
    63  			t.Errorf("#%d: Open was successful after altering ciphertext", i)
    64  		}
    65  		ct[alterCtIdx] ^= 0x80
    66  	}
    67  }
    68  
    69  func TestRandom(t *testing.T) {
    70  	// Some random tests to verify Open(Seal) == Plaintext
    71  	for i := 0; i < 256; i++ {
    72  		var nonce [12]byte
    73  		var key [32]byte
    74  
    75  		al := mr.Intn(128)
    76  		pl := mr.Intn(16384)
    77  		ad := make([]byte, al)
    78  		plaintext := make([]byte, pl)
    79  		cr.Read(key[:])
    80  		cr.Read(nonce[:])
    81  		cr.Read(ad)
    82  		cr.Read(plaintext)
    83  
    84  		aead, err := New(key[:])
    85  		if err != nil {
    86  			t.Fatal(err)
    87  		}
    88  
    89  		ct := aead.Seal(nil, nonce[:], plaintext, ad)
    90  
    91  		plaintext2, err := aead.Open(nil, nonce[:], ct, ad)
    92  		if err != nil {
    93  			t.Errorf("Random #%d: Open failed", i)
    94  			continue
    95  		}
    96  
    97  		if !bytes.Equal(plaintext, plaintext2) {
    98  			t.Errorf("Random #%d: plaintext's don't match: got %x vs %x", i, plaintext2, plaintext)
    99  			continue
   100  		}
   101  
   102  		if len(ad) > 0 {
   103  			alterAdIdx := mr.Intn(len(ad))
   104  			ad[alterAdIdx] ^= 0x80
   105  			if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
   106  				t.Errorf("Random #%d: Open was successful after altering additional data", i)
   107  			}
   108  			ad[alterAdIdx] ^= 0x80
   109  		}
   110  
   111  		alterNonceIdx := mr.Intn(aead.NonceSize())
   112  		nonce[alterNonceIdx] ^= 0x80
   113  		if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
   114  			t.Errorf("Random #%d: Open was successful after altering nonce", i)
   115  		}
   116  		nonce[alterNonceIdx] ^= 0x80
   117  
   118  		alterCtIdx := mr.Intn(len(ct))
   119  		ct[alterCtIdx] ^= 0x80
   120  		if _, err := aead.Open(nil, nonce[:], ct, ad); err == nil {
   121  			t.Errorf("Random #%d: Open was successful after altering ciphertext", i)
   122  		}
   123  		ct[alterCtIdx] ^= 0x80
   124  	}
   125  }
   126  
   127  func benchamarkChaCha20Poly1305Seal(b *testing.B, buf []byte) {
   128  	b.SetBytes(int64(len(buf)))
   129  
   130  	var key [32]byte
   131  	var nonce [12]byte
   132  	var ad [13]byte
   133  	var out []byte
   134  
   135  	aead, _ := New(key[:])
   136  	b.ResetTimer()
   137  	for i := 0; i < b.N; i++ {
   138  		out = aead.Seal(out[:0], nonce[:], buf[:], ad[:])
   139  	}
   140  }
   141  
   142  func benchamarkChaCha20Poly1305Open(b *testing.B, buf []byte) {
   143  	b.SetBytes(int64(len(buf)))
   144  
   145  	var key [32]byte
   146  	var nonce [12]byte
   147  	var ad [13]byte
   148  	var ct []byte
   149  	var out []byte
   150  
   151  	aead, _ := New(key[:])
   152  	ct = aead.Seal(ct[:0], nonce[:], buf[:], ad[:])
   153  
   154  	b.ResetTimer()
   155  	for i := 0; i < b.N; i++ {
   156  		out, _ = aead.Open(out[:0], nonce[:], ct[:], ad[:])
   157  	}
   158  }
   159  
   160  func BenchmarkChacha20Poly1305Open_64(b *testing.B) {
   161  	benchamarkChaCha20Poly1305Open(b, make([]byte, 64))
   162  }
   163  
   164  func BenchmarkChacha20Poly1305Seal_64(b *testing.B) {
   165  	benchamarkChaCha20Poly1305Seal(b, make([]byte, 64))
   166  }
   167  
   168  func BenchmarkChacha20Poly1305Open_1350(b *testing.B) {
   169  	benchamarkChaCha20Poly1305Open(b, make([]byte, 1350))
   170  }
   171  
   172  func BenchmarkChacha20Poly1305Seal_1350(b *testing.B) {
   173  	benchamarkChaCha20Poly1305Seal(b, make([]byte, 1350))
   174  }
   175  
   176  func BenchmarkChacha20Poly1305Open_8K(b *testing.B) {
   177  	benchamarkChaCha20Poly1305Open(b, make([]byte, 8*1024))
   178  }
   179  
   180  func BenchmarkChacha20Poly1305Seal_8K(b *testing.B) {
   181  	benchamarkChaCha20Poly1305Seal(b, make([]byte, 8*1024))
   182  }