Files
gnark-rln/rln/rln.go
2024-03-13 14:01:15 +05:30

74 lines
2.9 KiB
Go

package rln
import (
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/rangecheck"
)
// Circuit defines a simple circuit
// x**3 + x + 5 == y
type RlnCircuit struct {
X frontend.Variable `gnark:"x, public"` // message hash
ExternalNullifier frontend.Variable `gnark:"externalNullifier, public"` // external nullifier
IdentitySecret frontend.Variable `gnark:"identitySecret,secret"` // identity secret
MessageId frontend.Variable `gnark:"messageId,secret"` // message id
UserMessageLimit frontend.Variable `gnark:"userMessageLimit,secret"` // user message limit
PathElements [20]frontend.Variable `gnark:"pathElements,secret"` // path elements
IdentityPathIndex [20]frontend.Variable `gnark:"identityPathIndex,secret"` // identity path index
Y frontend.Variable `gnark:"y,public"`
Root frontend.Variable `gnark:"root, public"`
Nullifier frontend.Variable `gnark:"nullifier, public"`
}
func (circuit RlnCircuit) Define(api frontend.API) error {
var identity_commitment_input [1]frontend.Variable
identity_commitment_input[0] = circuit.IdentitySecret
identity_commitment := Poseidon(api, identity_commitment_input[:])
api.AssertIsEqual(identity_commitment, identity_commitment)
var rate_commitment_input [2]frontend.Variable
rate_commitment_input[0] = identity_commitment
rate_commitment_input[1] = circuit.UserMessageLimit
rate_commitment := Poseidon(api, rate_commitment_input[:])
api.AssertIsEqual(rate_commitment, rate_commitment)
levels := len(circuit.IdentityPathIndex)
hashes := make([]frontend.Variable, levels+1)
hashes[0] = rate_commitment
for i := 0; i < levels; i++ {
api.AssertIsBoolean(circuit.IdentityPathIndex[i])
var left_hash_input [2]frontend.Variable
left_hash_input[0] = hashes[i]
left_hash_input[1] = circuit.PathElements[i]
var right_hash_input [2]frontend.Variable
right_hash_input[0] = circuit.PathElements[i]
right_hash_input[1] = hashes[i]
left_hash := Poseidon(api, left_hash_input[:])
right_hash := Poseidon(api, right_hash_input[:])
hashes[i+1] = api.Select(circuit.IdentityPathIndex[i], right_hash, left_hash)
}
circuit.Root = hashes[levels]
api.AssertIsEqual(circuit.Root, circuit.Root)
rangeChecker := rangecheck.New(api)
rangeChecker.Check(circuit.MessageId, 16)
api.AssertIsLessOrEqual(circuit.MessageId, circuit.UserMessageLimit)
var a1_input [3]frontend.Variable
a1_input[0] = circuit.IdentitySecret
a1_input[1] = circuit.ExternalNullifier
a1_input[2] = circuit.MessageId
a1 := Poseidon(api, a1_input[:])
circuit.Y = api.Mul(api.Add(circuit.IdentitySecret, a1), circuit.X)
api.AssertIsEqual(circuit.Y, circuit.Y)
var nullifier_input [1]frontend.Variable
nullifier_input[0] = a1
circuit.Nullifier = Poseidon(api, nullifier_input[:])
api.AssertIsEqual(circuit.Nullifier, circuit.Nullifier)
return nil
}