// Code generated by bitwrap synth; DO NOT EDIT.
// Source schema: ZKPoll Vote:1.0.0

package prover

import (
	"github.com/consensys/gnark/frontend"
)

// VoteCastCircuit is generated from schema action "castVote". Parity target: VoteCastCircuit in prover/circuits.go.
type VoteCastCircuit struct {
	PollID            frontend.Variable `gnark:",public"`
	VoterRegistryRoot frontend.Variable `gnark:",public"`
	Nullifier         frontend.Variable `gnark:",public"`
	VoteCommitment    frontend.Variable `gnark:",public"`
	MaxChoices        frontend.Variable `gnark:",public"`

	VoterSecret frontend.Variable
	VoteChoice  frontend.Variable
	VoterWeight frontend.Variable

	PathElements [20]frontend.Variable
	PathIndices  [20]frontend.Variable
}

func (c *VoteCastCircuit) Define(api frontend.API) error {
	// 1. Merkle membership: leaf = mimcHash(voterSecret, voterWeight) → VoterRegistryRoot
	leaf := synthMimcHash(api, c.VoterSecret, c.VoterWeight)
	current := leaf
	for i := 0; i < 20; i++ {
		api.AssertIsBoolean(c.PathIndices[i])
		left := api.Select(c.PathIndices[i], c.PathElements[i], current)
		right := api.Select(c.PathIndices[i], current, c.PathElements[i])
		current = synthMimcHash(api, left, right)
	}
	api.AssertIsEqual(current, c.VoterRegistryRoot)

	// 2. NullifierBind ZKOp: Nullifier == hash(voterSecret, pollId)
	expectedNullifier := synthMimcHash(api, c.VoterSecret, c.PollID)
	api.AssertIsEqual(c.Nullifier, expectedNullifier)

	// 3. Range check: VoteChoice fits in 8 bits and < MaxChoices
	api.ToBinary(c.VoteChoice, 8)
	diff := api.Sub(c.MaxChoices, c.VoteChoice)
	diffMinusOne := api.Sub(diff, 1)
	api.ToBinary(diffMinusOne, 8)

	// 4. CommitmentBind ZKOp: VoteCommitment == hash(voterSecret, voteChoice)
	expectedCommitment := synthMimcHash(api, c.VoterSecret, c.VoteChoice)
	api.AssertIsEqual(c.VoteCommitment, expectedCommitment)
	return nil
}
