k = 14;
field = "pallas";

constant "Rlnv2Diff_Signal" {}

witness "Rlnv2Diff_Signal" {
	Base identity_nullifier,
	Base identity_trapdoor,
	Base user_message_limit,

	# Inclusion proof, the leaf is the identity_commitment
	SparseMerklePath path,

	# The message hash
	Base x,
	Base message_id,

	Base epoch,
}

circuit "Rlnv2Diff_Signal" {
	# Identity inclusion proof
	identity_secret = poseidon_hash(identity_nullifier, identity_trapdoor);
	identity_secret_hash = poseidon_hash(identity_secret, user_message_limit);
	identity_commitment = poseidon_hash(identity_secret_hash);
	root = sparse_merkle_root(identity_commitment, path, identity_commitment);
	constrain_instance(root);

	# External nullifier is created from epoch and app identifier
	app_id = witness_base(1000);
	external_nullifier = poseidon_hash(epoch, app_id);
	constrain_instance(external_nullifier);

	# Calculating internal nullifier
	# a_0 = identity_secret
	a_0 = poseidon_hash(identity_nullifier, identity_trapdoor);
	a_1 = poseidon_hash(a_0, external_nullifier, message_id);
	x_a_1  = base_mul(x, a_1);
	y = base_add(a_0, x_a_1);
	constrain_instance(x);
	constrain_instance(y);

	# Constrain message_id to be lower than actual message limit.
	less_than_strict(message_id, user_message_limit);

	internal_nullifier = poseidon_hash(a_1);
	constrain_instance(internal_nullifier);
}
