More changes

This commit is contained in:
alrevuelta 2024-01-18 16:34:27 +01:00
parent 4c93f5564f
commit d275cbaa0b
No known key found for this signature in database
GPG Key ID: F345C9F3CCDB886E
5 changed files with 132 additions and 112 deletions

View File

@ -6,7 +6,6 @@ import (
"encoding/json"
"errors"
"fmt"
"math/big"
"github.com/waku-org/go-zerokit-rln/rln/link"
)
@ -138,6 +137,16 @@ func appendLength(input []byte) []byte {
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
func appendLength32(input []byte) []byte {
inputLen := make([]byte, 8)
binary.LittleEndian.PutUint64(inputLen, uint64(len(input)/32))
return append(inputLen, input...)
}
func (r *RLN) Sha256(data []byte) (MerkleNode, error) {
lenPrefData := appendLength(data)
@ -236,9 +245,9 @@ func (r *RLN) GenerateProof(data []byte, key IdentityCredential, index Membershi
// input :
/*
identity_secret: Fr,
path_elements: Vec<Fr>,
identity_path_index: Vec<u8>,
x: 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,
*/
@ -350,7 +359,7 @@ func (r *RLN) Verify(data []byte, proof RateLimitProof, roots ...[32]byte) (bool
return false, err
}
return bool(res), nil
return res, nil
}
// RecoverIDSecret returns an IDSecret having obtained before two proofs
@ -464,60 +473,10 @@ func (r *RLN) GetMerkleProof(index MembershipIndex) (MerkleProof, error) {
return MerkleProof{}, err
}
// TODO: Take this from the function
// Check if we can read the first byte
if len(proofBytes) < 8 {
return MerkleProof{}, errors.New(fmt.Sprintf("wrong output size: %d", len(proofBytes)))
}
var result MerkleProof
var numElements big.Int
var numIndexes big.Int
offset := 0
// Get amounf of elements in the proof
numElements.SetBytes(revert(proofBytes[offset : offset+8]))
offset += 8
// With numElements we can determine the expected length of the proof.
expectedLen := 8 + int(32*numElements.Uint64()) + 8 + int(numElements.Uint64())
if len(proofBytes) != expectedLen {
return MerkleProof{}, errors.New(fmt.Sprintf("wrong output size expected: %d, current: %d",
expectedLen,
len(proofBytes)))
}
result.PathElements = make([]MerkleNode, numElements.Uint64())
for i := uint64(0); i < numElements.Uint64(); i++ {
copy(result.PathElements[i][:], proofBytes[offset:offset+32])
offset += 32
}
// Get amount of indexes in the path
numIndexes.SetBytes(revert(proofBytes[offset : offset+8]))
offset += 8
// Both numElements and numIndexes shall be equal and match the tree depth.
if numIndexes.Uint64() != numElements.Uint64() {
return MerkleProof{}, errors.New(fmt.Sprintf("amount of values in path and indexes do not match: %s vs %s",
numElements.String(), numIndexes.String()))
}
// TODO: Depth check, but currently not accesible
result.PathIndexes = make([]uint8, numIndexes.Uint64())
for i := uint64(0); i < numIndexes.Uint64(); i++ {
result.PathIndexes[i] = proofBytes[offset]
offset += 1
}
if offset != len(proofBytes) {
return MerkleProof{}, errors.New(
fmt.Sprintf("error parsing proof read: %d, length; %d", offset, len(proofBytes)))
err = result.deserialize(proofBytes)
if err != nil {
return MerkleProof{}, err
}
return result, nil

View File

@ -3,6 +3,7 @@ package rln
import (
"bytes"
"encoding/hex"
"fmt"
"math"
"testing"
@ -354,20 +355,17 @@ func (s *RLNSuite) TestGenerateRLNProofWithWitness() {
rln, err := NewRLN()
s.NoError(err)
// Leaf we generate the proof for
memberIndex := uint(4)
memKeys, err := rln.MembershipKeyGen()
s.NoError(err)
//peer's index in the Merkle Tree
index := 5
// Create a Merkle tree with random members
for i := 0; i < 10; i++ {
if i == index {
// insert the current peer's pk
for i := 0; i < 16; i++ {
if i == int(memberIndex) {
err := rln.InsertMember(memKeys.IDCommitment)
s.NoError(err)
} else {
// create a new key pair
memberKeys, err := rln.MembershipKeyGen()
s.NoError(err)
@ -379,33 +377,47 @@ func (s *RLNSuite) TestGenerateRLNProofWithWitness() {
root, err := rln.GetMerkleRoot()
s.NoError(err)
// prepare the message
msg := []byte("Hello")
fmt.Println("root from zerokit: ", root)
// prepare the epoch
var epoch Epoch
// Inputs for proof generation
msg := [32]byte{0x00, 0x00, 0x01}
var epoch = Epoch([32]byte{0x00, 0x00, 0x00, 0x00, 0x01})
badIndex := 4
merkleProof, err := rln.GetMerkleProof(uint(badIndex))
// We provide out custom witness
merkleProof, err := rln.GetMerkleProof(memberIndex)
s.NoError(err)
rlnWitness := RLNWitnessInput{
// memberIndex key
IdentityCredential: *memKeys,
MerkleProof: merkleProof,
Data: msg,
Data: msg[:],
Epoch: epoch,
RlnIdentifier: [32]byte{0x00, 0x00, 0x00}, // TODO
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
}
// generate proof
proofRes, err := rln.GenerateRLNProofWithWitness(rlnWitness)
s.NoError(err)
// verify the proof (should not be verified)
verified, err := rln.Verify(msg, *proofRes, root)
fmt.Println("Proof Epoch: ", proofRes.Epoch)
fmt.Println("Proof Nullifier: ", proofRes.Nullifier)
fmt.Println("Proof ShareX: ", proofRes.ShareX)
fmt.Println("Proof ShareY: ", proofRes.ShareY)
fmt.Println("Proof MerkleRoot: ", proofRes.MerkleRoot)
fmt.Println("Proof RlnIdentifier: ", proofRes.RLNIdentifier)
// verify the proof
//msg := [32]byte{0x00, 0x00, 0x01}
//verified, err := rln.Verify([]byte{0x00, 0x00, 0x01}, *proofRes, root)
verified, err := rln.Verify(msg[:], *proofRes, root)
s.NoError(err)
s.False(verified)
_ = verified
// TODO: Not working
//s.True(verified)
// TODO: test a proof that shall not be verified
}
func (s *RLNSuite) TestEpochConsistency() {

View File

@ -53,17 +53,22 @@ func (r *RLNWitnessInput) serialize() []byte {
output = append(output, r.IdentityCredential.IDSecretHash[:]...)
output = append(output, r.MerkleProof.serialize()...)
output = append(output, appendLength(r.Data)...)
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.Epoch[:]...)
output = append(output, r.RlnIdentifier[:]...)
return output
}
func (r *RLNWitnessInput) deserialize(b []byte) error {
return errors.New("not implemented")
}
func (r *MerkleProof) serialize() []byte {
output := make([]byte, 0)
output = append(output, appendLength(Flatten(r.PathElements))...)
output = append(output, appendLength32(Flatten(r.PathElements))...)
output = append(output, appendLength(r.PathIndexes)...)
return output
@ -73,7 +78,7 @@ func (r *MerkleProof) deserialize(b []byte) error {
// Check if we can read the first byte
if len(b) < 8 {
return errors.New(fmt.Sprintf("wrong output size: %d", len(b)))
return errors.New(fmt.Sprintf("wrong input size: %d", len(b)))
}
var numElements big.Int
@ -88,7 +93,7 @@ func (r *MerkleProof) deserialize(b []byte) error {
// With numElements we can determine the expected length of the proof.
expectedLen := 8 + int(32*numElements.Uint64()) + 8 + int(numElements.Uint64())
if len(b) != expectedLen {
return errors.New(fmt.Sprintf("wrong output size expected: %d, current: %d",
return errors.New(fmt.Sprintf("wrong input size expected: %d, current: %d",
expectedLen,
len(b)))
}

View File

@ -16,41 +16,64 @@ func random32() [32]byte {
func TestMerkleProofSerDe(t *testing.T) {
mProof := MerkleProof{
PathElements: []MerkleNode{},
PathIndexes: []uint8{},
for _, testSize := range []int{0, 1, 8, 16, 20} {
mProof := MerkleProof{
PathElements: []MerkleNode{},
PathIndexes: []uint8{},
}
for i := 0; i < testSize; i++ {
mProof.PathElements = append(mProof.PathElements, random32())
mProof.PathIndexes = append(mProof.PathIndexes, uint8(i%2))
}
// Check the size is the expected
ser := mProof.serialize()
require.Equal(t, 8+testSize*32+testSize+8, len(ser))
fmt.Println("path:", mProof.PathElements)
fmt.Println("Serialized: ", ser)
// Deserialize and check its matches the original
desProof := MerkleProof{}
err := desProof.deserialize(ser)
require.NoError(t, err)
require.Equal(t, mProof, desProof)
}
ser := mProof.serialize()
//require.Equal(t, []byte{0, 0, 0, 0}, ser, )
require.Equal(t, 16, len(ser))
mProof = MerkleProof{
PathElements: []MerkleNode{[32]byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0}},
PathIndexes: []uint8{0},
}
ser = mProof.serialize()
//require.Equal(t, []byte{0, 0, 0, 0}, ser, )
require.Equal(t, 49, len(ser))
mProof = MerkleProof{}
for i := 0; i < 16; i++ {
mProof.PathElements = append(mProof.PathElements, random32())
mProof.PathIndexes = append(mProof.PathIndexes, uint8(i%2))
}
ser = mProof.serialize()
fmt.Println(ser)
desProof := MerkleProof{}
err := desProof.deserialize(ser)
require.NoError(t, err)
// TODO test for errors. eg different size.
}
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{
PathElements: []MerkleNode{},
PathIndexes: []uint8{},
}
for i := 0; i < depth; i++ {
mProof.PathElements = append(mProof.PathElements, random32())
mProof.PathIndexes = append(mProof.PathIndexes, uint8(i%2))
}
witness := RLNWitnessInput{
IdentityCredential: IdentityCredential{
IDSecretHash: random32(),
},
MerkleProof: mProof,
Data: data[:],
Epoch: ToEpoch(10),
RlnIdentifier: [32]byte{0x00},
}
ser := witness.serialize()
require.Equal(t, 32+8+depth*32+depth+8+32+32+32, len(ser))
// TODO:
//desWitness := RLNWitnessInput{}
//err := desWitness.deserialize(ser)
}

View File

@ -20,4 +20,25 @@ func TestBigInt(t *testing.T) {
require.True(t, bytes.Equal(newValue.Bytes(), value.Bytes()))
}
// TODO: Test Flatten
func TestFlatten(t *testing.T) {
in1 := [][32]byte{[32]byte{}}
in2 := [][32]byte{[32]byte{0x00}, [32]byte{0x01}}
in3 := [][32]byte{[32]byte{0x01, 0x02, 0x03}, [32]byte{0x04, 0x05, 0x06}}
expected1 := []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
expected2 := []byte{
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
expected3 := []byte{
0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x4, 0x5, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
out1 := Flatten(in1)
require.Equal(t, expected1, out1)
out2 := Flatten(in2)
require.Equal(t, expected2, out2)
out3 := Flatten(in3)
require.Equal(t, expected3, out3)
}