/*
 signver.c - ESIGN Signature Verification

 Copyright NTT MCL, 2000.

 Duncan S Wong
 Security Group, NTT MCL
 July 2000
*/

#include <stdio.h>
#include <gmp.h>
#include "esign.h"
#include "hash.h"
#include "utils.h"

/*
 ESIGN Signature Verification

 Return: TRUE if the signature is valid; otherwise FALSE
*/
BYTE ESIGN_SignVer (
	BYTE             *signature,
   BYTE             *message,
	WORD             mLen,
   ESIGN_PUB_KEY    *publicKey
)
{
mpz_t m, S, tmp;
BYTE *H_out, *m_raw;
BYTE result;
long i;

	mpz_init(m);
	mpz_init(S);
	mpz_init(tmp);

	H_out = (BYTE *) malloc (publicKey->pLen/8);

	/* prepare (mpz_t) m and (BYTE *) m_raw */
	mpz_set_str(m, message, 0);

	m_raw = (BYTE *) malloc (ABS(m->_mp_size)*4);

	WORD2BYTE(m_raw, m->_mp_d, ABS(m->_mp_size));

	mpz_set_str(S, signature, 0);

	/* printf("ESIGN_SignVer: S =\n%s\n\n", mpz_get_str(NULL, 16, S)); */

	/* compute H'(M) and set it to 0||H(M) */
	indexedSHA(H_out, publicKey->pLen/8, m_raw, mLen/8);
	H_out[0] = H_out[0] & 0x7F;
	BYTE2WORD(tmp, H_out, publicKey->pLen/8);

	mpz_powm(S, S, publicKey->e, publicKey->n);

	mpz_fdiv_q_2exp(S, S, publicKey->pLen*2);
	/*
	printf("ESIGN_SignVer: [S^e mod n]^pLen =\n");
	printf("%s\n\n", mpz_get_str(NULL, 16, S));
	*/

	result = FALSE;
	if(mpz_cmp(S, tmp) == 0)
		result = TRUE;

	/* clean up */
	memset(H_out, 0, publicKey->pLen/8);
	memset(m_raw, 0, ABS(m->_mp_size)*4);
	free(H_out);
	free(m_raw);

	mpz_clear(m);
	mpz_clear(S);
	mpz_clear(tmp);

	return result;
}
