mirror of
https://github.com/vacp2p/gnark-rln.git
synced 2026-01-08 04:34:01 -05:00
74 lines
2.9 KiB
Go
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
|
|
}
|