/*
 * Copyright (C) 2025 - 2026, Stephan Mueller <smueller@chronox.de>
 *
 * License: see LICENSE file in root directory
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
 * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

#include <stdio.h>

#include "compare.h"
#include "lc_sha512.h"
#include "ret_checkers.h"
#include "signature_domain_separation.h"

static int composite_sig_domsep(void)
{
	/*
	 * Testvector from
	 * https://lamps-wg.github.io/draft-composite-sigs/draft-ietf-lamps-pq-composite-sigs.html
	 */
	/* Equals to the selected domain */
	static uint8_t nist_category = 0;
	static uint8_t userctx[] = { 0x08, 0x13, 0x06, 0x12,
				     0x05, 0x16, 0x26, 0x23 };
	static uint8_t phmsg[] = {
		0x0f, 0x89, 0xee, 0x1f, 0xcb, 0x7b, 0x0a, 0x4f, 0x78, 0x09,
		0xd1, 0x26, 0x7a, 0x02, 0x97, 0x19, 0x00, 0x4c, 0x5a, 0x5e,
		0x5e, 0xc3, 0x23, 0xa7, 0xc3, 0x52, 0x3a, 0x20, 0x97, 0x4f,
		0x9a, 0x3f, 0x20, 0x2f, 0x56, 0xfa, 0xdb, 0xa4, 0xcd, 0x9e,
		0x8d, 0x65, 0x4a, 0xb9, 0xf2, 0xe9, 0x6d, 0xc5, 0xc7, 0x95,
		0xea, 0x17, 0x6f, 0xa2, 0x0e, 0xde, 0x8d, 0x85, 0x4c, 0x34,
		0x2f, 0x90, 0x35, 0x33
	};
	static uint8_t exp_no_ctx[] = {
		0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x41,
		0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x53, 0x69,
		0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x32, 0x30,
		0x32, 0x35, 0x43, 0x4f, 0x4d, 0x50, 0x53, 0x49, 0x47, 0x2d,
		0x4d, 0x4c, 0x44, 0x53, 0x41, 0x36, 0x35, 0x2d, 0x45, 0x43,
		0x44, 0x53, 0x41, 0x2d, 0x50, 0x32, 0x35, 0x36, 0x2d, 0x53,
		0x48, 0x41, 0x35, 0x31, 0x32, 0x00, 0x0f, 0x89, 0xee, 0x1f,
		0xcb, 0x7b, 0x0a, 0x4f, 0x78, 0x09, 0xd1, 0x26, 0x7a, 0x02,
		0x97, 0x19, 0x00, 0x4c, 0x5a, 0x5e, 0x5e, 0xc3, 0x23, 0xa7,
		0xc3, 0x52, 0x3a, 0x20, 0x97, 0x4f, 0x9a, 0x3f, 0x20, 0x2f,
		0x56, 0xfa, 0xdb, 0xa4, 0xcd, 0x9e, 0x8d, 0x65, 0x4a, 0xb9,
		0xf2, 0xe9, 0x6d, 0xc5, 0xc7, 0x95, 0xea, 0x17, 0x6f, 0xa2,
		0x0e, 0xde, 0x8d, 0x85, 0x4c, 0x34, 0x2f, 0x90, 0x35, 0x33
	};
	static uint8_t exp_ctx[] = {
		0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x41,
		0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x53, 0x69,
		0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x32, 0x30,
		0x32, 0x35, 0x43, 0x4f, 0x4d, 0x50, 0x53, 0x49, 0x47, 0x2d,
		0x4d, 0x4c, 0x44, 0x53, 0x41, 0x36, 0x35, 0x2d, 0x45, 0x43,
		0x44, 0x53, 0x41, 0x2d, 0x50, 0x32, 0x35, 0x36, 0x2d, 0x53,
		0x48, 0x41, 0x35, 0x31, 0x32, 0x08, 0x08, 0x13, 0x06, 0x12,
		0x05, 0x16, 0x26, 0x23, 0x0f, 0x89, 0xee, 0x1f, 0xcb, 0x7b,
		0x0a, 0x4f, 0x78, 0x09, 0xd1, 0x26, 0x7a, 0x02, 0x97, 0x19,
		0x00, 0x4c, 0x5a, 0x5e, 0x5e, 0xc3, 0x23, 0xa7, 0xc3, 0x52,
		0x3a, 0x20, 0x97, 0x4f, 0x9a, 0x3f, 0x20, 0x2f, 0x56, 0xfa,
		0xdb, 0xa4, 0xcd, 0x9e, 0x8d, 0x65, 0x4a, 0xb9, 0xf2, 0xe9,
		0x6d, 0xc5, 0xc7, 0x95, 0xea, 0x17, 0x6f, 0xa2, 0x0e, 0xde,
		0x8d, 0x85, 0x4c, 0x34, 0x2f, 0x90, 0x35, 0x33
	};
	uint8_t exp_digest[LC_SHA512_SIZE_DIGEST];
	uint8_t act_digest[sizeof(exp_digest)];
	int ret;
	LC_HASH_CTX_ON_STACK(ctx, lc_sha512);

	CKINT(lc_hash(lc_sha512, exp_no_ctx, sizeof(exp_no_ctx), exp_digest));

	CKINT(lc_hash_init(ctx));
	CKINT(signature_domain_separation(ctx, 0, NULL, NULL, 0, phmsg,
					  sizeof(phmsg), 1, nist_category));
	lc_hash_final(ctx, act_digest);
	lc_compare(
		act_digest, exp_digest, sizeof(exp_digest),
		"Composite signature domain separator without user context\n");

	CKINT(lc_hash(lc_sha512, exp_ctx, sizeof(exp_ctx), exp_digest));

	CKINT(lc_hash_init(ctx));
	CKINT(signature_domain_separation(ctx, 0, NULL, userctx,
					  sizeof(userctx), phmsg, sizeof(phmsg),
					  1, nist_category));
	lc_hash_final(ctx, act_digest);
	lc_compare(act_digest, exp_digest, sizeof(exp_digest),
		   "Composite signature domain separator with user context\n");

out:
	return ret;
}

int main(int argc, char *argv[])
{
	(void)argv;
	(void)argc;
	return composite_sig_domsep();
}
