Verify works now

This commit is contained in:
alrevuelta 2024-01-22 17:36:15 +01:00
parent 85a45dc73a
commit 28a98ba8c0
No known key found for this signature in database
GPG Key ID: F345C9F3CCDB886E
6 changed files with 49 additions and 184 deletions

5
go.mod
View File

@ -3,21 +3,22 @@ module github.com/waku-org/go-zerokit-rln
go 1.19
require (
github.com/consensys/gnark-crypto v0.12.1
github.com/ethereum/go-ethereum v1.13.10
github.com/stretchr/testify v1.8.4
github.com/waku-org/go-zerokit-rln-apple v0.0.0-20240117094748-68b4162e8fd7
github.com/waku-org/go-zerokit-rln-arm v0.0.0-20240116134931-a8b8c6ab4b80
github.com/waku-org/go-zerokit-rln-x86_64 v0.0.0-20240116135046-2875fec12afc
golang.org/x/crypto v0.18.0
)
require (
github.com/bits-and-blooms/bitset v1.10.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/holiman/uint256 v1.2.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/sys v0.16.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

9
go.sum
View File

@ -1,6 +1,10 @@
github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88=
github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k=
github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M=
github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
@ -11,11 +15,9 @@ github.com/ethereum/go-ethereum v1.13.10 h1:Ppdil79nN+Vc+mXfge0AuUgmKWuVv4eMqzoI
github.com/ethereum/go-ethereum v1.13.10/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA=
github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU=
github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
@ -33,6 +35,5 @@ golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -377,80 +377,51 @@ func (s *RLNSuite) TestGenerateRLNProofWithWitness() {
root, err := rln.GetMerkleRoot()
s.NoError(err)
// TODO: Add some asserts on roots
fmt.Println("root from zerokit: ", root)
// Inputs for proof generation
msg := [32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0}
//msg := [32]byte{69, 7, 140, 46, 26, 131, 147, 30, 161, 68, 2, 5, 234, 195, 227, 223, 119, 187, 116, 97, 153, 70, 71, 254, 60, 149, 54, 109, 77, 79, 105, 20}
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)
//hashMsg, err := rln.Poseidon(msg[:])
//s.NoError(err)
hashMsg := [32]byte{69, 7, 140, 46, 26, 131, 147, 30, 161, 68, 2, 5, 234, 195, 227, 223, 119, 187, 116, 97, 153, 70, 71, 254, 60, 149, 54, 109, 77, 79, 105, 20}
// TODO: This should be abstracted away, move inside somewhere
x := HashToBN255(msg)
rlnWitness := RLNWitnessInput{
// memberIndex key
IdentityCredential: *memKeys,
MerkleProof: merkleProof,
Data: hashMsg[:],
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
}
fmt.Println("Witness secrethash ", rlnWitness.IdentityCredential.IDSecretHash)
fmt.Println("Witness merkle path", rlnWitness.MerkleProof.PathElements)
fmt.Println("Witness merkle indexes", rlnWitness.MerkleProof.PathIndexes)
fmt.Println("Witness data", rlnWitness.Data)
fmt.Println("Witness epoch", rlnWitness.Epoch)
fmt.Println("Witness rln identifier", rlnWitness.RlnIdentifier)
// generate proof
proofRes, err := rln.GenerateRLNProofWithWitness(rlnWitness)
// Generate a proof with our custom witness (Merkle Path of the memberIndex)
proofRes1, err := rln.GenerateRLNProofWithWitness(rlnWitness)
s.NoError(err)
//proofRes.ShareX = dataToReplace
fmt.Println("Proof Epoch: ", proofRes)
// TODO: for testing. proof without witness (are proofs deterministic? maybe not)
proofRes2, err := rln.GenerateProof(msg[:], *memKeys, MembershipIndex(memberIndex), epoch)
s.NoError(err)
fmt.Println("Proof1 Epoch: ", proofRes2.Epoch)
fmt.Println("Proof1 Nullifier: ", proofRes2.Nullifier)
fmt.Println("Proof1 ShareX: ", proofRes2.ShareX)
fmt.Println("Proof1 ShareY: ", proofRes2.ShareY)
fmt.Println("Proof1 MerkleRoot: ", proofRes2.MerkleRoot)
fmt.Println("Proof1 RlnIdentifier: ", proofRes2.RLNIdentifier)
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)
// Verifty old proofs
verified1, err := rln.Verify(msg[:], *proofRes2, root)
verified1, err := rln.Verify(msg[:], *proofRes1, root)
s.NoError(err)
s.True(verified1)
// verify the proof with the witness
//msg := [32]byte{0x00, 0x00, 0x01}
//verified, err := rln.Verify([]byte{0x00, 0x00, 0x01}, *proofRes, root)
verified, err := rln.Verify(msg[:], *proofRes, root)
proofRes2, err := rln.GenerateProof(msg[:], *memKeys, MembershipIndex(memberIndex), epoch)
s.NoError(err)
_ = verified
// TODO: Not working
s.True(verified)
// 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
s.Equal(proofRes1.MerkleRoot, proofRes2.MerkleRoot)
s.Equal(proofRes1.Epoch, proofRes2.Epoch)
s.Equal(proofRes1.ShareX, proofRes2.ShareX)
s.Equal(proofRes1.ShareY, proofRes2.ShareY)
s.Equal(proofRes1.Nullifier, proofRes2.Nullifier)
s.Equal(proofRes1.RLNIdentifier, proofRes2.RLNIdentifier)
// TODO: test a proof that shall not be verified
// TODO: generate multiple proofs with random data
}
func (s *RLNSuite) TestEpochConsistency() {

View File

@ -74,7 +74,7 @@ type RLNWitnessInput struct {
MerkleProof MerkleProof `json:"merkleProof"`
// This is not the data but the hashed version of it "x"..TODO rename and reconsider
Data []byte `json:"data"`
Data []byte `json:"data"` // TODO: this should be fixed 32
Epoch Epoch `json:"epoch"`
RlnIdentifier RLNIdentifier `json:"rlnIdentifier"` // what is this? TOOD: app specific. which one is ours?
}

View File

@ -2,9 +2,9 @@ package rln
import (
"encoding/hex"
"fmt"
"math/big"
"github.com/consensys/gnark-crypto/ecc/bn254/fr"
"github.com/ethereum/go-ethereum/crypto"
)
@ -110,38 +110,19 @@ func Bytes32ToBigInt(value [32]byte) *big.Int {
return result
}
func EndianConvertTODO(data []byte) [32]byte {
// Hashes a byte array to a field element in BN254, as used by zerokit.
// Equivalent to: https://github.com/vacp2p/zerokit/blob/v0.3.4/rln/src/hashers.rs
func HashToBN255(data []byte) [32]byte {
// Hash is fixed to 32 bytes
hashed := crypto.Keccak256(data[:])
hashGoEth := crypto.Keccak256(data[:])
_ = hashGoEth
//if len(hashGoEth) != 32 {
// fmt.Println("errorrrrrr")
// }
myHash32 := [32]byte{}
// copy(myHash32[:], hashGoEth)
// Convert to field element
var frBN254 fr.Element
frBN254.Unmarshal(revert(hashed))
frBN254Bytes := frBN254.Bytes()
// el hash esta controlado por ahora
copy(myHash32[:], data)
fmt.Println("inpit is: ", data)
fmt.Println("hash is: ", myHash32)
var uintVals [4]uint64
for i := 0; i < 4; i++ {
chunk := make([]byte, 8)
copy(chunk, myHash32[i*8:(i+1)*8])
fmt.Println("chunk is: ", chunk)
myBig := new(big.Int)
myBig.SetBytes(revert(chunk))
fmt.Println("big is: ", myBig)
uintVals[i] = myBig.Uint64()
}
fmt.Println("uintVals is: ", uintVals)
returnthis := [32]byte{}
return returnthis
// Return fixed size
fixexLen := [32]byte{}
copy(fixexLen[:], revert(frBN254Bytes[:]))
return fixexLen
}

View File

@ -4,8 +4,6 @@ import (
"bytes"
"fmt"
"math/big"
"strconv"
"strings"
"testing"
"github.com/stretchr/testify/require"
@ -45,100 +43,13 @@ func TestFlatten(t *testing.T) {
out3 := Flatten(in3)
require.Equal(t, expected3, out3)
}
func TestTODO(t *testing.T) {
func TestHashToBN255(t *testing.T) {
// Inputs for proof generation
msg := []byte{72, 7, 140, 254, 213, 99, 57, 234, 84, 150, 46, 114, 195, 124, 127, 88, 143, 196, 248, 229, 188, 23, 56, 39, 186, 117, 203, 16, 166, 58, 150, 165}
msg := []byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
conv := EndianConvertTODO(msg)
fmt.Println(conv)
ints := []uint64{16877630849297418056, 6376952776256034388, 2826034866254562447, 11931788747685459386}
fmt.Println(ints[0])
str := ""
for i, _ := range ints {
str = str + padBinaryString(uint64ToBinaryString(ints[4-i-1]), 64)
}
fmt.Println("-- ", str)
byteArray, err := binaryStringToBytes(str)
if err != nil {
fmt.Println("Error:", err)
return
}
myBigInt := new(big.Int)
myBigInt.SetBytes(byteArray[:])
fmt.Println("mybigint", myBigInt.String())
fmt.Println(byteArray)
// Expected
// in := [32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0}
// hashed: []byte{72, 7, 140, 254, 213, 99, 57, 234, 84, 150, 46, 114, 195, 124, 127, 88, 143, 196, 248, 229, 188, 23, 56, 39, 186, 117, 203, 16, 166, 58, 150, 165}
// expected := [32]byte{69, 7, 140, 46, 26, 131, 147, 30, 161, 68, 2, 5, 234, 195, 227, 223, 119, 187, 116, 97, 153, 70, 71, 254, 60, 149, 54, 109, 77, 79, 105, 20}
}
func reverseString(input string) string {
// Convert string to a slice of runes
runes := []rune(input)
// Reverse the order of runes
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
// Convert the slice of runes back to a string
reversedString := string(runes)
return reversedString
}
func binaryStringToBytes(binaryString string) ([32]byte, error) {
var byteArray [32]byte
// Ensure the binary string has 256 bits (32 bytes)
if len(binaryString) != 256 {
return byteArray, fmt.Errorf("binary string must have exactly 256 bits")
}
// Iterate over 32 chunks of 8 bits each and parse them to bytes
for i := 0; i < 32; i++ {
startIndex := i * 8
endIndex := startIndex + 8
bits := binaryString[startIndex:endIndex]
// Parse the 8-bit chunk to a byte
byteValue, err := strconv.ParseUint(bits, 2, 8)
if err != nil {
return byteArray, err
}
byteArray[i] = byte(byteValue)
}
return byteArray, nil
}
func padBinaryString(binaryString string, length int) string {
// Calculate padding length
paddingLength := length - len(binaryString)
// Pad with zeros
paddedBinaryString := strings.Repeat("0", paddingLength) + binaryString
return paddedBinaryString
}
func bigIntToBinaryString(num *big.Int) string {
return fmt.Sprintf("%b", num)
}
func uint64ToBinaryString(num uint64) string {
return strconv.FormatUint(num, 2)
out := HashToBN255(msg)
fmt.Println("out: ", out)
require.Equal(t,
[32]byte{69, 7, 140, 46, 26, 131, 147, 30, 161, 68, 2, 5, 234, 195, 227, 223, 119, 187, 116, 97, 153, 70, 71, 254, 60, 149, 54, 109, 77, 79, 105, 20},
out)
}