/**
 * Copyright (c) 2014-2026 Governikus GmbH & Co. KG, Germany
 */

#pragma once

#include <QByteArray>
#include <QSharedPointer>
#include <openssl/ec.h>

class test_EcdhGenericMapping;

namespace governikus
{

/*!
 * Algorithm according to TR 03110 Part 3 chapter A.3.4.1.Generic Mapping
 */
class EcdhGenericMapping
{
	friend class ::test_EcdhGenericMapping;

	private:
		const QSharedPointer<EC_GROUP> mCurve;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(USE_LEGACY_OPENSSL_API)
		QSharedPointer<EVP_PKEY> mLocalKey;
#else
		QSharedPointer<EC_KEY> mLocalKey;
#endif

		QSharedPointer<EC_POINT> createNewGenerator(const QSharedPointer<const EC_POINT>& pRemotePubKey, const QSharedPointer<const BIGNUM>& pS);

		bool setGenerator(const QSharedPointer<const EC_POINT>& pNewGenerator) const;

	public:
		explicit EcdhGenericMapping(const QSharedPointer<EC_GROUP>& pCurve);

		[[nodiscard]] const QSharedPointer<EC_GROUP>& getCurve() const;

		/*!
		 * \brief Generates the local mapping data, that will be sent to the remote.
		 * \return The local mapping data
		 */
		QByteArray generateLocalMappingData();

		/*!
		 * \brief Generates the ephemeral domain parameters.
		 * \param pRemoteMappingData the card's mapping data
		 * \param pNonce the nonce that was generated by the card
		 * \return the terminal's mapping data
		 */
		bool generateEphemeralDomainParameters(const QByteArray& pRemoteMappingData, const QByteArray& pNonce);
};

} // namespace governikus
