Some refactors

This commit is contained in:
alrevuelta 2024-01-23 14:13:12 +01:00
parent 28a98ba8c0
commit 86d2d24525
No known key found for this signature in database
GPG Key ID: F345C9F3CCDB886E
6 changed files with 40 additions and 54 deletions

View File

@ -10,6 +10,10 @@ import (
"github.com/waku-org/go-zerokit-rln/rln/link"
)
// Same as: https://github.com/vacp2p/zerokit/blob/v0.3.5/rln/src/public.rs#L35
// Prevents a RLN ZK proof generated for one application to be re-used in another one.
var RLN_IDENTIFIER = [32]byte{166, 140, 43, 8, 8, 22, 206, 113, 151, 128, 118, 40, 119, 197, 218, 174, 11, 117, 84, 228, 96, 211, 212, 140, 145, 104, 146, 99, 24, 192, 217, 4}
// RLN represents the context used for rln.
type RLN struct {
w *link.RLNWrapper
@ -130,17 +134,14 @@ func (r *RLN) SeededMembershipKeyGen(seed []byte) (*IdentityCredential, error) {
// appendLength returns length prefixed version of the input with the following format
// [len<8>|input<var>], the len is a 8 byte value serialized in little endian
func appendLength(input []byte) []byte {
inputLen := make([]byte, 8)
binary.LittleEndian.PutUint64(inputLen, uint64(len(input)))
return append(inputLen, input...)
}
// can i reuse serialize32??
// TODO: dirty
// Assume that the input is a sequence of 32 byte values
// so length is the amount of 32 byte values
// Similar to appendLength but for 32 byte values. The length that is prepended is
// the length of elements that are 32 bytes long each
func appendLength32(input []byte) []byte {
inputLen := make([]byte, 8)
binary.LittleEndian.PutUint64(inputLen, uint64(len(input)/32))
@ -242,32 +243,12 @@ func (r *RLN) GenerateProof(data []byte, key IdentityCredential, index Membershi
}, nil
}
// input :
/*
identity_secret: Fr,
path_elements: Vec<Fr>, | 8 * 20*32 + 20 + 8
identity_path_index: Vec<u8>, | --
x: Fr, -> this seems to be of fixed size? not size+ variablelenarray
epoch: Fr,
rln_identifier: Fr,
*/
// todo: output same as other function.
// Returns a RLN proof with a custom witness, so no tree is required in the RLN instance
// to calculate such proof. The witness can be created with GetMerkleProof data
// input [ id_secret_hash<32> | num_elements<8> | path_elements<var1> | num_indexes<8> | path_indexes<var2> | x<32> | epoch<32> | rln_identifier<32> ]
// output [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> ]
func (r *RLN) GenerateRLNProofWithWitness(witness RLNWitnessInput) (*RateLimitProof, error) {
// TODO: this shouldn go here but i think there is an issue in zerokit
fmt.Println("len data before ", len(witness.Data))
// Remove its not a poseidon hash but kekkack
hashedData, err := r.Poseidon(witness.Data[:])
if err != nil {
return nil, err
}
//witness.Data = hashedData[:]
_ = hashedData
fmt.Println("len data after ", len(witness.Data))
proofBytes, err := r.w.GenerateRLNProofWithWitness(witness.serialize())
if err != nil {
return nil, err
@ -277,7 +258,6 @@ func (r *RLN) GenerateRLNProofWithWitness(witness RLNWitnessInput) (*RateLimitPr
return nil, errors.New("invalid proof generated")
}
// TODO: maybe move this into a common function (used by the other generateRlnproof function)
// parse the proof as [ proof<128> | root<32> | epoch<32> | share_x<32> | share_y<32> | nullifier<32> | rln_identifier<32> ]
proofOffset := 128
rootOffset := proofOffset + 32

View File

@ -355,6 +355,8 @@ func (s *RLNSuite) TestGenerateRLNProofWithWitness() {
rln, err := NewRLN()
s.NoError(err)
// TODO: Run multiple test with multiple indexes
// Leaf we generate the proof for
memberIndex := uint(4)
memKeys, err := rln.MembershipKeyGen()
@ -380,39 +382,30 @@ func (s *RLNSuite) TestGenerateRLNProofWithWitness() {
// TODO: Add some asserts on roots
fmt.Println("root from zerokit: ", root)
// Inputs for proof generation
msg := []byte("hi there")
var epoch = Epoch([32]byte{0x00, 0x00, 0x00, 0x00, 0x01})
// We provide out custom witness
merkleProof, err := rln.GetMerkleProof(memberIndex)
s.NoError(err)
// TODO: This should be abstracted away, move inside somewhere
x := HashToBN255(msg)
rlnWitness := RLNWitnessInput{
// memberIndex key
IdentityCredential: *memKeys,
MerkleProof: merkleProof,
Data: x[:], // TODO: This is not really data, its a hash of data
Epoch: epoch,
RlnIdentifier: [32]byte{166, 140, 43, 8, 8, 22, 206, 113, 151, 128, 118, 40, 119, 197, 218, 174, 11, 117, 84, 228, 96, 211, 212, 140, 145, 104, 146, 99, 24, 192, 217, 4}, // TODO
}
message := []byte("some rln protected message")
epoch := ToEpoch(1000)
rlnWitness := CreateWitness(
*memKeys,
message,
epoch,
merkleProof)
// Generate a proof with our custom witness (Merkle Path of the memberIndex)
proofRes1, err := rln.GenerateRLNProofWithWitness(rlnWitness)
s.NoError(err)
verified1, err := rln.Verify(msg[:], *proofRes1, root)
verified1, err := rln.Verify(message, *proofRes1, root)
s.NoError(err)
s.True(verified1)
proofRes2, err := rln.GenerateProof(msg[:], *memKeys, MembershipIndex(memberIndex), epoch)
proofRes2, err := rln.GenerateProof(message, *memKeys, MembershipIndex(memberIndex), epoch)
s.NoError(err)
// Proof generate with custom witness match the proof generate with the witness
// from zerokit
//s.Equal(proofRes1.Proof, proofRes2.Proof) // The proof itself can be different
// from zerokit. Proof itself is not asserted, can be different.
s.Equal(proofRes1.MerkleRoot, proofRes2.MerkleRoot)
s.Equal(proofRes1.Epoch, proofRes2.Epoch)
s.Equal(proofRes1.ShareX, proofRes2.ShareX)

View File

@ -53,7 +53,7 @@ func (r *RLNWitnessInput) serialize() []byte {
output = append(output, r.IdentityCredential.IDSecretHash[:]...)
output = append(output, r.MerkleProof.serialize()...)
output = append(output, r.Data...) // TODO: Data doesnt have the lend prepended. Is it fixed to 32 bytes? Different than in other places
output = append(output, r.X[:]...)
output = append(output, r.Epoch[:]...)
output = append(output, r.RlnIdentifier[:]...)
@ -115,8 +115,6 @@ func (r *MerkleProof) deserialize(b []byte) error {
numElements.String(), numIndexes.String()))
}
// TODO: Depth check, but currently not accesible
r.PathIndexes = make([]uint8, numIndexes.Uint64())
for i := uint64(0); i < numIndexes.Uint64(); i++ {

View File

@ -47,7 +47,6 @@ func TestMerkleProofSerDe(t *testing.T) {
func TestRLNWitnessInputSerDe(t *testing.T) {
// TODO: Is data size arbitrary? or fixed to 32. How its decode in zerokit seems to be fixed to 32.
// At least in the proof with custom witness function.
data := [32]byte{0x00}
depth := 20
mProof := MerkleProof{
@ -65,7 +64,7 @@ func TestRLNWitnessInputSerDe(t *testing.T) {
IDSecretHash: random32(),
},
MerkleProof: mProof,
Data: data[:],
X: [32]byte{0x00},
Epoch: ToEpoch(10),
RlnIdentifier: [32]byte{0x00},
}

View File

@ -68,13 +68,14 @@ type MerkleProof struct {
PathIndexes []uint8 `json:"pathIndexes"`
}
// Equivalent: https://github.com/vacp2p/zerokit/blob/v0.3.5/rln/src/protocol.rs#L33-L40
type RLNWitnessInput struct {
// TODO: Maybe dont store the whole IdentityCredential and just the secret
IdentityCredential IdentityCredential `json:"identityCredential"`
MerkleProof MerkleProof `json:"merkleProof"`
// This is not the data but the hashed version of it "x"..TODO rename and reconsider
Data []byte `json:"data"` // TODO: this should be fixed 32
X [32]byte `json:"x"`
Epoch Epoch `json:"epoch"`
RlnIdentifier RLNIdentifier `json:"rlnIdentifier"` // what is this? TOOD: app specific. which one is ours?
}

View File

@ -8,6 +8,21 @@ import (
"github.com/ethereum/go-ethereum/crypto"
)
func CreateWitness(
identityCredential IdentityCredential, // TODO only the secret hash.
data []byte,
epoch [32]byte,
merkleProof MerkleProof) RLNWitnessInput {
return RLNWitnessInput{
IdentityCredential: identityCredential,
MerkleProof: merkleProof,
X: HashToBN255(data),
Epoch: epoch,
RlnIdentifier: RLN_IDENTIFIER,
}
}
func ToIdentityCredentials(groupKeys [][]string) ([]IdentityCredential, error) {
// groupKeys is sequence of membership key tuples in the form of (identity key, identity commitment) all in the hexadecimal format
// the toIdentityCredentials proc populates a sequence of IdentityCredentials using the supplied groupKeys