// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package fipstest

import (
	"bytes"
	"crypto/internal/fips140/drbg"
	"crypto/internal/fips140/subtle"
	"testing"
)

func TestCounterDRBG(t *testing.T) {
	// https://github.com/usnistgov/ACVP-Server/blob/fb44dce/gen-val/json-files/ctrDRBG-1.0/prompt.json#L4447-L4482

	entropyInput := decodeHex(t, "9FCBB4CCC0135C484BDED061DA9FD70748682FE84166B97FF53F9AA1909B2E95D3D529C0F453B3AC575D12AA441CC5CD")
	persoString := decodeHex(t, "2C9FED0B39556CDBE699EBCA2A0EC7EECB287E8744475050C572FA8AE9ED0A4A7D6F1CABF1C4278532FB20AF7D64BD32")
	reseedEntropy := decodeHex(t, "913C0DA19B010EDDD55A7A4F3F713EEF5B1534D34360A7EC376AE71A6B340043CC7726F762CB853453F399B3A645062A")
	reseedAdditional := decodeHex(t, "2D9D4EC141A22E6CD2F6EE4F6719CF6BDF95CFE50B8D5EA6C87D38B4B872706FFF80B0380BB90E9C42D11D6526E56C29")
	additional1 := decodeHex(t, "A642F06D327828F3E84564A3E37D60C157073B95864CA07981B0189668A0D978CD5DC68F06801CEFF0DC839A312B028E")
	additional2 := decodeHex(t, "9DB14BABFA9107C88BA92073C0B4A65E89147EA06D74B894142979482F452915B35B5636F9B8A951759735ADE7C8D5D1")
	returnedBits := decodeHex(t, "F10C645683FF0131254052ED4C698122B46B563654C29D728AC191CA4AAEFE649EEFE4C6FC33B25BB739294DD5CF578099F856C98D98000CBF971F1E6EA900822FF8C110118F6520471744D3F8A3F5C7D568494240E57F5488AF9C9F9F4E7322F56CCD843C0DBFCE9170C02E205389420527F23EDB3369D9FCC5E34901B5BA4EB71B973FC7982FFE0899FF7FE53EE0C4F51A3EF93EF9C6D4D279DD7536F8776BE94AAA05E89EF6E6AEE8832B4B42FFCA5FB91EC0273F9EF945865512889B0C5EE141D1B38DF827D2A694835561628C6F9B093A01A835F07ADBB9E03FEBF93389E8F3B86E1E0ABF1F9958FA286AD995289C2F606D1A9043A166C1AFE8D00769C712650819C9068A4BD22717C98338395A7BA6E95B5178BFBF4EFB0F05A91713BA8BF2127A6BA1EDFA6D1CAB05C03EE0D2AFE1DA4EB8F2C579EC872FF4B602027EF4BDCF2F4B01423F8E600A13D7CACB6AB83263BA58F907694AF614A6724FD0E4C627A0D91DDC6716C697FACE6F4808A4F37B731DE4E0CD4766CEADAAAF47992505299C72AC1A6E9A8335B8D7E501B3841188D0DA4DE5267674444DC2B0CF9F010756FA865A25CA3F1B24C34E845B2259926B6A867A7684DE68A6137C4FB0F47A2E54AE9E6455BEBA0B0A9629644FE9E378EE95386443BA977124FFD1192E9F460684C7B09FA99F5F93F04F56FD7955E042187887CE696F1934017E458B16B5C9")

	// We don't support personalization strings, but the pre-generated JSON
	// vectors always use them, so just pre-mix them.
	var seed [drbg.SeedSize]byte
	subtle.XORBytes(seed[:], entropyInput, persoString)
	c := drbg.NewCounter(&seed)

	c.Reseed((*[48]byte)(reseedEntropy), (*[48]byte)(reseedAdditional))

	buf := make([]byte, len(returnedBits))
	c.Generate(buf, (*[48]byte)(additional1))

	c.Generate(buf, (*[48]byte)(additional2))
	if !bytes.Equal(buf, returnedBits) {
		t.Errorf("unexpected output:\n%x\n%x", buf, returnedBits)
	}
}
