// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package subtle_test

import (
	"bytes"
	"crypto/aes"
	"encoding/hex"
	"strings"
	"testing"

	"github.com/google/tink/go/aead/subtle"
	"github.com/google/tink/go/subtle/random"
)

func TestNewAESCTR(t *testing.T) {
	key := make([]byte, 64)

	// Test various key sizes with a fixed IV size.
	for i := 0; i < 64; i++ {
		k := key[:i]
		c, err := subtle.NewAESCTR(k, subtle.AESCTRMinIVSize)

		switch len(k) {
		case 16:
			fallthrough
		case 32:
			// Valid key sizes.
			if err != nil {
				t.Errorf("want: valid cipher (key size=%d), got: error %v", len(k), err)
			}
			// Verify that the struct contents are correctly set.
			if len(c.Key) != len(k) {
				t.Errorf("want: key size=%d, got: key size=%d", len(k), len(c.Key))
			}
			if c.IVSize != subtle.AESCTRMinIVSize {
				t.Errorf("want: IV size=%d, got: IV size=%d", subtle.AESCTRMinIVSize, c.IVSize)
			}
		default:
			// Invalid key sizes.
			if !strings.Contains(err.Error(), "aes_ctr: invalid AES key size; want 16 or 32") {
				t.Errorf("wrong error message; want a string starting with \"aes_ctr: invalid AES key size; want 16 or 32\", got %v", err)
			}
		}
	}

	// Test different IV sizes with a fixed key.
	for i := 0; i < 64; i++ {
		k := key[:16]
		c, err := subtle.NewAESCTR(k, i)
		if i >= subtle.AESCTRMinIVSize && i <= aes.BlockSize {
			if err != nil {
				t.Errorf("want: valid cipher (IV size=%d), got: error %v", i, err)
			}
			if len(c.Key) != len(k) {
				t.Errorf("want: key size=%d, got: key size=%d", len(k), len(c.Key))
			}
			if c.IVSize != i {
				t.Errorf("want: IV size=%d, got: IV size=%d", i, c.IVSize)
			}
			continue
		}
		if !strings.Contains(err.Error(), "aes_ctr: invalid IV size:") {
			t.Errorf("want: error invalid IV size, got: %v", err)
		}
	}
}

func TestNistTestVector(t *testing.T) {
	// NIST SP 800-38A pp 55
	key, err := hex.DecodeString("2b7e151628aed2a6abf7158809cf4f3c")
	if err != nil {
		t.Fatalf("failed to hex decode key, error: %v", err)
	}

	// NIST IV
	iv := "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
	// NIST ciphertext blocks
	c := "874d6191b620e3261bef6864990db6ce" +
		"9806f66b7970fdff8617187bb9fffdff" +
		"5ae4df3edbd5d35e5b4f09020db03eab" +
		"1e031dda2fbe03d1792170a0f3009cee"
	ciphertext, err := hex.DecodeString(iv + c)
	if err != nil {
		t.Fatalf("failed to hex decode ciphertext, error: %v", err)
	}

	// NIST plaintext blocks
	p := "6bc1bee22e409f96e93d7e117393172a" +
		"ae2d8a571e03ac9c9eb76fac45af8e51" +
		"30c81c46a35ce411e5fbc1191a0a52ef" +
		"f69f2445df4f9b17ad2b417be66c3710"
	message, err := hex.DecodeString(p)
	if err != nil {
		t.Fatalf("failed to hex decode message, error: %v", err)
	}

	stream, err := subtle.NewAESCTR(key, len(iv)/2)
	if err != nil {
		t.Fatalf("failed to create AESCTR instance, error: %v", err)
	}

	plaintext, err := stream.Decrypt(ciphertext)
	if err != nil {
		t.Errorf("failed to decrypt ciphertext, error: %v", err)
	}

	if !bytes.Equal(plaintext, message) {
		t.Errorf("plaintext doesn't match message")
	}
}

func TestMultipleEncrypt(t *testing.T) {
	key := random.GetRandomBytes(16)

	stream, err := subtle.NewAESCTR(key, subtle.AESCTRMinIVSize)
	if err != nil {
		t.Fatalf("failed to create AESCTR instance, error: %v", err)
	}

	plaintext := []byte("Some data to encrypt.")
	ct1, err := stream.Encrypt(plaintext)
	if err != nil {
		t.Errorf("encryption failed, error: %v", err)
	}
	ct2, err := stream.Encrypt(plaintext)
	if err != nil {
		t.Errorf("encryption failed, error: %v", err)
	}
	if bytes.Equal(ct1, ct2) {
		t.Error("the two ciphertexts cannot be equal")
	}
	// Encrypt 100 times and verify that the result is 100 different ciphertexts.
	ciphertexts := map[string]bool{}
	for i := 0; i < 100; i++ {
		c, err := stream.Encrypt(plaintext)
		if err != nil {
			t.Errorf("encryption failed for iteration %d, error: %v", i, err)
		}
		ciphertexts[string(c)] = true
	}

	if len(ciphertexts) != 100 {
		t.Errorf("got: %d ciphertexts, want: 100 ciphertexts", len(ciphertexts))
	}
}

func TestEncryptDecrypt(t *testing.T) {
	key, err := hex.DecodeString("000102030405060708090a0b0c0d0e0f")
	if err != nil {
		t.Fatal("failed to hex decode key")
	}

	stream, err := subtle.NewAESCTR(key, subtle.AESCTRMinIVSize)
	if err != nil {
		t.Fatalf("failed to get AESCTR instance, error: %v", err)
	}

	message := []byte("Some data to encrypt.")
	ciphertext, err := stream.Encrypt(message)
	if err != nil {
		t.Errorf("encryption failed, error: %v", err)
	}

	if len(ciphertext) != len(message)+subtle.AESCTRMinIVSize {
		t.Errorf("ciphertext incorrect size, got: %d, want: %d", len(ciphertext), len(message)+subtle.AESCTRMinIVSize)
	}

	plaintext, err := stream.Decrypt(ciphertext)
	if err != nil {
		t.Errorf("decryption failed, error: %v", err)
	}

	if !bytes.Equal(message, plaintext) {
		t.Errorf("decryption result mismatch, got: %v, want: %v", plaintext, message)
	}
}

func TestEncryptRandomMessage(t *testing.T) {
	key := random.GetRandomBytes(16)

	stream, err := subtle.NewAESCTR(key, subtle.AESCTRMinIVSize)
	if err != nil {
		t.Errorf("failed to instantiate AESCTR, error: %v", err)
	}

	for i := 0; i < 256; i++ {
		message := random.GetRandomBytes(uint32(i))
		ciphertext, err := stream.Encrypt(message)
		if err != nil {
			t.Errorf("encryption failed at iteration %d, error: %v", i, err)
		}
		if len(ciphertext) != len(message)+subtle.AESCTRMinIVSize {
			t.Errorf("invalid ciphertext length for i = %d", i)
		}

		plaintext, err := stream.Decrypt(ciphertext)
		if err != nil {
			t.Errorf("decryption failed at iteration %d, error: %v", i, err)
		}

		if !bytes.Equal(plaintext, message) {
			t.Errorf("plaintext doesn't match message, i = %d", i)
		}
	}
}

func TestEncryptRandomKeyAndMessage(t *testing.T) {
	for i := 0; i < 256; i++ {
		key := random.GetRandomBytes(16)

		stream, err := subtle.NewAESCTR(key, subtle.AESCTRMinIVSize)
		if err != nil {
			t.Errorf("failed to instantiate AESCTR, error: %v", err)
		}

		message := random.GetRandomBytes(uint32(i))
		ciphertext, err := stream.Encrypt(message)
		if err != nil {
			t.Errorf("encryption failed at iteration %d, error: %v", i, err)
		}
		if len(ciphertext) != len(message)+subtle.AESCTRMinIVSize {
			t.Errorf("invalid ciphertext length for i = %d", i)
		}

		plaintext, err := stream.Decrypt(ciphertext)
		if err != nil {
			t.Errorf("decryption failed at iteration %d, error: %v", i, err)
		}

		if !bytes.Equal(plaintext, message) {
			t.Errorf("plaintext doesn't match message, i = %d", i)
		}
	}
}
