mirror of
https://github.com/logos-messaging/go-zerokit-rln.git
synced 2026-01-02 13:13:11 +00:00
More changes
This commit is contained in:
parent
4c93f5564f
commit
d275cbaa0b
75
rln/rln.go
75
rln/rln.go
@ -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
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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)))
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user