This commit is contained in:
rymnc
2024-03-13 14:55:05 +05:30
parent c540f3ab32
commit e52251cbdc
3 changed files with 8 additions and 108 deletions

View File

@@ -1,83 +0,0 @@
package rln
import (
"github.com/consensys/gnark/frontend"
)
// TestPoseidon tests the Gnark Poseidon implementation against Iden3's Go implementation on all the test
// vectors outlined in the original paper's reference repository, which can be found here: https://extgit.iaik.tugraz.at/krypto/hadeshash/-/tree/master/code
//
// The actual test vectors are outlined here: https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/test_vectors.txt
// We have included more for the sake of robustness.
// Note that our implementation is focused on the 3-input variant with an x^5 S-box, so not all the test vectors apply.
// func TestPoseidon(t *testing.T) {
// tests := map[string]struct {
// gnarkPoseidonInput [3]frontend.Variable
// referencePoseidonInput []*big.Int
// }{
// "happy path: basic input": {
// gnarkPoseidonInput: [3]frontend.Variable{1, 2, 3},
// referencePoseidonInput: []*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3)},
// },
// "official test vector: poseidonperm_x5_254_3": {
// gnarkPoseidonInput: [3]frontend.Variable{0, 1, 2},
// referencePoseidonInput: []*big.Int{big.NewInt(0), big.NewInt(1), big.NewInt(2)},
// },
// "zero vector": {
// gnarkPoseidonInput: [3]frontend.Variable{0, 0, 0},
// referencePoseidonInput: []*big.Int{big.NewInt(0), big.NewInt(0), big.NewInt(0)},
// },
// "larger inputs": {
// gnarkPoseidonInput: [3]frontend.Variable{129048, 990217, 2234383333},
// referencePoseidonInput: []*big.Int{big.NewInt(129048), big.NewInt(990217), big.NewInt(2234383333)},
// },
// "decreasing vector inputs": {
// gnarkPoseidonInput: [3]frontend.Variable{10000000, 10000, 100},
// referencePoseidonInput: []*big.Int{big.NewInt(10000000), big.NewInt(10000), big.NewInt(100)},
// },
// }
// for name, testCase := range tests {
// assert := test.NewAssert(t)
// var circuit circuitPoseidon
// // Compute reference hash to test against
// referenceHash, err := poseidon.Hash(testCase.referencePoseidonInput)
// if err != nil {
// t.Fatal(err, "Failed to compute reference poseidon hash for test case: ", name)
// }
// t.Logf("Reference hash: %s", referenceHash.String())
// // Generate poseidon hash using gnark implementation
// assert.ProverSucceeded(&circuit, &circuitPoseidon{
// A: testCase.gnarkPoseidonInput,
// Hash: referenceHash,
// }, test.WithCurves(ecc.BN254), test.WithBackends(backend.GROTH16))
// // Ensure output correctly compiles
// _r1cs, err := frontend.Compile(big.NewInt(1), r1cs.NewBuilder, &circuit)
// if err != nil {
// t.Fatal(err, "Failed to compile computed poseidon hash for test case: ", name)
// }
// // Sanity check and debugging support for internal variables
// internal, secret, public := _r1cs.GetNbVariables()
// t.Logf("Public, secret, internal %v, %v, %v\n", public, secret, internal)
// }
// }
// --- Test Helpers ---
type circuitPoseidon struct {
A [3]frontend.Variable `gnark:",public"`
Hash frontend.Variable `gnark:",public"`
}
func (t *circuitPoseidon) Define(api frontend.API) error {
hash := Poseidon(api, t.A[:])
api.Println(t.Hash)
api.Println(hash)
api.AssertIsEqual(hash, t.Hash)
return nil
}

View File

@@ -21,15 +21,9 @@ type RlnCircuit struct {
}
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[:])
identity_commitment := Poseidon(api, []frontend.Variable{circuit.IdentitySecret})
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[:])
rate_commitment := Poseidon(api, []frontend.Variable{identity_commitment, circuit.UserMessageLimit})
api.AssertIsEqual(rate_commitment, rate_commitment)
levels := len(circuit.IdentityPathIndex)
@@ -38,15 +32,8 @@ func (circuit RlnCircuit) Define(api frontend.API) error {
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[:])
left_hash := Poseidon(api, []frontend.Variable{hashes[i], circuit.PathElements[i]})
right_hash := Poseidon(api, []frontend.Variable{circuit.PathElements[i], hashes[i]})
hashes[i+1] = api.Select(circuit.IdentityPathIndex[i], right_hash, left_hash)
}
root := hashes[levels]
@@ -56,17 +43,11 @@ func (circuit RlnCircuit) Define(api frontend.API) error {
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[:])
a1 := Poseidon(api, []frontend.Variable{circuit.IdentitySecret, circuit.ExternalNullifier, circuit.MessageId})
y := api.Add(circuit.IdentitySecret, api.Mul(a1, circuit.X))
api.AssertIsEqual(y, circuit.Y)
var nullifier_input [1]frontend.Variable
nullifier_input[0] = a1
nullifier := Poseidon(api, nullifier_input[:])
nullifier := Poseidon(api, []frontend.Variable{a1})
api.AssertIsEqual(nullifier, circuit.Nullifier)
return nil

View File

@@ -7,6 +7,8 @@ import (
"github.com/consensys/gnark/test"
)
// TODO: get kats for other curves
func TestRlnCircuit(t *testing.T) {
assert := test.NewAssert(t)