diff --git a/LICENSE b/LICENSE index 915b62e..8efb4fd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ MIT License Copyright (c) 2021 Dean Eigenmann +Copyright (c) 2022 Status Research & Development GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index 6b2be34..e877c18 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,20 @@ .PHONY: rlnlib -rlnlib: - sh scripts/build.sh +SHELL := bash # the shell used internally by Make + +GOBIN ?= $(shell which go) + +rlnlib-cross: + scripts/build-cross.sh cd lib/rln && cbindgen --config ../cbindgen.toml --crate rln --output ../../rln/librln.h --lang c + +rlnlib: + scripts/build.sh + cd lib/rln && cbindgen --config ../cbindgen.toml --crate rln --output ../../rln/librln.h --lang c + +generate: + ${GOBIN} generate ./rln/pb/generate.go + ${GOBIN} generate ./rln/contracts/generate.go + +test: + LD_LIBRARY_PATH="${PWD}/libs/x86_64-unknown-linux-gnu/" go test ./... -count 1 -v \ No newline at end of file diff --git a/README.md b/README.md index 415a790..8a31436 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,36 @@ Further research can be found here: The goal of this is to create a rate-limiter for blockchains where block production is cheap. I started playing around with this after talking to the team at [Celestia](https://celestia.org/). + + +### Building this library + +#### Using [cross](https://github.com/cross-rs) + +``` +make rlnlibs-cross +``` + +Some architectures are not available in cross unless they're locally build. This [PR](https://github.com/cross-rs/cross/pull/591) will update ubuntu base version on cross. But while it's merged, build them locally. To build them locally execute the following instructions (adapted from [here](https://github.com/cross-rs/cross/wiki/FAQ#newer-linux-versions)): + +``` +git clone --single-branch --depth 1 --branch increment_versions https://github.com/Alexhuszagh/cross +cd cross +cargo build-docker-image x86_64-pc-windows-gnu +cargo build-docker-image aarch64-unknown-linux-gnu +cargo build-docker-image x86_64-unknown-linux-gnu +cargo build-docker-image arm-unknown-linux-gnueabi +cargo build-docker-image i686-pc-windows-gnu +cargo build-docker-image i686-unknown-linux-gnu +cargo build-docker-image arm-unknown-linux-gnueabihf +cargo build-docker-image mips-unknown-linux-gnu +cargo build-docker-image mips64-unknown-linux-gnuabi64 +cargo build-docker-image mips64el-unknown-linux-gnuabi64 +cargo build-docker-image mipsel-unknown-linux-gnu +``` + +#### Using [rustup](https://rust-lang.github.io/rustup/cross-compilation.html) + +``` +make rlnlibs-cross +``` \ No newline at end of file diff --git a/go.mod b/go.mod index a527e55..8c85738 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,9 @@ module github.com/decanus/go-rln go 1.16 + +require ( + github.com/ethereum/go-ethereum v1.10.20 + github.com/golang/protobuf v1.5.2 + github.com/stretchr/testify v1.7.2 +) diff --git a/go.sum b/go.sum index e29e10a..168f86b 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,622 @@ -github.com/cbergoon/merkletree v0.2.0 h1:Bttqr3OuoiZEo4ed1L7fTasHka9II+BF9fhBfbNEEoQ= -github.com/cbergoon/merkletree v0.2.0/go.mod h1:5c15eckUgiucMGDOCanvalj/yJnD+KAZj1qyJtRW5aM= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= +github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= +github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= +github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= +github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= +github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= +github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= +github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= +github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +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/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= +github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= +github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= +github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= +github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/docker/docker v1.6.2/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= +github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ethereum/go-ethereum v1.10.20 h1:75IW830ClSS40yrQC1ZCMZCt5I+zU16oqId2SiQwdQ4= +github.com/ethereum/go-ethereum v1.10.20/go.mod h1:LWUN82TCHGpxB3En5HVmLLzPD7YSrEUFmFfN1nKkVN0= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= +github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= +github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= +github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= +github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= +github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= +github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= +github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= +github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= +github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= +github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= +github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +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/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= +github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= +github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= +github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= +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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= +github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE= +github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= +github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= +github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= +github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= +github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= +github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191126055441-b0650ceb63d9/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= +gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/lib/rln b/lib/rln index 628fd74..7ac7418 160000 --- a/lib/rln +++ b/lib/rln @@ -1 +1 @@ -Subproject commit 628fd742237f49347469dfcbbe57fd591d6629b1 +Subproject commit 7ac74183f8b69b399e3bc96c1ae8ab61c026dc43 diff --git a/libs/aarch64-linux-android/librln.d b/libs/aarch64-linux-android/librln.d new file mode 100644 index 0000000..7834959 --- /dev/null +++ b/libs/aarch64-linux-android/librln.d @@ -0,0 +1 @@ +/target/aarch64-linux-android/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/aarch64-linux-android/release/build/num-bigint-4ba1a00c5942ed3b/out/radix_bases.rs build.rs diff --git a/libs/aarch64-linux-android/librln.rlib b/libs/aarch64-linux-android/librln.rlib new file mode 100644 index 0000000..ade059f Binary files /dev/null and b/libs/aarch64-linux-android/librln.rlib differ diff --git a/libs/aarch64-unknown-linux-gnu/librln.d b/libs/aarch64-unknown-linux-gnu/librln.d new file mode 100644 index 0000000..662d2d7 --- /dev/null +++ b/libs/aarch64-unknown-linux-gnu/librln.d @@ -0,0 +1 @@ +/target/aarch64-unknown-linux-gnu/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/aarch64-unknown-linux-gnu/release/build/num-bigint-69b80aa090dc4b25/out/radix_bases.rs build.rs diff --git a/libs/aarch64-unknown-linux-gnu/librln.rlib b/libs/aarch64-unknown-linux-gnu/librln.rlib new file mode 100644 index 0000000..df00039 Binary files /dev/null and b/libs/aarch64-unknown-linux-gnu/librln.rlib differ diff --git a/libs/arm-unknown-linux-gnueabi/librln.d b/libs/arm-unknown-linux-gnueabi/librln.d new file mode 100644 index 0000000..b5c51e8 --- /dev/null +++ b/libs/arm-unknown-linux-gnueabi/librln.d @@ -0,0 +1 @@ +/target/arm-unknown-linux-gnueabi/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/arm-unknown-linux-gnueabi/release/build/num-bigint-9bbf2c096f81fccc/out/radix_bases.rs build.rs diff --git a/libs/arm-unknown-linux-gnueabi/librln.rlib b/libs/arm-unknown-linux-gnueabi/librln.rlib new file mode 100644 index 0000000..6b54527 Binary files /dev/null and b/libs/arm-unknown-linux-gnueabi/librln.rlib differ diff --git a/libs/arm-unknown-linux-gnueabihf/librln.d b/libs/arm-unknown-linux-gnueabihf/librln.d new file mode 100644 index 0000000..82701e9 --- /dev/null +++ b/libs/arm-unknown-linux-gnueabihf/librln.d @@ -0,0 +1 @@ +/target/arm-unknown-linux-gnueabihf/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/arm-unknown-linux-gnueabihf/release/build/num-bigint-c5d4eab0df01f46f/out/radix_bases.rs build.rs diff --git a/libs/arm-unknown-linux-gnueabihf/librln.rlib b/libs/arm-unknown-linux-gnueabihf/librln.rlib new file mode 100644 index 0000000..1e4998a Binary files /dev/null and b/libs/arm-unknown-linux-gnueabihf/librln.rlib differ diff --git a/libs/armv7-linux-androideabi/librln.d b/libs/armv7-linux-androideabi/librln.d new file mode 100644 index 0000000..7cfd9f8 --- /dev/null +++ b/libs/armv7-linux-androideabi/librln.d @@ -0,0 +1 @@ +/target/armv7-linux-androideabi/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/armv7-linux-androideabi/release/build/num-bigint-8fa42ea69abd53fb/out/radix_bases.rs build.rs diff --git a/libs/armv7-linux-androideabi/librln.rlib b/libs/armv7-linux-androideabi/librln.rlib new file mode 100644 index 0000000..7caf0af Binary files /dev/null and b/libs/armv7-linux-androideabi/librln.rlib differ diff --git a/libs/i686-linux-android/librln.d b/libs/i686-linux-android/librln.d new file mode 100644 index 0000000..ae956f5 --- /dev/null +++ b/libs/i686-linux-android/librln.d @@ -0,0 +1 @@ +/target/i686-linux-android/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/i686-linux-android/release/build/num-bigint-5b002515a3c1c3de/out/radix_bases.rs build.rs diff --git a/libs/i686-linux-android/librln.rlib b/libs/i686-linux-android/librln.rlib new file mode 100644 index 0000000..7aecd76 Binary files /dev/null and b/libs/i686-linux-android/librln.rlib differ diff --git a/libs/i686-pc-windows-gnu/librln.d b/libs/i686-pc-windows-gnu/librln.d new file mode 100644 index 0000000..c240a71 --- /dev/null +++ b/libs/i686-pc-windows-gnu/librln.d @@ -0,0 +1 @@ +/target/i686-pc-windows-gnu/release/librln.rlib: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/i686-pc-windows-gnu/release/build/num-bigint-cab2a6b70097bfc3/out/radix_bases.rs build.rs diff --git a/libs/i686-pc-windows-gnu/librln.dll.a b/libs/i686-pc-windows-gnu/librln.dll.a new file mode 100644 index 0000000..1acf675 Binary files /dev/null and b/libs/i686-pc-windows-gnu/librln.dll.a differ diff --git a/libs/i686-pc-windows-gnu/librln.rlib b/libs/i686-pc-windows-gnu/librln.rlib new file mode 100644 index 0000000..8a8c777 Binary files /dev/null and b/libs/i686-pc-windows-gnu/librln.rlib differ diff --git a/libs/i686-unknown-linux-gnu/librln.d b/libs/i686-unknown-linux-gnu/librln.d new file mode 100644 index 0000000..3e5005b --- /dev/null +++ b/libs/i686-unknown-linux-gnu/librln.d @@ -0,0 +1 @@ +/target/i686-unknown-linux-gnu/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/i686-unknown-linux-gnu/release/build/num-bigint-b0e1c075ff9f6d68/out/radix_bases.rs build.rs diff --git a/libs/i686-unknown-linux-gnu/librln.rlib b/libs/i686-unknown-linux-gnu/librln.rlib new file mode 100644 index 0000000..7e9e39b Binary files /dev/null and b/libs/i686-unknown-linux-gnu/librln.rlib differ diff --git a/libs/mips-unknown-linux-gnu/librln.d b/libs/mips-unknown-linux-gnu/librln.d new file mode 100644 index 0000000..0c3f27e --- /dev/null +++ b/libs/mips-unknown-linux-gnu/librln.d @@ -0,0 +1 @@ +/target/mips-unknown-linux-gnu/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/mips-unknown-linux-gnu/release/build/num-bigint-2a58e28365905d0a/out/radix_bases.rs build.rs diff --git a/libs/mips-unknown-linux-gnu/librln.rlib b/libs/mips-unknown-linux-gnu/librln.rlib new file mode 100644 index 0000000..ef12d55 Binary files /dev/null and b/libs/mips-unknown-linux-gnu/librln.rlib differ diff --git a/libs/mips64-unknown-linux-gnuabi64/librln.d b/libs/mips64-unknown-linux-gnuabi64/librln.d new file mode 100644 index 0000000..95c46ff --- /dev/null +++ b/libs/mips64-unknown-linux-gnuabi64/librln.d @@ -0,0 +1 @@ +/target/mips64-unknown-linux-gnuabi64/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/mips64-unknown-linux-gnuabi64/release/build/num-bigint-a70850dcc99c7fb1/out/radix_bases.rs build.rs diff --git a/libs/mips64-unknown-linux-gnuabi64/librln.rlib b/libs/mips64-unknown-linux-gnuabi64/librln.rlib new file mode 100644 index 0000000..c3b6d38 Binary files /dev/null and b/libs/mips64-unknown-linux-gnuabi64/librln.rlib differ diff --git a/libs/mips64el-unknown-linux-gnuabi64/librln.d b/libs/mips64el-unknown-linux-gnuabi64/librln.d new file mode 100644 index 0000000..3ceaf0f --- /dev/null +++ b/libs/mips64el-unknown-linux-gnuabi64/librln.d @@ -0,0 +1 @@ +/target/mips64el-unknown-linux-gnuabi64/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/mips64el-unknown-linux-gnuabi64/release/build/num-bigint-0b729d8fe959893e/out/radix_bases.rs build.rs diff --git a/libs/mips64el-unknown-linux-gnuabi64/librln.rlib b/libs/mips64el-unknown-linux-gnuabi64/librln.rlib new file mode 100644 index 0000000..8a244c7 Binary files /dev/null and b/libs/mips64el-unknown-linux-gnuabi64/librln.rlib differ diff --git a/libs/mipsel-unknown-linux-gnu/librln.d b/libs/mipsel-unknown-linux-gnu/librln.d new file mode 100644 index 0000000..0705146 --- /dev/null +++ b/libs/mipsel-unknown-linux-gnu/librln.d @@ -0,0 +1 @@ +/target/mipsel-unknown-linux-gnu/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/mipsel-unknown-linux-gnu/release/build/num-bigint-23ad468891d1fc36/out/radix_bases.rs build.rs diff --git a/libs/mipsel-unknown-linux-gnu/librln.rlib b/libs/mipsel-unknown-linux-gnu/librln.rlib new file mode 100644 index 0000000..7e9f564 Binary files /dev/null and b/libs/mipsel-unknown-linux-gnu/librln.rlib differ diff --git a/libs/x86_64-apple-darwin/librln.d b/libs/x86_64-apple-darwin/librln.d deleted file mode 100644 index eca7915..0000000 --- a/libs/x86_64-apple-darwin/librln.d +++ /dev/null @@ -1 +0,0 @@ -/Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/target/x86_64-apple-darwin/release/librln.dylib: /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/circuit/mod.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/circuit/polynomial.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/circuit/poseidon.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/circuit/rln.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/ffi.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/lib.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/merkle.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/poseidon.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/public.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/utils.rs diff --git a/libs/x86_64-apple-darwin/librln.rlib b/libs/x86_64-apple-darwin/librln.rlib deleted file mode 100644 index 2f5185f..0000000 Binary files a/libs/x86_64-apple-darwin/librln.rlib and /dev/null differ diff --git a/libs/x86_64-linux-android/librln.d b/libs/x86_64-linux-android/librln.d new file mode 100644 index 0000000..9f741e7 --- /dev/null +++ b/libs/x86_64-linux-android/librln.d @@ -0,0 +1 @@ +/target/x86_64-linux-android/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/x86_64-linux-android/release/build/num-bigint-a07eaff1eafc61a9/out/radix_bases.rs build.rs diff --git a/libs/x86_64-linux-android/librln.rlib b/libs/x86_64-linux-android/librln.rlib new file mode 100644 index 0000000..dc1ec97 Binary files /dev/null and b/libs/x86_64-linux-android/librln.rlib differ diff --git a/libs/x86_64-pc-windows-gnu/librln.d b/libs/x86_64-pc-windows-gnu/librln.d new file mode 100644 index 0000000..f59b149 --- /dev/null +++ b/libs/x86_64-pc-windows-gnu/librln.d @@ -0,0 +1 @@ +/target/x86_64-pc-windows-gnu/release/librln.rlib: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/x86_64-pc-windows-gnu/release/build/num-bigint-2d87d54ca5f526b6/out/radix_bases.rs build.rs diff --git a/libs/x86_64-pc-windows-gnu/librln.dll.a b/libs/x86_64-pc-windows-gnu/librln.dll.a new file mode 100644 index 0000000..b10aa1a Binary files /dev/null and b/libs/x86_64-pc-windows-gnu/librln.dll.a differ diff --git a/libs/x86_64-pc-windows-gnu/librln.rlib b/libs/x86_64-pc-windows-gnu/librln.rlib new file mode 100644 index 0000000..ff7f9c3 Binary files /dev/null and b/libs/x86_64-pc-windows-gnu/librln.rlib differ diff --git a/libs/x86_64-unknown-linux-gnu/librln.d b/libs/x86_64-unknown-linux-gnu/librln.d new file mode 100644 index 0000000..b1393c5 --- /dev/null +++ b/libs/x86_64-unknown-linux-gnu/librln.d @@ -0,0 +1 @@ +/target/x86_64-unknown-linux-gnu/release/librln.so: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/x86_64-unknown-linux-gnu/release/build/num-bigint-e05ef1c2b46a8adc/out/radix_bases.rs build.rs diff --git a/libs/x86_64-unknown-linux-gnu/librln.rlib b/libs/x86_64-unknown-linux-gnu/librln.rlib new file mode 100644 index 0000000..58eb28b Binary files /dev/null and b/libs/x86_64-unknown-linux-gnu/librln.rlib differ diff --git a/libs/x86_64-unknown-linux-musl/librln.d b/libs/x86_64-unknown-linux-musl/librln.d index 5baae82..85dcdc8 100644 --- a/libs/x86_64-unknown-linux-musl/librln.d +++ b/libs/x86_64-unknown-linux-musl/librln.d @@ -1 +1 @@ -/Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/target/x86_64-unknown-linux-musl/release/librln.rlib: /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/circuit/mod.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/circuit/polynomial.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/circuit/poseidon.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/circuit/rln.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/ffi.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/lib.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/merkle.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/poseidon.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/public.rs /Users/deaneigenmann/go/src/github.com/decanus/go-rln/lib/rln/src/utils.rs +/target/x86_64-unknown-linux-musl/release/librln.rlib: /project/src/circuit/mod.rs /project/src/circuit/polynomial.rs /project/src/circuit/poseidon.rs /project/src/circuit/rln.rs /project/src/ffi.rs /project/src/hash_to_field.rs /project/src/lib.rs /project/src/merkle.rs /project/src/poseidon.rs /project/src/public.rs /project/src/utils.rs /target/x86_64-unknown-linux-musl/release/build/num-bigint-11903a3d0fc503f2/out/radix_bases.rs build.rs diff --git a/libs/x86_64-unknown-linux-musl/librln.rlib b/libs/x86_64-unknown-linux-musl/librln.rlib index fcc073e..f110e4c 100644 Binary files a/libs/x86_64-unknown-linux-musl/librln.rlib and b/libs/x86_64-unknown-linux-musl/librln.rlib differ diff --git a/rln/contracts/RLN.go b/rln/contracts/RLN.go new file mode 100644 index 0000000..03521e4 --- /dev/null +++ b/rln/contracts/RLN.go @@ -0,0 +1,1222 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// IPoseidonHasherABI is the input ABI used to generate the binding from. +const IPoseidonHasherABI = "[{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"input\",\"type\":\"uint256[2]\"}],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"identity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]" + +// IPoseidonHasherFuncSigs maps the 4-byte function signature to its string representation. +var IPoseidonHasherFuncSigs = map[string]string{ + "561558fe": "hash(uint256[2])", + "2c159a1a": "identity()", +} + +// IPoseidonHasher is an auto generated Go binding around an Ethereum contract. +type IPoseidonHasher struct { + IPoseidonHasherCaller // Read-only binding to the contract + IPoseidonHasherTransactor // Write-only binding to the contract + IPoseidonHasherFilterer // Log filterer for contract events +} + +// IPoseidonHasherCaller is an auto generated read-only Go binding around an Ethereum contract. +type IPoseidonHasherCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IPoseidonHasherTransactor is an auto generated write-only Go binding around an Ethereum contract. +type IPoseidonHasherTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IPoseidonHasherFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type IPoseidonHasherFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IPoseidonHasherSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type IPoseidonHasherSession struct { + Contract *IPoseidonHasher // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IPoseidonHasherCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type IPoseidonHasherCallerSession struct { + Contract *IPoseidonHasherCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// IPoseidonHasherTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type IPoseidonHasherTransactorSession struct { + Contract *IPoseidonHasherTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IPoseidonHasherRaw is an auto generated low-level Go binding around an Ethereum contract. +type IPoseidonHasherRaw struct { + Contract *IPoseidonHasher // Generic contract binding to access the raw methods on +} + +// IPoseidonHasherCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type IPoseidonHasherCallerRaw struct { + Contract *IPoseidonHasherCaller // Generic read-only contract binding to access the raw methods on +} + +// IPoseidonHasherTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type IPoseidonHasherTransactorRaw struct { + Contract *IPoseidonHasherTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewIPoseidonHasher creates a new instance of IPoseidonHasher, bound to a specific deployed contract. +func NewIPoseidonHasher(address common.Address, backend bind.ContractBackend) (*IPoseidonHasher, error) { + contract, err := bindIPoseidonHasher(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &IPoseidonHasher{IPoseidonHasherCaller: IPoseidonHasherCaller{contract: contract}, IPoseidonHasherTransactor: IPoseidonHasherTransactor{contract: contract}, IPoseidonHasherFilterer: IPoseidonHasherFilterer{contract: contract}}, nil +} + +// NewIPoseidonHasherCaller creates a new read-only instance of IPoseidonHasher, bound to a specific deployed contract. +func NewIPoseidonHasherCaller(address common.Address, caller bind.ContractCaller) (*IPoseidonHasherCaller, error) { + contract, err := bindIPoseidonHasher(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &IPoseidonHasherCaller{contract: contract}, nil +} + +// NewIPoseidonHasherTransactor creates a new write-only instance of IPoseidonHasher, bound to a specific deployed contract. +func NewIPoseidonHasherTransactor(address common.Address, transactor bind.ContractTransactor) (*IPoseidonHasherTransactor, error) { + contract, err := bindIPoseidonHasher(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IPoseidonHasherTransactor{contract: contract}, nil +} + +// NewIPoseidonHasherFilterer creates a new log filterer instance of IPoseidonHasher, bound to a specific deployed contract. +func NewIPoseidonHasherFilterer(address common.Address, filterer bind.ContractFilterer) (*IPoseidonHasherFilterer, error) { + contract, err := bindIPoseidonHasher(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IPoseidonHasherFilterer{contract: contract}, nil +} + +// bindIPoseidonHasher binds a generic wrapper to an already deployed contract. +func bindIPoseidonHasher(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(IPoseidonHasherABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IPoseidonHasher *IPoseidonHasherRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IPoseidonHasher.Contract.IPoseidonHasherCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IPoseidonHasher *IPoseidonHasherRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IPoseidonHasher.Contract.IPoseidonHasherTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IPoseidonHasher *IPoseidonHasherRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IPoseidonHasher.Contract.IPoseidonHasherTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IPoseidonHasher *IPoseidonHasherCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IPoseidonHasher.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IPoseidonHasher *IPoseidonHasherTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IPoseidonHasher.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IPoseidonHasher *IPoseidonHasherTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IPoseidonHasher.Contract.contract.Transact(opts, method, params...) +} + +// Hash is a free data retrieval call binding the contract method 0x561558fe. +// +// Solidity: function hash(uint256[2] input) pure returns(uint256 result) +func (_IPoseidonHasher *IPoseidonHasherCaller) Hash(opts *bind.CallOpts, input [2]*big.Int) (*big.Int, error) { + var out []interface{} + err := _IPoseidonHasher.contract.Call(opts, &out, "hash", input) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Hash is a free data retrieval call binding the contract method 0x561558fe. +// +// Solidity: function hash(uint256[2] input) pure returns(uint256 result) +func (_IPoseidonHasher *IPoseidonHasherSession) Hash(input [2]*big.Int) (*big.Int, error) { + return _IPoseidonHasher.Contract.Hash(&_IPoseidonHasher.CallOpts, input) +} + +// Hash is a free data retrieval call binding the contract method 0x561558fe. +// +// Solidity: function hash(uint256[2] input) pure returns(uint256 result) +func (_IPoseidonHasher *IPoseidonHasherCallerSession) Hash(input [2]*big.Int) (*big.Int, error) { + return _IPoseidonHasher.Contract.Hash(&_IPoseidonHasher.CallOpts, input) +} + +// Identity is a free data retrieval call binding the contract method 0x2c159a1a. +// +// Solidity: function identity() pure returns(uint256) +func (_IPoseidonHasher *IPoseidonHasherCaller) Identity(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IPoseidonHasher.contract.Call(opts, &out, "identity") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Identity is a free data retrieval call binding the contract method 0x2c159a1a. +// +// Solidity: function identity() pure returns(uint256) +func (_IPoseidonHasher *IPoseidonHasherSession) Identity() (*big.Int, error) { + return _IPoseidonHasher.Contract.Identity(&_IPoseidonHasher.CallOpts) +} + +// Identity is a free data retrieval call binding the contract method 0x2c159a1a. +// +// Solidity: function identity() pure returns(uint256) +func (_IPoseidonHasher *IPoseidonHasherCallerSession) Identity() (*big.Int, error) { + return _IPoseidonHasher.Contract.Identity(&_IPoseidonHasher.CallOpts) +} + +// PoseidonHasherABI is the input ABI used to generate the binding from. +const PoseidonHasherABI = "[{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"input\",\"type\":\"uint256[2]\"}],\"name\":\"hash\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"result\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"identity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]" + +// PoseidonHasherFuncSigs maps the 4-byte function signature to its string representation. +var PoseidonHasherFuncSigs = map[string]string{ + "561558fe": "hash(uint256[2])", + "2c159a1a": "identity()", +} + +// PoseidonHasherBin is the compiled bytecode used for deploying new contracts. +var PoseidonHasherBin = "0x608060405234801561001057600080fd5b50612142806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632c159a1a1461003b578063561558fe14610055575b600080fd5b6100436100a0565b60408051918252519081900360200190f35b6100436004803603604081101561006b57600080fd5b604080518082018252918301929181830191839060029083908390808284376000920191909152509194506100af9350505050565b60006100aa6100c0565b905090565b60006100ba826100e4565b92915050565b7f2ff267fd23782a5625e6d804f0a7fa700b8dc6084e2e7a5aff7cd4b1c506d30b90565b60007f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000016040517f165d45ae851912f9a33800b04cc6617b184bf67db11ce904dc82601244551ae281527f10fc284d0af588165f4fc650fe7c53b1d80fbaac16d30518bf142117f42f820460208201527f06b687bd3c688aa9a03545d0835bca75ae82c434bf7d5fb065a2818b5c74814f60408201527f01057eb8e4bba26f12f4ea819251708d72e0605e6de827e990c3ba4ae13f5ecd60608201527e23779a38eb9ef4a9beaf4dc0a2ab5233a28ce6d10ad2512230a275b83017c360808201527f012e5dfdd4f34081753b70c897773f5d2987c8bbae32ad202a27cd61d7fba2fb7f0d1807f022a8d80d9304a1522087b8692dc0acf7b43fea28782d2ae672c0b11f7f17d468d0e6541de501481931453ed1e4a250e5e301f27dc91fe3b4bd522aa53c7f1ea09a4bd33f14eafd75e775d85e568fa668938fdd2f16fad1d4d2d2b9862b007f061f2e832c23bee84c2f09d63d371cc5eda2f749cdbe9a6a6d20469e9fa36e8b8851017f061f2e832c23bee84c2f09d63d371cc5eda2f749cdbe9a6a6d20469e9fa36e8b60208a0151017f061f2e832c23bee84c2f09d63d371cc5eda2f749cdbe9a6a6d20469e9fa36e8b8883840989848b83840909935089838409905089838b83840909925089828309905089828b8384090991507f0e4d154ca9b7f5111958289f43ed5bbc4d4f6118d45d9aefeb778179d921a59b9050808a60408b015184098b60208c015186098c8c518809010101818b8a85098c60808d015187098d60608e01518909010101828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991508b81820992508b818d8586090990508b84850992508b848d8586090993507f298d683000ab71c72fe4371cf6cd37bb584b6d816a653ee4bfea62518a337e079250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995508b85860992508b858d8586090994508b84850992508b848d8586090993507f2f860295bc93d694e74905913ddcae47290b9b5abb43a537fe40d9305bd1e1679250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991508b81820992508b818d8586090990508b84850992508b848d8586090993507f1dd8b95942d95c7896be7f3f455e595cbfee5e1023c5d45e6573c8513f1f3dfa9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f189aa3023aeaa7267dd3c74e2c8b9cba363546619bb9c54bcb02b22fe64c51619250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f0da6b697fd05fe54a523131d91e2a7f6ac18184e237c1b20ab1936616f08e5239250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f019df963bfafa7f0e34cf092f33ce93b38b9d130fb44f276196e59f16e63ac5a9250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f295332d5ab168bc3c5eb671528c9896b7bd5034fb02472ff2af4fa1087ae658f9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f0f423b84792458876c314228be9361a604c75010411b87add91b791df2f980fa9250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f1171744890a155b5ad9cde4f1f5c4eab878f3730a9fc71f546eb737c84abec5f9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f2a557a13928c7eacff5dc049bc603cff1d7959c3975c5c9fc035b0c67173abac9250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507ec9c858d5d1ab1622d7ea2174cd9a35b07c2655dd08dcda3f5a9f7222c021af9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f0b358e01fc7cf925b6d3ba6e80c345881b54ff289479cc532f9fec01b500b9789250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f26c26f6e5a92ff96ec05a61d5f36df4f8134f8d61ff0eaa28cf7a480ee2b7f849250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f020930074e8c6c15295104a58533a601f202d3b3f959650d7b8cfa754ae41e7f9250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f10f5f06286fdde345a5cd8ba4ad94828271ea16309f5fa906841e72eb4c330279250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f116ce0fb46b45c99fec7d369ab5c0d11d374a16b2107c5d6f21e3792d33fc9699250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f2a59da7487bf7a05c3dbdfca6084e2ec589b1baf87ddd790d9bbc9c23557255b9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f1559c4b2c04c419e948f42a7f8fecfb1525dbdf2b6830632723ff4fa77030ea89250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f030b1745767217e6d8df6885a85651f9aebefcf468003d2dd25906897c3ca92a9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f2668ff336585f1e64cd6ddf2cbcaa8a695585f0db79cbd1727becfeabe76d0449250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f158c1ceb605d6cb3e0c3a7e6650b1f297c4fccb1aeed560a09dfd474c4e47f999250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f27506f4872c8b8bb7f42921afbefd206cef54f5001f1c32efbc2a22094d172d49250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f0e915e793df4e8ee01fd861b22ee463c985c691fb2a54c8657575ed93ab92c739250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f264bd2bc0486212803e5ef729bcaf466eb14f5b6ac18b898ed94844dda28d8a99250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f2f23c5d822cd0d5b27fee9ff2c51f30a40654cdd08677543244f6aad8f2ebc8a9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f2776a03893ed5c5ce680ca5acda3c7d4b60b81269cabca38bfe060ce6eb6c4129250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f07aba324bd6d746b9f23313249f6a1809f3cfea3b1f3eb70c37951eb77120d3a9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f09c0a6b8cf7f1c457987d7bb476b8ed8ddf88dbb146f2d887821d93d453d0fa39250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f292e4542f0e5b148bc7c9188b9db100f0f2aa2a62edb236041c4e4ebf44eb1469250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f01b08e9289e3a73080f49265283832fc48dfb2da2d540503b8274d7c0e52c9b69250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f0d897c5adfe393f4c0247e718eb0b227f87226cc416b703eb2a96d61581af2e39250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f057582e2ebdd031c39c69ed08086d969d22de5d1bf79ee1be837234977e3477c9250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f0be6726fc2d3d2b9681fdc9ce4e274395f9e6dc5c6e647a3a5343e3f3fe77edf9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f0e919ea6e332df81ae88f1155eac9e3c4b7dd7d8637feb112bcb2176f45fd9429250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f2dadfa8057c413974c1c03aa2d38aac0d8c09748d08edc0e97450320c889c40d9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f2954c27dbde3ba4f887becde3fc6c47db5266d436914d50d4e93faa79e40f7789250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f1e8f4f1b4fa7cc676e0d02084ce2bbf095adf6bcee924520e57c2f2a4b43f98a9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f01892c0a3e4c3ffce3763f5d67ea86157c3b2461e08ff82ee28342ad41e636259250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f297b80afd662c439ff4837049ea3d95f565007b2defd87d981bfa45ce9ce80bf9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f28def6e44cc1e6b1826dd02d19d3383ddfd0dcdf96d5e9ce0b2834c6ad5c17b89250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f0e7efce2651888246927ee306c83f4b24982ae2a126ff3be0217ea155e850d3e9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f1b61bcbf0030070f3ca673d814ad8ea269bf0b4ddf75c4b4dd8383835be6b3809250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f2bfc5e31157cdf08d36dcba28d869c209688dcb9da74df689427efbfe7ef20409250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f2535e86274b29f682edc2f95d8fc9aa4b660b1992da99d3e3ccfd551b25280ae9250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f2e26f31955ddb83a0866535943960e6bf1d75532494e07382a1886df2eba4f2c9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f1367f3092e878d4204f8597f09a6e75e596f8f859f7c4f0e4ee3bdefb14185759250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f0786e0a89d59f9f1ec5a24b4e77471afb551993358839a2ad7f0cd30ee34a5939250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f05a623c15705f67c426798eb1aeb61d16bd599b73c618801e79ce87e4acf44439250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f216a2cd9a5dec0ce0f298c37a605d63a7a241fd04f74ee76d955ec729f75c7749250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f1ac59c277950c8cf903e1e0b04c13b6be622d88a899267ccd30957e8b24feb899250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f21181ae96428a48600806eb2d2b94b4972bc69f4b69d99fb1edcbce69d1a73029250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f2a24403e8cf5fb93ed9408b11d96e377bf1f1a2e183b0e14a18d6b794fc482909250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f13324a9a9db19a8f877c22de405a88bd39bec4696dc84721e7ccfef724a8e4f59250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f17f556db73809befc58822ad53ad5785aee4ff6891f211ae7183284b57a3910a9250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f22e4f8f9c9ae56f5254ca73dc68572e805b9406a45fb4e10a831a7619b129fe59250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f066e36c90fda2dd52aa0c05909831d1dd345f75fcb17934ecb754d74e7ce8df99250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991507f190c65fb8440d50383891cbe244a8b063f0f9afbf14adce401416de7d6c755e19250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995507f0b4fec4e028a67f9a9b932ae35a1269eeec8b98b96793d29811a766ad089ab1b9250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991508b81820992508b818d8586090990508b84850992508b848d8586090993507f1def7475769de3cd372283c7d36bd153637723ff14615542bfe8b27108ad4de79250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c860901010193508b86870992508b868d8586090995508b85860992508b858d8586090994508b84850992508b848d8586090993507f119217aded5f1ebf525a69e23a08f6a976178e5939646f6c87033299d2d3c8749250828c60408d015186098d60208e015188098e8e518a090101019150828c8b86098d60808e015188098e60608f01518a090101019050828c8886098d8a88098e8c8a0901010193508b82830992508b828d8586090991508b81820992508b818d8586090990508b84850992508b848d8586090993507f036bd8311510a8d03c5b354f03c664f9f2d23f57b1e4286d1938f8dbe4a7c28c9250828c60408d015186098d60208e015184098e8e5186090101019550828c8b86098d60808e015184098e60608f015186090101019450828c8886098d8a84098e8c86090101019350505089848509905089848b83840909935089838409905089838b83840909925089828309905089828b838409505050929b9a505050505050505050505056fea264697066735822122022fc21868d907bed4fa3abb78ab3ed4f2a0fb08b5292320b05ffb1408625623f64736f6c63430007040033" + +// DeployPoseidonHasher deploys a new Ethereum contract, binding an instance of PoseidonHasher to it. +func DeployPoseidonHasher(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *PoseidonHasher, error) { + parsed, err := abi.JSON(strings.NewReader(PoseidonHasherABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(PoseidonHasherBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &PoseidonHasher{PoseidonHasherCaller: PoseidonHasherCaller{contract: contract}, PoseidonHasherTransactor: PoseidonHasherTransactor{contract: contract}, PoseidonHasherFilterer: PoseidonHasherFilterer{contract: contract}}, nil +} + +// PoseidonHasher is an auto generated Go binding around an Ethereum contract. +type PoseidonHasher struct { + PoseidonHasherCaller // Read-only binding to the contract + PoseidonHasherTransactor // Write-only binding to the contract + PoseidonHasherFilterer // Log filterer for contract events +} + +// PoseidonHasherCaller is an auto generated read-only Go binding around an Ethereum contract. +type PoseidonHasherCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PoseidonHasherTransactor is an auto generated write-only Go binding around an Ethereum contract. +type PoseidonHasherTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PoseidonHasherFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type PoseidonHasherFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// PoseidonHasherSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type PoseidonHasherSession struct { + Contract *PoseidonHasher // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PoseidonHasherCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type PoseidonHasherCallerSession struct { + Contract *PoseidonHasherCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// PoseidonHasherTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type PoseidonHasherTransactorSession struct { + Contract *PoseidonHasherTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// PoseidonHasherRaw is an auto generated low-level Go binding around an Ethereum contract. +type PoseidonHasherRaw struct { + Contract *PoseidonHasher // Generic contract binding to access the raw methods on +} + +// PoseidonHasherCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type PoseidonHasherCallerRaw struct { + Contract *PoseidonHasherCaller // Generic read-only contract binding to access the raw methods on +} + +// PoseidonHasherTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type PoseidonHasherTransactorRaw struct { + Contract *PoseidonHasherTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewPoseidonHasher creates a new instance of PoseidonHasher, bound to a specific deployed contract. +func NewPoseidonHasher(address common.Address, backend bind.ContractBackend) (*PoseidonHasher, error) { + contract, err := bindPoseidonHasher(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &PoseidonHasher{PoseidonHasherCaller: PoseidonHasherCaller{contract: contract}, PoseidonHasherTransactor: PoseidonHasherTransactor{contract: contract}, PoseidonHasherFilterer: PoseidonHasherFilterer{contract: contract}}, nil +} + +// NewPoseidonHasherCaller creates a new read-only instance of PoseidonHasher, bound to a specific deployed contract. +func NewPoseidonHasherCaller(address common.Address, caller bind.ContractCaller) (*PoseidonHasherCaller, error) { + contract, err := bindPoseidonHasher(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &PoseidonHasherCaller{contract: contract}, nil +} + +// NewPoseidonHasherTransactor creates a new write-only instance of PoseidonHasher, bound to a specific deployed contract. +func NewPoseidonHasherTransactor(address common.Address, transactor bind.ContractTransactor) (*PoseidonHasherTransactor, error) { + contract, err := bindPoseidonHasher(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &PoseidonHasherTransactor{contract: contract}, nil +} + +// NewPoseidonHasherFilterer creates a new log filterer instance of PoseidonHasher, bound to a specific deployed contract. +func NewPoseidonHasherFilterer(address common.Address, filterer bind.ContractFilterer) (*PoseidonHasherFilterer, error) { + contract, err := bindPoseidonHasher(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &PoseidonHasherFilterer{contract: contract}, nil +} + +// bindPoseidonHasher binds a generic wrapper to an already deployed contract. +func bindPoseidonHasher(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(PoseidonHasherABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PoseidonHasher *PoseidonHasherRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PoseidonHasher.Contract.PoseidonHasherCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PoseidonHasher *PoseidonHasherRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PoseidonHasher.Contract.PoseidonHasherTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PoseidonHasher *PoseidonHasherRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PoseidonHasher.Contract.PoseidonHasherTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_PoseidonHasher *PoseidonHasherCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _PoseidonHasher.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_PoseidonHasher *PoseidonHasherTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _PoseidonHasher.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_PoseidonHasher *PoseidonHasherTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _PoseidonHasher.Contract.contract.Transact(opts, method, params...) +} + +// Hash is a free data retrieval call binding the contract method 0x561558fe. +// +// Solidity: function hash(uint256[2] input) pure returns(uint256 result) +func (_PoseidonHasher *PoseidonHasherCaller) Hash(opts *bind.CallOpts, input [2]*big.Int) (*big.Int, error) { + var out []interface{} + err := _PoseidonHasher.contract.Call(opts, &out, "hash", input) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Hash is a free data retrieval call binding the contract method 0x561558fe. +// +// Solidity: function hash(uint256[2] input) pure returns(uint256 result) +func (_PoseidonHasher *PoseidonHasherSession) Hash(input [2]*big.Int) (*big.Int, error) { + return _PoseidonHasher.Contract.Hash(&_PoseidonHasher.CallOpts, input) +} + +// Hash is a free data retrieval call binding the contract method 0x561558fe. +// +// Solidity: function hash(uint256[2] input) pure returns(uint256 result) +func (_PoseidonHasher *PoseidonHasherCallerSession) Hash(input [2]*big.Int) (*big.Int, error) { + return _PoseidonHasher.Contract.Hash(&_PoseidonHasher.CallOpts, input) +} + +// Identity is a free data retrieval call binding the contract method 0x2c159a1a. +// +// Solidity: function identity() pure returns(uint256) +func (_PoseidonHasher *PoseidonHasherCaller) Identity(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _PoseidonHasher.contract.Call(opts, &out, "identity") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Identity is a free data retrieval call binding the contract method 0x2c159a1a. +// +// Solidity: function identity() pure returns(uint256) +func (_PoseidonHasher *PoseidonHasherSession) Identity() (*big.Int, error) { + return _PoseidonHasher.Contract.Identity(&_PoseidonHasher.CallOpts) +} + +// Identity is a free data retrieval call binding the contract method 0x2c159a1a. +// +// Solidity: function identity() pure returns(uint256) +func (_PoseidonHasher *PoseidonHasherCallerSession) Identity() (*big.Int, error) { + return _PoseidonHasher.Contract.Identity(&_PoseidonHasher.CallOpts) +} + +// RLNABI is the input ABI used to generate the binding from. +const RLNABI = "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"membershipDeposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"depth\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_poseidonHasher\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"pubkey\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"MemberRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"pubkey\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"MemberWithdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEPTH\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MEMBERSHIP_DEPOSIT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SET_SIZE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"members\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poseidonHasher\",\"outputs\":[{\"internalType\":\"contractIPoseidonHasher\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pubkeyIndex\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"pubkey\",\"type\":\"uint256\"}],\"name\":\"register\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"pubkeys\",\"type\":\"uint256[]\"}],\"name\":\"registerBatch\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"secret\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_pubkeyIndex\",\"type\":\"uint256\"},{\"internalType\":\"addresspayable\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"secrets\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"pubkeyIndexes\",\"type\":\"uint256[]\"},{\"internalType\":\"addresspayable[]\",\"name\":\"receivers\",\"type\":\"address[]\"}],\"name\":\"withdrawBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" + +// RLNFuncSigs maps the 4-byte function signature to its string representation. +var RLNFuncSigs = map[string]string{ + "98366e35": "DEPTH()", + "f220b9ec": "MEMBERSHIP_DEPOSIT()", + "d0383d68": "SET_SIZE()", + "5daf08ca": "members(uint256)", + "331b6ab3": "poseidonHasher()", + "61579a93": "pubkeyIndex()", + "f207564e": "register(uint256)", + "69e4863f": "registerBatch(uint256[])", + "0ad58d2f": "withdraw(uint256,uint256,address)", + "a9d85eba": "withdrawBatch(uint256[],uint256[],address[])", +} + +// RLNBin is the compiled bytecode used for deploying new contracts. +var RLNBin = "0x60e06040526000805534801561001457600080fd5b50604051610c33380380610c338339818101604052606081101561003757600080fd5b5080516020820151604090920151608082905260a08390526001831b60c0819052600280546001600160a01b0319166001600160a01b0390931692909217909155909190610b776100bc6000398061037a52806105c352806105e752806106eb52508061047f5250806103f2528061065d52806106c7528061087b5250610b776000f3fe6080604052600436106100915760003560e01c806398366e351161005957806398366e35146101c7578063a9d85eba146101dc578063d0383d68146102f7578063f207564e1461030c578063f220b9ec1461032957610091565b80630ad58d2f14610096578063331b6ab3146100d75780635daf08ca1461010857806361579a931461014457806369e4863f14610159575b600080fd5b3480156100a257600080fd5b506100d5600480360360608110156100b957600080fd5b50803590602081013590604001356001600160a01b031661033e565b005b3480156100e357600080fd5b506100ec61034e565b604080516001600160a01b039092168252519081900360200190f35b34801561011457600080fd5b506101326004803603602081101561012b57600080fd5b503561035d565b60408051918252519081900360200190f35b34801561015057600080fd5b5061013261036f565b6100d56004803603602081101561016f57600080fd5b810190602081018135600160201b81111561018957600080fd5b82018360208201111561019b57600080fd5b803590602001918460208302840111600160201b831117156101bc57600080fd5b509092509050610375565b3480156101d357600080fd5b5061013261047d565b3480156101e857600080fd5b506100d5600480360360608110156101ff57600080fd5b810190602081018135600160201b81111561021957600080fd5b82018360208201111561022b57600080fd5b803590602001918460208302840111600160201b8311171561024c57600080fd5b919390929091602081019035600160201b81111561026957600080fd5b82018360208201111561027b57600080fd5b803590602001918460208302840111600160201b8311171561029c57600080fd5b919390929091602081019035600160201b8111156102b957600080fd5b8201836020820111156102cb57600080fd5b803590602001918460208302840111600160201b831117156102ec57600080fd5b5090925090506104a1565b34801561030357600080fd5b506101326105c1565b6100d56004803603602081101561032257600080fd5b50356105e5565b34801561033557600080fd5b506101326106c5565b6103498383836106e9565b505050565b6002546001600160a01b031681565b60016020526000908152604090205481565b60005481565b6000547f000000000000000000000000000000000000000000000000000000000000000090820111156103ef576040805162461bcd60e51b815260206004820152601f60248201527f524c4e2c20726567697374657242617463683a207365742069732066756c6c00604482015290519081900360640190fd5b347f000000000000000000000000000000000000000000000000000000000000000082021461044f5760405162461bcd60e51b8152600401808060200182810382526037815260200180610a3a6037913960400191505060405180910390fd5b60005b818110156103495761047583838381811061046957fe5b905060200201356108f4565b600101610452565b7f000000000000000000000000000000000000000000000000000000000000000081565b84806104de5760405162461bcd60e51b8152600401808060200182810382526023815260200180610a176023913960400191505060405180910390fd5b80841461051c5760405162461bcd60e51b81526004018080602001828103825260368152602001806109e16036913960400191505060405180910390fd5b80821461055a5760405162461bcd60e51b8152600401808060200182810382526031815260200180610a716031913960400191505060405180910390fd5b60005b818110156105b7576105af88888381811061057457fe5b9050602002013587878481811061058757fe5b9050602002013586868581811061059a57fe5b905060200201356001600160a01b03166106e9565b60010161055d565b5050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f00000000000000000000000000000000000000000000000000000000000000006000541061065b576040805162461bcd60e51b815260206004820152601a60248201527f524c4e2c2072656769737465723a207365742069732066756c6c000000000000604482015290519081900360640190fd5b7f000000000000000000000000000000000000000000000000000000000000000034146106b95760405162461bcd60e51b8152600401808060200182810382526032815260200180610aa26032913960400191505060405180910390fd5b6106c2816108f4565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000082106107475760405162461bcd60e51b8152600401808060200182810382526024815260200180610ad46024913960400191505060405180910390fd5b6000828152600160205260409020546107915760405162461bcd60e51b8152600401808060200182810382526024815260200180610af86024913960400191505060405180910390fd5b6001600160a01b0381166107d65760405162461bcd60e51b8152600401808060200182810382526026815260200180610b1c6026913960400191505060405180910390fd5b60006107f66040518060400160405280868152602001600081525061093f565b600084815260016020526040902054909150811461085b576040805162461bcd60e51b815260206004820152601c60248201527f524c4e2c205f77697468647261773a206e6f7420766572696669656400000000604482015290519081900360640190fd5b600083815260016020526040808220829055516001600160a01b038416917f000000000000000000000000000000000000000000000000000000000000000080156108fc02929091818181858888f193505050501580156108c0573d6000803e3d6000fd5b50604051839082907f62ec3a516d22a993ce5cb4e7593e878c74f4d799dde522a88dc27a994fd5a94390600090a350505050565b6000805481526001602052604080822083905581549051909183917f5a92c2530f207992057b9c3e544108ffce3beda4a63719f316967c49bf6159d29190a350600080546001019055565b60025460408051632b0aac7f60e11b81526000926001600160a01b03169163561558fe918591600490910190819083908083838a5b8381101561098c578181015183820152602001610974565b5050505090500191505060206040518083038186803b1580156109ae57600080fd5b505afa1580156109c2573d6000803e3d6000fd5b505050506040513d60208110156109d857600080fd5b50519291505056fe524c4e2c20776974686472617742617463683a2062617463682073697a65206d69736d61746368207075626b657920696e6465786573524c4e2c20776974686472617742617463683a2062617463682073697a65207a65726f524c4e2c20726567697374657242617463683a206d656d62657273686970206465706f736974206973206e6f7420736174697366696564524c4e2c20776974686472617742617463683a2062617463682073697a65206d69736d6174636820726563656976657273524c4e2c2072656769737465723a206d656d62657273686970206465706f736974206973206e6f7420736174697366696564524c4e2c205f77697468647261773a20696e76616c6964207075626b657920696e646578524c4e2c205f77697468647261773a206d656d62657220646f65736e2774206578697374524c4e2c205f77697468647261773a20656d7074792072656365697665722061646472657373a2646970667358221220dcc34924e16df270e8b86d64190c1f7883505e74ccc71c669ce988ce89e0effc64736f6c63430007040033" + +// DeployRLN deploys a new Ethereum contract, binding an instance of RLN to it. +func DeployRLN(auth *bind.TransactOpts, backend bind.ContractBackend, membershipDeposit *big.Int, depth *big.Int, _poseidonHasher common.Address) (common.Address, *types.Transaction, *RLN, error) { + parsed, err := abi.JSON(strings.NewReader(RLNABI)) + if err != nil { + return common.Address{}, nil, nil, err + } + + address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(RLNBin), backend, membershipDeposit, depth, _poseidonHasher) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &RLN{RLNCaller: RLNCaller{contract: contract}, RLNTransactor: RLNTransactor{contract: contract}, RLNFilterer: RLNFilterer{contract: contract}}, nil +} + +// RLN is an auto generated Go binding around an Ethereum contract. +type RLN struct { + RLNCaller // Read-only binding to the contract + RLNTransactor // Write-only binding to the contract + RLNFilterer // Log filterer for contract events +} + +// RLNCaller is an auto generated read-only Go binding around an Ethereum contract. +type RLNCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RLNTransactor is an auto generated write-only Go binding around an Ethereum contract. +type RLNTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RLNFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type RLNFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// RLNSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type RLNSession struct { + Contract *RLN // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// RLNCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type RLNCallerSession struct { + Contract *RLNCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// RLNTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type RLNTransactorSession struct { + Contract *RLNTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// RLNRaw is an auto generated low-level Go binding around an Ethereum contract. +type RLNRaw struct { + Contract *RLN // Generic contract binding to access the raw methods on +} + +// RLNCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type RLNCallerRaw struct { + Contract *RLNCaller // Generic read-only contract binding to access the raw methods on +} + +// RLNTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type RLNTransactorRaw struct { + Contract *RLNTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewRLN creates a new instance of RLN, bound to a specific deployed contract. +func NewRLN(address common.Address, backend bind.ContractBackend) (*RLN, error) { + contract, err := bindRLN(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &RLN{RLNCaller: RLNCaller{contract: contract}, RLNTransactor: RLNTransactor{contract: contract}, RLNFilterer: RLNFilterer{contract: contract}}, nil +} + +// NewRLNCaller creates a new read-only instance of RLN, bound to a specific deployed contract. +func NewRLNCaller(address common.Address, caller bind.ContractCaller) (*RLNCaller, error) { + contract, err := bindRLN(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &RLNCaller{contract: contract}, nil +} + +// NewRLNTransactor creates a new write-only instance of RLN, bound to a specific deployed contract. +func NewRLNTransactor(address common.Address, transactor bind.ContractTransactor) (*RLNTransactor, error) { + contract, err := bindRLN(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &RLNTransactor{contract: contract}, nil +} + +// NewRLNFilterer creates a new log filterer instance of RLN, bound to a specific deployed contract. +func NewRLNFilterer(address common.Address, filterer bind.ContractFilterer) (*RLNFilterer, error) { + contract, err := bindRLN(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &RLNFilterer{contract: contract}, nil +} + +// bindRLN binds a generic wrapper to an already deployed contract. +func bindRLN(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(RLNABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_RLN *RLNRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RLN.Contract.RLNCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_RLN *RLNRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RLN.Contract.RLNTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_RLN *RLNRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RLN.Contract.RLNTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_RLN *RLNCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _RLN.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_RLN *RLNTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _RLN.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_RLN *RLNTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _RLN.Contract.contract.Transact(opts, method, params...) +} + +// DEPTH is a free data retrieval call binding the contract method 0x98366e35. +// +// Solidity: function DEPTH() view returns(uint256) +func (_RLN *RLNCaller) DEPTH(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _RLN.contract.Call(opts, &out, "DEPTH") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// DEPTH is a free data retrieval call binding the contract method 0x98366e35. +// +// Solidity: function DEPTH() view returns(uint256) +func (_RLN *RLNSession) DEPTH() (*big.Int, error) { + return _RLN.Contract.DEPTH(&_RLN.CallOpts) +} + +// DEPTH is a free data retrieval call binding the contract method 0x98366e35. +// +// Solidity: function DEPTH() view returns(uint256) +func (_RLN *RLNCallerSession) DEPTH() (*big.Int, error) { + return _RLN.Contract.DEPTH(&_RLN.CallOpts) +} + +// MEMBERSHIPDEPOSIT is a free data retrieval call binding the contract method 0xf220b9ec. +// +// Solidity: function MEMBERSHIP_DEPOSIT() view returns(uint256) +func (_RLN *RLNCaller) MEMBERSHIPDEPOSIT(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _RLN.contract.Call(opts, &out, "MEMBERSHIP_DEPOSIT") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MEMBERSHIPDEPOSIT is a free data retrieval call binding the contract method 0xf220b9ec. +// +// Solidity: function MEMBERSHIP_DEPOSIT() view returns(uint256) +func (_RLN *RLNSession) MEMBERSHIPDEPOSIT() (*big.Int, error) { + return _RLN.Contract.MEMBERSHIPDEPOSIT(&_RLN.CallOpts) +} + +// MEMBERSHIPDEPOSIT is a free data retrieval call binding the contract method 0xf220b9ec. +// +// Solidity: function MEMBERSHIP_DEPOSIT() view returns(uint256) +func (_RLN *RLNCallerSession) MEMBERSHIPDEPOSIT() (*big.Int, error) { + return _RLN.Contract.MEMBERSHIPDEPOSIT(&_RLN.CallOpts) +} + +// SETSIZE is a free data retrieval call binding the contract method 0xd0383d68. +// +// Solidity: function SET_SIZE() view returns(uint256) +func (_RLN *RLNCaller) SETSIZE(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _RLN.contract.Call(opts, &out, "SET_SIZE") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// SETSIZE is a free data retrieval call binding the contract method 0xd0383d68. +// +// Solidity: function SET_SIZE() view returns(uint256) +func (_RLN *RLNSession) SETSIZE() (*big.Int, error) { + return _RLN.Contract.SETSIZE(&_RLN.CallOpts) +} + +// SETSIZE is a free data retrieval call binding the contract method 0xd0383d68. +// +// Solidity: function SET_SIZE() view returns(uint256) +func (_RLN *RLNCallerSession) SETSIZE() (*big.Int, error) { + return _RLN.Contract.SETSIZE(&_RLN.CallOpts) +} + +// Members is a free data retrieval call binding the contract method 0x5daf08ca. +// +// Solidity: function members(uint256 ) view returns(uint256) +func (_RLN *RLNCaller) Members(opts *bind.CallOpts, arg0 *big.Int) (*big.Int, error) { + var out []interface{} + err := _RLN.contract.Call(opts, &out, "members", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Members is a free data retrieval call binding the contract method 0x5daf08ca. +// +// Solidity: function members(uint256 ) view returns(uint256) +func (_RLN *RLNSession) Members(arg0 *big.Int) (*big.Int, error) { + return _RLN.Contract.Members(&_RLN.CallOpts, arg0) +} + +// Members is a free data retrieval call binding the contract method 0x5daf08ca. +// +// Solidity: function members(uint256 ) view returns(uint256) +func (_RLN *RLNCallerSession) Members(arg0 *big.Int) (*big.Int, error) { + return _RLN.Contract.Members(&_RLN.CallOpts, arg0) +} + +// PoseidonHasher is a free data retrieval call binding the contract method 0x331b6ab3. +// +// Solidity: function poseidonHasher() view returns(address) +func (_RLN *RLNCaller) PoseidonHasher(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _RLN.contract.Call(opts, &out, "poseidonHasher") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PoseidonHasher is a free data retrieval call binding the contract method 0x331b6ab3. +// +// Solidity: function poseidonHasher() view returns(address) +func (_RLN *RLNSession) PoseidonHasher() (common.Address, error) { + return _RLN.Contract.PoseidonHasher(&_RLN.CallOpts) +} + +// PoseidonHasher is a free data retrieval call binding the contract method 0x331b6ab3. +// +// Solidity: function poseidonHasher() view returns(address) +func (_RLN *RLNCallerSession) PoseidonHasher() (common.Address, error) { + return _RLN.Contract.PoseidonHasher(&_RLN.CallOpts) +} + +// PubkeyIndex is a free data retrieval call binding the contract method 0x61579a93. +// +// Solidity: function pubkeyIndex() view returns(uint256) +func (_RLN *RLNCaller) PubkeyIndex(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _RLN.contract.Call(opts, &out, "pubkeyIndex") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// PubkeyIndex is a free data retrieval call binding the contract method 0x61579a93. +// +// Solidity: function pubkeyIndex() view returns(uint256) +func (_RLN *RLNSession) PubkeyIndex() (*big.Int, error) { + return _RLN.Contract.PubkeyIndex(&_RLN.CallOpts) +} + +// PubkeyIndex is a free data retrieval call binding the contract method 0x61579a93. +// +// Solidity: function pubkeyIndex() view returns(uint256) +func (_RLN *RLNCallerSession) PubkeyIndex() (*big.Int, error) { + return _RLN.Contract.PubkeyIndex(&_RLN.CallOpts) +} + +// Register is a paid mutator transaction binding the contract method 0xf207564e. +// +// Solidity: function register(uint256 pubkey) payable returns() +func (_RLN *RLNTransactor) Register(opts *bind.TransactOpts, pubkey *big.Int) (*types.Transaction, error) { + return _RLN.contract.Transact(opts, "register", pubkey) +} + +// Register is a paid mutator transaction binding the contract method 0xf207564e. +// +// Solidity: function register(uint256 pubkey) payable returns() +func (_RLN *RLNSession) Register(pubkey *big.Int) (*types.Transaction, error) { + return _RLN.Contract.Register(&_RLN.TransactOpts, pubkey) +} + +// Register is a paid mutator transaction binding the contract method 0xf207564e. +// +// Solidity: function register(uint256 pubkey) payable returns() +func (_RLN *RLNTransactorSession) Register(pubkey *big.Int) (*types.Transaction, error) { + return _RLN.Contract.Register(&_RLN.TransactOpts, pubkey) +} + +// RegisterBatch is a paid mutator transaction binding the contract method 0x69e4863f. +// +// Solidity: function registerBatch(uint256[] pubkeys) payable returns() +func (_RLN *RLNTransactor) RegisterBatch(opts *bind.TransactOpts, pubkeys []*big.Int) (*types.Transaction, error) { + return _RLN.contract.Transact(opts, "registerBatch", pubkeys) +} + +// RegisterBatch is a paid mutator transaction binding the contract method 0x69e4863f. +// +// Solidity: function registerBatch(uint256[] pubkeys) payable returns() +func (_RLN *RLNSession) RegisterBatch(pubkeys []*big.Int) (*types.Transaction, error) { + return _RLN.Contract.RegisterBatch(&_RLN.TransactOpts, pubkeys) +} + +// RegisterBatch is a paid mutator transaction binding the contract method 0x69e4863f. +// +// Solidity: function registerBatch(uint256[] pubkeys) payable returns() +func (_RLN *RLNTransactorSession) RegisterBatch(pubkeys []*big.Int) (*types.Transaction, error) { + return _RLN.Contract.RegisterBatch(&_RLN.TransactOpts, pubkeys) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x0ad58d2f. +// +// Solidity: function withdraw(uint256 secret, uint256 _pubkeyIndex, address receiver) returns() +func (_RLN *RLNTransactor) Withdraw(opts *bind.TransactOpts, secret *big.Int, _pubkeyIndex *big.Int, receiver common.Address) (*types.Transaction, error) { + return _RLN.contract.Transact(opts, "withdraw", secret, _pubkeyIndex, receiver) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x0ad58d2f. +// +// Solidity: function withdraw(uint256 secret, uint256 _pubkeyIndex, address receiver) returns() +func (_RLN *RLNSession) Withdraw(secret *big.Int, _pubkeyIndex *big.Int, receiver common.Address) (*types.Transaction, error) { + return _RLN.Contract.Withdraw(&_RLN.TransactOpts, secret, _pubkeyIndex, receiver) +} + +// Withdraw is a paid mutator transaction binding the contract method 0x0ad58d2f. +// +// Solidity: function withdraw(uint256 secret, uint256 _pubkeyIndex, address receiver) returns() +func (_RLN *RLNTransactorSession) Withdraw(secret *big.Int, _pubkeyIndex *big.Int, receiver common.Address) (*types.Transaction, error) { + return _RLN.Contract.Withdraw(&_RLN.TransactOpts, secret, _pubkeyIndex, receiver) +} + +// WithdrawBatch is a paid mutator transaction binding the contract method 0xa9d85eba. +// +// Solidity: function withdrawBatch(uint256[] secrets, uint256[] pubkeyIndexes, address[] receivers) returns() +func (_RLN *RLNTransactor) WithdrawBatch(opts *bind.TransactOpts, secrets []*big.Int, pubkeyIndexes []*big.Int, receivers []common.Address) (*types.Transaction, error) { + return _RLN.contract.Transact(opts, "withdrawBatch", secrets, pubkeyIndexes, receivers) +} + +// WithdrawBatch is a paid mutator transaction binding the contract method 0xa9d85eba. +// +// Solidity: function withdrawBatch(uint256[] secrets, uint256[] pubkeyIndexes, address[] receivers) returns() +func (_RLN *RLNSession) WithdrawBatch(secrets []*big.Int, pubkeyIndexes []*big.Int, receivers []common.Address) (*types.Transaction, error) { + return _RLN.Contract.WithdrawBatch(&_RLN.TransactOpts, secrets, pubkeyIndexes, receivers) +} + +// WithdrawBatch is a paid mutator transaction binding the contract method 0xa9d85eba. +// +// Solidity: function withdrawBatch(uint256[] secrets, uint256[] pubkeyIndexes, address[] receivers) returns() +func (_RLN *RLNTransactorSession) WithdrawBatch(secrets []*big.Int, pubkeyIndexes []*big.Int, receivers []common.Address) (*types.Transaction, error) { + return _RLN.Contract.WithdrawBatch(&_RLN.TransactOpts, secrets, pubkeyIndexes, receivers) +} + +// RLNMemberRegisteredIterator is returned from FilterMemberRegistered and is used to iterate over the raw logs and unpacked data for MemberRegistered events raised by the RLN contract. +type RLNMemberRegisteredIterator struct { + Event *RLNMemberRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *RLNMemberRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(RLNMemberRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(RLNMemberRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *RLNMemberRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *RLNMemberRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// RLNMemberRegistered represents a MemberRegistered event raised by the RLN contract. +type RLNMemberRegistered struct { + Pubkey *big.Int + Index *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMemberRegistered is a free log retrieval operation binding the contract event 0x5a92c2530f207992057b9c3e544108ffce3beda4a63719f316967c49bf6159d2. +// +// Solidity: event MemberRegistered(uint256 indexed pubkey, uint256 indexed index) +func (_RLN *RLNFilterer) FilterMemberRegistered(opts *bind.FilterOpts, pubkey []*big.Int, index []*big.Int) (*RLNMemberRegisteredIterator, error) { + + var pubkeyRule []interface{} + for _, pubkeyItem := range pubkey { + pubkeyRule = append(pubkeyRule, pubkeyItem) + } + var indexRule []interface{} + for _, indexItem := range index { + indexRule = append(indexRule, indexItem) + } + + logs, sub, err := _RLN.contract.FilterLogs(opts, "MemberRegistered", pubkeyRule, indexRule) + if err != nil { + return nil, err + } + return &RLNMemberRegisteredIterator{contract: _RLN.contract, event: "MemberRegistered", logs: logs, sub: sub}, nil +} + +// WatchMemberRegistered is a free log subscription operation binding the contract event 0x5a92c2530f207992057b9c3e544108ffce3beda4a63719f316967c49bf6159d2. +// +// Solidity: event MemberRegistered(uint256 indexed pubkey, uint256 indexed index) +func (_RLN *RLNFilterer) WatchMemberRegistered(opts *bind.WatchOpts, sink chan<- *RLNMemberRegistered, pubkey []*big.Int, index []*big.Int) (event.Subscription, error) { + + var pubkeyRule []interface{} + for _, pubkeyItem := range pubkey { + pubkeyRule = append(pubkeyRule, pubkeyItem) + } + var indexRule []interface{} + for _, indexItem := range index { + indexRule = append(indexRule, indexItem) + } + + logs, sub, err := _RLN.contract.WatchLogs(opts, "MemberRegistered", pubkeyRule, indexRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(RLNMemberRegistered) + if err := _RLN.contract.UnpackLog(event, "MemberRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseMemberRegistered is a log parse operation binding the contract event 0x5a92c2530f207992057b9c3e544108ffce3beda4a63719f316967c49bf6159d2. +// +// Solidity: event MemberRegistered(uint256 indexed pubkey, uint256 indexed index) +func (_RLN *RLNFilterer) ParseMemberRegistered(log types.Log) (*RLNMemberRegistered, error) { + event := new(RLNMemberRegistered) + if err := _RLN.contract.UnpackLog(event, "MemberRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// RLNMemberWithdrawnIterator is returned from FilterMemberWithdrawn and is used to iterate over the raw logs and unpacked data for MemberWithdrawn events raised by the RLN contract. +type RLNMemberWithdrawnIterator struct { + Event *RLNMemberWithdrawn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *RLNMemberWithdrawnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(RLNMemberWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(RLNMemberWithdrawn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *RLNMemberWithdrawnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *RLNMemberWithdrawnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// RLNMemberWithdrawn represents a MemberWithdrawn event raised by the RLN contract. +type RLNMemberWithdrawn struct { + Pubkey *big.Int + Index *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMemberWithdrawn is a free log retrieval operation binding the contract event 0x62ec3a516d22a993ce5cb4e7593e878c74f4d799dde522a88dc27a994fd5a943. +// +// Solidity: event MemberWithdrawn(uint256 indexed pubkey, uint256 indexed index) +func (_RLN *RLNFilterer) FilterMemberWithdrawn(opts *bind.FilterOpts, pubkey []*big.Int, index []*big.Int) (*RLNMemberWithdrawnIterator, error) { + + var pubkeyRule []interface{} + for _, pubkeyItem := range pubkey { + pubkeyRule = append(pubkeyRule, pubkeyItem) + } + var indexRule []interface{} + for _, indexItem := range index { + indexRule = append(indexRule, indexItem) + } + + logs, sub, err := _RLN.contract.FilterLogs(opts, "MemberWithdrawn", pubkeyRule, indexRule) + if err != nil { + return nil, err + } + return &RLNMemberWithdrawnIterator{contract: _RLN.contract, event: "MemberWithdrawn", logs: logs, sub: sub}, nil +} + +// WatchMemberWithdrawn is a free log subscription operation binding the contract event 0x62ec3a516d22a993ce5cb4e7593e878c74f4d799dde522a88dc27a994fd5a943. +// +// Solidity: event MemberWithdrawn(uint256 indexed pubkey, uint256 indexed index) +func (_RLN *RLNFilterer) WatchMemberWithdrawn(opts *bind.WatchOpts, sink chan<- *RLNMemberWithdrawn, pubkey []*big.Int, index []*big.Int) (event.Subscription, error) { + + var pubkeyRule []interface{} + for _, pubkeyItem := range pubkey { + pubkeyRule = append(pubkeyRule, pubkeyItem) + } + var indexRule []interface{} + for _, indexItem := range index { + indexRule = append(indexRule, indexItem) + } + + logs, sub, err := _RLN.contract.WatchLogs(opts, "MemberWithdrawn", pubkeyRule, indexRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(RLNMemberWithdrawn) + if err := _RLN.contract.UnpackLog(event, "MemberWithdrawn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseMemberWithdrawn is a log parse operation binding the contract event 0x62ec3a516d22a993ce5cb4e7593e878c74f4d799dde522a88dc27a994fd5a943. +// +// Solidity: event MemberWithdrawn(uint256 indexed pubkey, uint256 indexed index) +func (_RLN *RLNFilterer) ParseMemberWithdrawn(log types.Log) (*RLNMemberWithdrawn, error) { + event := new(RLNMemberWithdrawn) + if err := _RLN.contract.UnpackLog(event, "MemberWithdrawn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/rln/contracts/RLN.sol b/rln/contracts/RLN.sol new file mode 100644 index 0000000..1419d96 --- /dev/null +++ b/rln/contracts/RLN.sol @@ -0,0 +1,98 @@ +// https://github.com/kilic/rlnapp/blob/master/packages/contracts/contracts/RLN.sol + +pragma solidity 0.7.4; + +import { IPoseidonHasher } from "./crypto/PoseidonHasher.sol"; + +contract RLN { + uint256 public immutable MEMBERSHIP_DEPOSIT; + uint256 public immutable DEPTH; + uint256 public immutable SET_SIZE; + + uint256 public pubkeyIndex = 0; + mapping(uint256 => uint256) public members; + + IPoseidonHasher public poseidonHasher; + + event MemberRegistered(uint256 indexed pubkey, uint256 indexed index); + event MemberWithdrawn(uint256 indexed pubkey, uint256 indexed index); + + constructor( + uint256 membershipDeposit, + uint256 depth, + address _poseidonHasher + ) public { + MEMBERSHIP_DEPOSIT = membershipDeposit; + DEPTH = depth; + SET_SIZE = 1 << depth; + poseidonHasher = IPoseidonHasher(_poseidonHasher); + } + + function register(uint256 pubkey) external payable { + require(pubkeyIndex < SET_SIZE, "RLN, register: set is full"); + require(msg.value == MEMBERSHIP_DEPOSIT, "RLN, register: membership deposit is not satisfied"); + _register(pubkey); + } + + function registerBatch(uint256[] calldata pubkeys) external payable { + require(pubkeyIndex + pubkeys.length <= SET_SIZE, "RLN, registerBatch: set is full"); + require(msg.value == MEMBERSHIP_DEPOSIT * pubkeys.length, "RLN, registerBatch: membership deposit is not satisfied"); + for (uint256 i = 0; i < pubkeys.length; i++) { + _register(pubkeys[i]); + } + } + + function _register(uint256 pubkey) internal { + members[pubkeyIndex] = pubkey; + emit MemberRegistered(pubkey, pubkeyIndex); + pubkeyIndex += 1; + } + + function withdrawBatch( + uint256[] calldata secrets, + uint256[] calldata pubkeyIndexes, + address payable[] calldata receivers + ) external { + uint256 batchSize = secrets.length; + require(batchSize != 0, "RLN, withdrawBatch: batch size zero"); + require(batchSize == pubkeyIndexes.length, "RLN, withdrawBatch: batch size mismatch pubkey indexes"); + require(batchSize == receivers.length, "RLN, withdrawBatch: batch size mismatch receivers"); + for (uint256 i = 0; i < batchSize; i++) { + _withdraw(secrets[i], pubkeyIndexes[i], receivers[i]); + } + } + + function withdraw( + uint256 secret, + uint256 _pubkeyIndex, + address payable receiver + ) external { + _withdraw(secret, _pubkeyIndex, receiver); + } + + function _withdraw( + uint256 secret, + uint256 _pubkeyIndex, + address payable receiver + ) internal { + require(_pubkeyIndex < SET_SIZE, "RLN, _withdraw: invalid pubkey index"); + require(members[_pubkeyIndex] != 0, "RLN, _withdraw: member doesn't exist"); + require(receiver != address(0), "RLN, _withdraw: empty receiver address"); + + // derive public key + uint256 pubkey = hash([secret, 0]); + require(members[_pubkeyIndex] == pubkey, "RLN, _withdraw: not verified"); + + // delete member + members[_pubkeyIndex] = 0; + + // refund deposit + receiver.transfer(MEMBERSHIP_DEPOSIT); + + emit MemberWithdrawn(pubkey, _pubkeyIndex); + } + + function hash(uint256[2] memory input) internal view returns (uint256) { + return poseidonHasher.hash(input); + } +} \ No newline at end of file diff --git a/rln/contracts/crypto/PoseidonHasher.sol b/rln/contracts/crypto/PoseidonHasher.sol new file mode 100644 index 0000000..c00bb8b --- /dev/null +++ b/rln/contracts/crypto/PoseidonHasher.sol @@ -0,0 +1,535 @@ +// https://github.com/kilic/rlnapp/blob/master/packages/contracts/contracts/crypto/PoseidonHasher.sol + +pragma solidity 0.7.4; + +interface IPoseidonHasher { + function hash(uint256[2] memory input) external pure returns (uint256 result); + + function identity() external pure returns (uint256); +} + +contract PoseidonHasher is IPoseidonHasher { + uint256 constant Q = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + uint256 constant C0 = 2768970367241139781802170833007148522174069744848643939234067191877771423371; + uint256 constant C1 = 6468574107656347268529237497718336587709069456280471580424455063721832719771; + uint256 constant C2 = 18794671303815708509784162368644133457448839260573151733485130900959816547847; + uint256 constant C3 = 21495479230478098685877232964279351350768322664786520160088149860043275231591; + uint256 constant C4 = 13499990804456294376331975175669076043666672782766959528979369127842395667962; + uint256 constant C5 = 11128727858753328237562379127901473551876426168355298792273038389175814738273; + uint256 constant C6 = 6174623859769212836350518599861056828848352474434521101649917228563284157731; + uint256 constant C7 = 731429061815452030222739129549549044853294286077603862495031070831228988506; + uint256 constant C8 = 18691825946094184197601861261718857711439992232978967087150603050561229972879; + uint256 constant C9 = 6901715409529528992021081413007214967207374659260807285380744444309443019002; + uint256 constant C10 = 7889774703159213060685393199720756541539275646424166159037924832893670779999; + uint256 constant C11 = 19148164181730036907570646123652401621475121269795476659255226436085540432812; + uint256 constant C12 = 356519004282890736138910009474234839367086357569508205089190200287135015343; + uint256 constant C13 = 5070064330380484074844995745007722918545766490350556589468108281662282971512; + uint256 constant C14 = 17531425645708334340342421865584088711059286683026910061769879104052748058500; + uint256 constant C15 = 920858801565935944623869688790191117976818337296182581403952541435643043455; + uint256 constant C16 = 7671542183617251806500810220803333911317855932989746628699368932279406768167; + uint256 constant C17 = 7881690674485945577862776772342991782415236259307258648854817257894786877801; + uint256 constant C18 = 19155896751615806549889067080381563929649717724892491357642801041215501837659; + uint256 constant C19 = 9657176770419678097838646349393281787292209556252142440714968703151552794280; + uint256 constant C20 = 1376534476338443314506167934949939673567644510933411653555577922098640496938; + uint256 constant C21 = 17373401671868429549652772677366856294616993437583002599910365256220696563780; + uint256 constant C22 = 9746128003951157537728271629364357225604237114762257721895149249266834505625; + uint256 constant C23 = 17782316906978487011972931426261039391542241330560756508577882755911543517908; + uint256 constant C24 = 6589224737393540076643416156354549730831080306137040791236143083907274321011; + uint256 constant C25 = 17321856211701727875100310423669922181823762220382619531116210312384063527081; + uint256 constant C26 = 21321909001724533038371153813693276559530291455431564073497502239396933319818; + uint256 constant C27 = 17849794853142289789836828064662594833303692772683927435966421769162340090898; + uint256 constant C28 = 3469446763321625523201767743510820386262850368964003752018684310306935672122; + uint256 constant C29 = 4411200946062535851397814394775457104021582693964231752948256822578636459939; + uint256 constant C30 = 18626579782117576204277882219675177684589838126472487652629778677837675278662; + uint256 constant C31 = 764261930639154699767774045099363658161006905585481283735008957581415860662; + uint256 constant C32 = 6122983345977564957406231576949193286198709429730716375547595362175192593123; + uint256 constant C33 = 2469188694307740124657403582315280809174737971010077914159812443136587941756; + uint256 constant C34 = 5382605971470296415808536561267917764719132018437742878552512928718168489695; + uint256 constant C35 = 6589667679759352998039311059993721585330589021804485020627575514256149305666; + uint256 constant C36 = 20661471625156349582050865201555079410137144327315643708284763422133754381325; + uint256 constant C37 = 18694584274137621868895160209707042629719656780873050479100267791928497600376; + uint256 constant C38 = 13822590562029956399621741895244911145933359734099212387467069390727913142666; + uint256 constant C39 = 694674849457359992382704784272941309716157308424480468618786287819256378917; + uint256 constant C40 = 18763037144982179742008371677750585549220053470184500098542470704194556690623; + uint256 constant C41 = 18486457976264107916834430437402981813449917200007719339429151501964183082936; + uint256 constant C42 = 6556747954001777118869362753998468478855885460502383141235961204400638463294; + uint256 constant C43 = 12385133754714463216711399717325449316164682530612784512290690756146937377664; + uint256 constant C44 = 19895348036861519723386861870711743699604138662509897355377030959682349375552; + uint256 constant C45 = 16830822151531046474312344756361243376821272897299262546129244900502111682734; + uint256 constant C46 = 20875209030695524214960780268667166557156788659940284813793529164900666593068; + uint256 constant C47 = 8777606742656153264634386709062440729894098167014885703560793183003141571957; + uint256 constant C48 = 3404497983786933300887052921900023151252717521554164668384012034556256626067; + uint256 constant C49 = 2555107629226010512992356367848094165962022522393505508367085820070687884355; + uint256 constant C50 = 15113919336730148565553505760820732613676431799289611544548947520407297443700; + uint256 constant C51 = 12109280671570307231007703707720632582709786369013364642897329602318304275337; + uint256 constant C52 = 14968914070423010632399365015358049892440762915276845426568596163422798377730; + uint256 constant C53 = 19061189532957010364709072574663003871548558794774753349573267371990486123152; + uint256 constant C54 = 8682801373989521576522508447484143687434748406228624907362693631377691698421; + uint256 constant C55 = 10836672514863795455996193088790111107823297731722043988991810099345596059914; + uint256 constant C56 = 15783196349960742821266383686606772431598902255698169764526487081837237805029; + uint256 constant C57 = 2908608383546665417899486637528022511748691900266764564499649456344035921401; + uint256 constant C58 = 11329727236614532496067886659074662970462346457991275919233250048151273297377; + uint256 constant C59 = 5116653167814666817290578004214535117470888177090558374943095066718387153691; + uint256 constant C60 = 13540152826778549413479417002435847356268346234631393477044136590757331815911; + uint256 constant C61 = 7947441526608065582264952807420254797193034288774248212171921641395121801332; + uint256 constant C62 = 1547483282147791156522335107475157206253201614573941966672490820147450725004; + uint256 constant M0 = 10115680371401748607263639966297231210785101245789087039760048681884121897698; + uint256 constant M1 = 7682529184580308813007726368887641784100790067958820768670102409394963579396; + uint256 constant M2 = 3036380094837744536618704667164758501777151816139077990926623931426168668495; + uint256 constant M3 = 462021688665431536448264191536285854244979957674130050775621906384644169421; + uint256 constant M4 = 62665112908715427992420108025470785827183241813778563254523765114425841603; + uint256 constant M5 = 534236519266104271325123542701236478972353175554309786393016883839422407419; + uint256 constant M6 = 5922526147398848214826466482573128257954044394758836008121691281747299315999; + uint256 constant M7 = 10778490508693548114587990025762035374898560218037495485187480124708600063292; + uint256 constant M8 = 13853145901042782779715203529626320031162484246107565810821674712070680357632; + + function hash(uint256[2] memory input) external pure override returns (uint256 result) { + return _hash(input); + } + + function _hash(uint256[2] memory input) internal pure returns (uint256 result) { + assembly { + let q := Q + let pos := mload(0x40) + mstore(pos, M0) + mstore(add(pos, 32), M1) + mstore(add(pos, 64), M2) + mstore(add(pos, 96), M3) + mstore(add(pos, 128), M4) + + // mstore(add(pos, 160), M5) + // mstore(add(pos, 192), M6) + // mstore(add(pos, 224), M7) + // mstore(add(pos, 256), M8) + + // use stack intensively + let m5 := M5 + let m6 := M6 + let m7 := M7 + let m8 := M8 + + let s0 := add(mload(input), C0) + let s1 := add(mload(add(input, 32)), C0) + let s2 := C0 + + let t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := mulmod(s1, s1, q) + s1 := mulmod(mulmod(t, t, q), s1, q) + t := mulmod(s2, s2, q) + s2 := mulmod(mulmod(t, t, q), s2, q) + t := C1 + let z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + let z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := mulmod(z1, z1, q) + z1 := mulmod(mulmod(t, t, q), z1, q) + t := mulmod(s2, s2, q) + s2 := mulmod(mulmod(t, t, q), s2, q) + t := C2 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := mulmod(s1, s1, q) + s1 := mulmod(mulmod(t, t, q), s1, q) + t := mulmod(s2, s2, q) + s2 := mulmod(mulmod(t, t, q), s2, q) + t := C3 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := mulmod(z1, z1, q) + z1 := mulmod(mulmod(t, t, q), z1, q) + t := mulmod(s2, s2, q) + s2 := mulmod(mulmod(t, t, q), s2, q) + t := C4 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C5 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C6 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C7 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C8 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C9 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C10 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C11 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C12 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C13 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C14 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C15 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C16 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C17 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C18 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C19 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C20 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C21 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C22 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C23 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C24 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C25 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C26 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C27 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C28 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C29 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C30 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C31 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C32 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C33 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C34 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C35 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C36 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C37 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C38 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C39 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C40 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C41 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C42 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C43 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C44 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C45 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C46 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C47 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C48 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C49 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C50 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C51 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C52 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C53 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C54 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C55 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C56 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C57 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := C58 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := C59 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := mulmod(z1, z1, q) + z1 := mulmod(mulmod(t, t, q), z1, q) + t := mulmod(s2, s2, q) + s2 := mulmod(mulmod(t, t, q), s2, q) + t := C60 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := mulmod(s1, s1, q) + s1 := mulmod(mulmod(t, t, q), s1, q) + t := mulmod(s2, s2, q) + s2 := mulmod(mulmod(t, t, q), s2, q) + t := C61 + z0 := add(add(add(mulmod(s0, mload(pos), q), mulmod(s1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + z1 := add(add(add(mulmod(s0, mload(add(pos, 96)), q), mulmod(s1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(s0, m6, q), mulmod(s1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(z0, z0, q) + z0 := mulmod(mulmod(t, t, q), z0, q) + t := mulmod(z1, z1, q) + z1 := mulmod(mulmod(t, t, q), z1, q) + t := mulmod(s2, s2, q) + s2 := mulmod(mulmod(t, t, q), s2, q) + t := C62 + s0 := add(add(add(mulmod(z0, mload(pos), q), mulmod(z1, mload(add(pos, 32)), q)), mulmod(s2, mload(add(pos, 64)), q)), t) + s1 := add(add(add(mulmod(z0, mload(add(pos, 96)), q), mulmod(z1, mload(add(pos, 128)), q)), mulmod(s2, m5, q)), t) + s2 := add(add(add(mulmod(z0, m6, q), mulmod(z1, m7, q)), mulmod(s2, m8, q)), t) + t := mulmod(s0, s0, q) + s0 := mulmod(mulmod(t, t, q), s0, q) + t := mulmod(s1, s1, q) + s1 := mulmod(mulmod(t, t, q), s1, q) + t := mulmod(s2, s2, q) + s2 := mulmod(mulmod(t, t, q), s2, q) + + result := s0 + } + } + + function identity() external pure override returns (uint256) { + return _identity(); + } + + function _identity() internal pure returns (uint256) { + return 0x2ff267fd23782a5625e6d804f0a7fa700b8dc6084e2e7a5aff7cd4b1c506d30b; + } +} \ No newline at end of file diff --git a/rln/contracts/generate.go b/rln/contracts/generate.go new file mode 100644 index 0000000..0ae8bd4 --- /dev/null +++ b/rln/contracts/generate.go @@ -0,0 +1,3 @@ +package contracts + +//go:generate abigen -sol ./RLN.sol -pkg contracts -out ./RLN.go diff --git a/rln/librln.h b/rln/librln.h index 3d38d57..b2c117e 100644 --- a/rln/librln.h +++ b/rln/librln.h @@ -14,11 +14,6 @@ typedef struct Buffer { uintptr_t len; } Buffer; -typedef struct Auth { - const struct Buffer *secret_buffer; - uintptr_t index; -} Auth; - bool new_circuit_from_params(uintptr_t merkle_depth, const struct Buffer *parameters_buffer, struct RLN_Bn256 **ctx); @@ -31,14 +26,12 @@ bool delete_member(struct RLN_Bn256 *ctx, uintptr_t index); bool generate_proof(const struct RLN_Bn256 *ctx, const struct Buffer *input_buffer, - const struct Auth *auth, struct Buffer *output_buffer); -bool verify(const struct RLN_Bn256 *ctx, struct Buffer *proof_buffer, uint32_t *result_ptr); +bool verify(const struct RLN_Bn256 *ctx, const struct Buffer *proof_buffer, uint32_t *result_ptr); -bool hash(const struct RLN_Bn256 *ctx, - const struct Buffer *inputs_buffer, - uintptr_t input_len, - struct Buffer *output_buffer); +bool signal_to_field(const struct RLN_Bn256 *ctx, + const struct Buffer *inputs_buffer, + struct Buffer *output_buffer); -bool key_gen(const struct RLN_Bn256 *ctx, struct Buffer *keypair_buffer); +bool key_gen(const struct RLN_Bn256 *ctx, struct Buffer *input_buffer); diff --git a/rln/pb/generate.go b/rln/pb/generate.go new file mode 100644 index 0000000..b0af357 --- /dev/null +++ b/rln/pb/generate.go @@ -0,0 +1,3 @@ +package pb + +//go:generate protoc -I. --gofast_out=. ./waku_message.proto diff --git a/rln/pb/waku_message.pb.go b/rln/pb/waku_message.pb.go new file mode 100644 index 0000000..a6a357e --- /dev/null +++ b/rln/pb/waku_message.pb.go @@ -0,0 +1,969 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: waku_message.proto + +package pb + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type RateLimitProof struct { + Proof []byte `protobuf:"bytes,1,opt,name=proof,proto3" json:"proof,omitempty"` + MerkleRoot []byte `protobuf:"bytes,2,opt,name=merkle_root,json=merkleRoot,proto3" json:"merkle_root,omitempty"` + Epoch []byte `protobuf:"bytes,3,opt,name=epoch,proto3" json:"epoch,omitempty"` + ShareX []byte `protobuf:"bytes,4,opt,name=share_x,json=shareX,proto3" json:"share_x,omitempty"` + ShareY []byte `protobuf:"bytes,5,opt,name=share_y,json=shareY,proto3" json:"share_y,omitempty"` + Nullifier []byte `protobuf:"bytes,6,opt,name=nullifier,proto3" json:"nullifier,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RateLimitProof) Reset() { *m = RateLimitProof{} } +func (m *RateLimitProof) String() string { return proto.CompactTextString(m) } +func (*RateLimitProof) ProtoMessage() {} +func (*RateLimitProof) Descriptor() ([]byte, []int) { + return fileDescriptor_6f0a20862b3bf714, []int{0} +} +func (m *RateLimitProof) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RateLimitProof) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RateLimitProof.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RateLimitProof) XXX_Merge(src proto.Message) { + xxx_messageInfo_RateLimitProof.Merge(m, src) +} +func (m *RateLimitProof) XXX_Size() int { + return m.Size() +} +func (m *RateLimitProof) XXX_DiscardUnknown() { + xxx_messageInfo_RateLimitProof.DiscardUnknown(m) +} + +var xxx_messageInfo_RateLimitProof proto.InternalMessageInfo + +func (m *RateLimitProof) GetProof() []byte { + if m != nil { + return m.Proof + } + return nil +} + +func (m *RateLimitProof) GetMerkleRoot() []byte { + if m != nil { + return m.MerkleRoot + } + return nil +} + +func (m *RateLimitProof) GetEpoch() []byte { + if m != nil { + return m.Epoch + } + return nil +} + +func (m *RateLimitProof) GetShareX() []byte { + if m != nil { + return m.ShareX + } + return nil +} + +func (m *RateLimitProof) GetShareY() []byte { + if m != nil { + return m.ShareY + } + return nil +} + +func (m *RateLimitProof) GetNullifier() []byte { + if m != nil { + return m.Nullifier + } + return nil +} + +type WakuMessage struct { + Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` + ContentTopic string `protobuf:"bytes,2,opt,name=contentTopic,proto3" json:"contentTopic,omitempty"` + Version uint32 `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"` + Timestamp int64 `protobuf:"zigzag64,10,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + RateLimitProof *RateLimitProof `protobuf:"bytes,21,opt,name=rate_limit_proof,json=rateLimitProof,proto3" json:"rate_limit_proof,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WakuMessage) Reset() { *m = WakuMessage{} } +func (m *WakuMessage) String() string { return proto.CompactTextString(m) } +func (*WakuMessage) ProtoMessage() {} +func (*WakuMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_6f0a20862b3bf714, []int{1} +} +func (m *WakuMessage) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *WakuMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_WakuMessage.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *WakuMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_WakuMessage.Merge(m, src) +} +func (m *WakuMessage) XXX_Size() int { + return m.Size() +} +func (m *WakuMessage) XXX_DiscardUnknown() { + xxx_messageInfo_WakuMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_WakuMessage proto.InternalMessageInfo + +func (m *WakuMessage) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *WakuMessage) GetContentTopic() string { + if m != nil { + return m.ContentTopic + } + return "" +} + +func (m *WakuMessage) GetVersion() uint32 { + if m != nil { + return m.Version + } + return 0 +} + +func (m *WakuMessage) GetTimestamp() int64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +func (m *WakuMessage) GetRateLimitProof() *RateLimitProof { + if m != nil { + return m.RateLimitProof + } + return nil +} + +func init() { + proto.RegisterType((*RateLimitProof)(nil), "pb.RateLimitProof") + proto.RegisterType((*WakuMessage)(nil), "pb.WakuMessage") +} + +func init() { proto.RegisterFile("waku_message.proto", fileDescriptor_6f0a20862b3bf714) } + +var fileDescriptor_6f0a20862b3bf714 = []byte{ + // 299 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x91, 0xbf, 0x4e, 0xf3, 0x30, + 0x14, 0xc5, 0x3f, 0xf7, 0xa3, 0xad, 0x7a, 0x5b, 0xaa, 0xca, 0x02, 0xe1, 0x01, 0x85, 0xaa, 0x53, + 0xa7, 0x0e, 0xb0, 0x32, 0x31, 0x83, 0x84, 0x2c, 0x24, 0x60, 0x8a, 0x9c, 0x70, 0x4b, 0xad, 0xfc, + 0xb9, 0x96, 0xe3, 0x00, 0x7d, 0x13, 0x5e, 0x82, 0x87, 0x60, 0x63, 0xe4, 0x11, 0x50, 0x78, 0x11, + 0x14, 0x87, 0x2a, 0x64, 0xf3, 0xef, 0x1c, 0x1d, 0xe9, 0xf8, 0x5c, 0xe0, 0xcf, 0x2a, 0x29, 0xc3, + 0x0c, 0x8b, 0x42, 0x3d, 0xe2, 0xca, 0x58, 0x72, 0xc4, 0x7b, 0x26, 0x5a, 0xbc, 0x31, 0x98, 0x4a, + 0xe5, 0xf0, 0x52, 0x67, 0xda, 0x5d, 0x5b, 0xa2, 0x35, 0x3f, 0x80, 0xbe, 0xa9, 0x1f, 0x82, 0xcd, + 0xd9, 0x72, 0x22, 0x1b, 0xe0, 0x27, 0x30, 0xce, 0xd0, 0x26, 0x29, 0x86, 0x96, 0xc8, 0x89, 0x9e, + 0xf7, 0xa0, 0x91, 0x24, 0x91, 0xab, 0x63, 0x68, 0x28, 0xde, 0x88, 0xff, 0x4d, 0xcc, 0x03, 0x3f, + 0x82, 0x61, 0xb1, 0x51, 0x16, 0xc3, 0x17, 0xb1, 0xe7, 0xf5, 0x81, 0xc7, 0xbb, 0xd6, 0xd8, 0x8a, + 0xfe, 0x1f, 0xe3, 0x9e, 0x1f, 0xc3, 0x28, 0x2f, 0xd3, 0x54, 0xaf, 0x35, 0x5a, 0x31, 0xf0, 0x56, + 0x2b, 0x2c, 0xde, 0x19, 0x8c, 0x6f, 0x55, 0x52, 0x5e, 0x35, 0x3f, 0xe1, 0x02, 0x86, 0x46, 0x6d, + 0x53, 0x52, 0x0f, 0xbf, 0x75, 0x77, 0xc8, 0x17, 0x30, 0x89, 0x29, 0x77, 0x98, 0xbb, 0x1b, 0x32, + 0x3a, 0xf6, 0x8d, 0x47, 0xb2, 0xa3, 0xd5, 0xe9, 0x27, 0xb4, 0x85, 0xa6, 0xdc, 0xb7, 0xde, 0x97, + 0x3b, 0xac, 0x5b, 0x38, 0x9d, 0x61, 0xe1, 0x54, 0x66, 0x04, 0xcc, 0xd9, 0x92, 0xcb, 0x56, 0xe0, + 0xe7, 0x30, 0xb3, 0xca, 0x61, 0x98, 0xd6, 0xab, 0x85, 0xcd, 0x5a, 0x87, 0x73, 0xb6, 0x1c, 0x9f, + 0xf2, 0x95, 0x89, 0x56, 0xdd, 0x41, 0xe5, 0xd4, 0x76, 0xf8, 0x62, 0xf6, 0x51, 0x05, 0xec, 0xb3, + 0x0a, 0xd8, 0x57, 0x15, 0xb0, 0xd7, 0xef, 0xe0, 0x5f, 0x34, 0xf0, 0x07, 0x39, 0xfb, 0x09, 0x00, + 0x00, 0xff, 0xff, 0x4a, 0x19, 0x2a, 0x86, 0xa6, 0x01, 0x00, 0x00, +} + +func (m *RateLimitProof) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RateLimitProof) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RateLimitProof) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Nullifier) > 0 { + i -= len(m.Nullifier) + copy(dAtA[i:], m.Nullifier) + i = encodeVarintWakuMessage(dAtA, i, uint64(len(m.Nullifier))) + i-- + dAtA[i] = 0x32 + } + if len(m.ShareY) > 0 { + i -= len(m.ShareY) + copy(dAtA[i:], m.ShareY) + i = encodeVarintWakuMessage(dAtA, i, uint64(len(m.ShareY))) + i-- + dAtA[i] = 0x2a + } + if len(m.ShareX) > 0 { + i -= len(m.ShareX) + copy(dAtA[i:], m.ShareX) + i = encodeVarintWakuMessage(dAtA, i, uint64(len(m.ShareX))) + i-- + dAtA[i] = 0x22 + } + if len(m.Epoch) > 0 { + i -= len(m.Epoch) + copy(dAtA[i:], m.Epoch) + i = encodeVarintWakuMessage(dAtA, i, uint64(len(m.Epoch))) + i-- + dAtA[i] = 0x1a + } + if len(m.MerkleRoot) > 0 { + i -= len(m.MerkleRoot) + copy(dAtA[i:], m.MerkleRoot) + i = encodeVarintWakuMessage(dAtA, i, uint64(len(m.MerkleRoot))) + i-- + dAtA[i] = 0x12 + } + if len(m.Proof) > 0 { + i -= len(m.Proof) + copy(dAtA[i:], m.Proof) + i = encodeVarintWakuMessage(dAtA, i, uint64(len(m.Proof))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *WakuMessage) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *WakuMessage) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *WakuMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.RateLimitProof != nil { + { + size, err := m.RateLimitProof.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintWakuMessage(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xaa + } + if m.Timestamp != 0 { + i = encodeVarintWakuMessage(dAtA, i, uint64((uint64(m.Timestamp)<<1)^uint64((m.Timestamp>>63)))) + i-- + dAtA[i] = 0x50 + } + if m.Version != 0 { + i = encodeVarintWakuMessage(dAtA, i, uint64(m.Version)) + i-- + dAtA[i] = 0x18 + } + if len(m.ContentTopic) > 0 { + i -= len(m.ContentTopic) + copy(dAtA[i:], m.ContentTopic) + i = encodeVarintWakuMessage(dAtA, i, uint64(len(m.ContentTopic))) + i-- + dAtA[i] = 0x12 + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintWakuMessage(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintWakuMessage(dAtA []byte, offset int, v uint64) int { + offset -= sovWakuMessage(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *RateLimitProof) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Proof) + if l > 0 { + n += 1 + l + sovWakuMessage(uint64(l)) + } + l = len(m.MerkleRoot) + if l > 0 { + n += 1 + l + sovWakuMessage(uint64(l)) + } + l = len(m.Epoch) + if l > 0 { + n += 1 + l + sovWakuMessage(uint64(l)) + } + l = len(m.ShareX) + if l > 0 { + n += 1 + l + sovWakuMessage(uint64(l)) + } + l = len(m.ShareY) + if l > 0 { + n += 1 + l + sovWakuMessage(uint64(l)) + } + l = len(m.Nullifier) + if l > 0 { + n += 1 + l + sovWakuMessage(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *WakuMessage) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovWakuMessage(uint64(l)) + } + l = len(m.ContentTopic) + if l > 0 { + n += 1 + l + sovWakuMessage(uint64(l)) + } + if m.Version != 0 { + n += 1 + sovWakuMessage(uint64(m.Version)) + } + if m.Timestamp != 0 { + n += 1 + sozWakuMessage(uint64(m.Timestamp)) + } + if m.RateLimitProof != nil { + l = m.RateLimitProof.Size() + n += 2 + l + sovWakuMessage(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovWakuMessage(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozWakuMessage(x uint64) (n int) { + return sovWakuMessage(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *RateLimitProof) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RateLimitProof: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RateLimitProof: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWakuMessage + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWakuMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Proof = append(m.Proof[:0], dAtA[iNdEx:postIndex]...) + if m.Proof == nil { + m.Proof = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MerkleRoot", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWakuMessage + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWakuMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MerkleRoot = append(m.MerkleRoot[:0], dAtA[iNdEx:postIndex]...) + if m.MerkleRoot == nil { + m.MerkleRoot = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Epoch", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWakuMessage + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWakuMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Epoch = append(m.Epoch[:0], dAtA[iNdEx:postIndex]...) + if m.Epoch == nil { + m.Epoch = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ShareX", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWakuMessage + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWakuMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ShareX = append(m.ShareX[:0], dAtA[iNdEx:postIndex]...) + if m.ShareX == nil { + m.ShareX = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ShareY", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWakuMessage + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWakuMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ShareY = append(m.ShareY[:0], dAtA[iNdEx:postIndex]...) + if m.ShareY == nil { + m.ShareY = []byte{} + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Nullifier", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWakuMessage + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWakuMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Nullifier = append(m.Nullifier[:0], dAtA[iNdEx:postIndex]...) + if m.Nullifier == nil { + m.Nullifier = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipWakuMessage(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthWakuMessage + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *WakuMessage) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: WakuMessage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: WakuMessage: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthWakuMessage + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthWakuMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContentTopic", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthWakuMessage + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthWakuMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContentTopic = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + m.Version = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Version |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + v = (v >> 1) ^ uint64((int64(v&1)<<63)>>63) + m.Timestamp = int64(v) + case 21: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RateLimitProof", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthWakuMessage + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthWakuMessage + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.RateLimitProof == nil { + m.RateLimitProof = &RateLimitProof{} + } + if err := m.RateLimitProof.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipWakuMessage(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthWakuMessage + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipWakuMessage(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowWakuMessage + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthWakuMessage + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupWakuMessage + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthWakuMessage + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthWakuMessage = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowWakuMessage = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupWakuMessage = fmt.Errorf("proto: unexpected end of group") +) diff --git a/rln/pb/waku_message.proto b/rln/pb/waku_message.proto new file mode 100644 index 0000000..4cb13b7 --- /dev/null +++ b/rln/pb/waku_message.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package pb; + +message RateLimitProof { + bytes proof = 1; + bytes merkle_root = 2; + bytes epoch = 3; + bytes share_x = 4; + bytes share_y = 5; + bytes nullifier = 6; +} + +message WakuMessage { + bytes payload = 1; + string contentTopic = 2; + uint32 version = 3; + sint64 timestamp = 10; + RateLimitProof rate_limit_proof = 21; +} \ No newline at end of file diff --git a/rln/rln.go b/rln/rln.go index 3945039..e2841fa 100644 --- a/rln/rln.go +++ b/rln/rln.go @@ -5,10 +5,13 @@ package rln #include "./librln.h" */ import "C" - import ( + "encoding/binary" "errors" + "io/ioutil" "unsafe" + + "github.com/decanus/go-rln/rln/pb" ) // RLN represents the context used for rln. @@ -16,22 +19,35 @@ type RLN struct { ptr *C.RLN_Bn256 } -// KeyPair generated by the GenerateKey function for RLN values. -type KeyPair struct { - // Key represents the secret key. - Key [32]byte - - // Commitment hash of the Key generated by a hash function in the rln lib. - Commitment [32]byte +// New returns a new RLN generated using the default merkle tree depth +func NewRLN() (*RLN, error) { + return NewRLNWithDepth(MERKLE_TREE_DEPTH) } -// @TODO THINK ABOUT AUTH OBJECT - -// New returns a new RLN generated from the passed depth and parameters. -func New(depth int, parameters []byte) (*RLN, error) { +// NewRLNWithDepth generates an instance of RLN. An instance supports both zkSNARKs logics +// and Merkle tree data structure and operations. The parameter `depth`` indicates the depth of Merkle tree +func NewRLNWithDepth(depth int) (*RLN, error) { r := &RLN{} - buf := toBuffer(parameters) + // parameters.key contains the prover and verifier keys + // to generate this file, clone this repo https://github.com/kilic/rln + // and run the following command in the root directory of the cloned project + // cargo run --example export_test_keys + // the file is generated separately and copied here + // parameters are function of tree depth and poseidon hasher + // to generate parameters for a different tree depth, change the tree size in the following line of rln library + // https://github.com/kilic/rln/blob/3bbec368a4adc68cd5f9bfae80b17e1bbb4ef373/examples/export_test_keys/main.rs#L4 + // and then proceed as explained above + params, err := ioutil.ReadFile("./testdata/parameters.key") + if err != nil { + return nil, err + } + + if len(params) == 0 { + return nil, errors.New("error in parameters.key") + } + + buf := toBuffer(params) size := int(unsafe.Sizeof(buf)) in := (*C.Buffer)(C.malloc(C.size_t(size))) @@ -44,106 +60,39 @@ func New(depth int, parameters []byte) (*RLN, error) { return r, nil } -// GenerateKey generates a KeyPair for an RLN. -func (r *RLN) GenerateKey() (*KeyPair, error) { +// MembershipKeyGen generates a MembershipKeyPair that can be used for the registration into the rln membership contract +func (r *RLN) MembershipKeyGen() (*MembershipKeyPair, error) { buffer := toBuffer([]byte{}) if !bool(C.key_gen(r.ptr, &buffer)) { - return nil, errors.New("failed to genenrate key") + return nil, errors.New("error in key generation") } - key := &KeyPair{ - Key: [32]byte{}, - Commitment: [32]byte{}, + key := &MembershipKeyPair{ + IDKey: [32]byte{}, + IDCommitment: [32]byte{}, } - b := C.GoBytes(unsafe.Pointer(buffer.ptr), C.int(buffer.len)) + // the public and secret keys together are 64 bytes + generatedKeys := C.GoBytes(unsafe.Pointer(buffer.ptr), C.int(buffer.len)) + if len(generatedKeys) != 64 { + return nil, errors.New("the generated keys are invalid") + } - copy(key.Key[:], b[:32]) - copy(key.Commitment[:], b[32:64]) + copy(key.IDKey[:], generatedKeys[:32]) + copy(key.IDCommitment[:], generatedKeys[32:64]) return key, nil } -// Hash hashes a given input using the underlying function. -func (r *RLN) Hash(input []byte) ([]byte, error) { - - buf := toBuffer(input) - size := int(unsafe.Sizeof(buf)) - in := (*C.Buffer)(C.malloc(C.size_t(size))) - *in = buf - - var output []byte - out := toBuffer(output) - - if !bool(C.hash(r.ptr, in, 1, &out)) { - return nil, errors.New("failed to hash") - } - - return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil -} - -// GenerateProof generates a proof for the RLN given a KeyPair and the index in a merkle tree. -func (r *RLN) GenerateProof(input []byte, key *KeyPair, index uint) ([]byte, error) { - inputBuf := toBuffer(input) - - var output []byte - out := toBuffer(output) - - keybuf := toBuffer(key.Key[:]) - auth := &C.Auth{ - secret_buffer: &keybuf, - index: C.ulong(index), - } - - if !bool(C.generate_proof(r.ptr, &inputBuf, auth, &out)) { - return nil, errors.New("failed to generate proof") - } - - return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil -} - -// Verify verifies a proof generated for the RLN. -func (r *RLN) Verify(proof []byte) bool { - proofBuf := toBuffer(proof) - - result := uint32(0) - res := C.uint(result) - if !bool(C.verify(r.ptr, &proofBuf, &res)) { - // @TODO THINK ABOUT ERROR? - return false - } - - return uint32(res) == 0 -} - -func (r *RLN) UpdateNextMember(input []byte) error { - buf := toBuffer(input) - if !bool(C.update_next_member(r.ptr, &buf)) { - return errors.New("failed to update next member") - } - - return nil -} - -func (r *RLN) DeleteMember(index int) error { - if !bool(C.delete_member(r.ptr, C.ulong(index))) { - return errors.New("failed to delete member") - } - - return nil -} - -func (r *RLN) GetRoot() ([]byte, error) { - var output []byte - out := toBuffer(output) - - if !bool(C.get_root(r.ptr, &out)) { - return nil, errors.New("failed to get root") - } - - return C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)), nil +// appendLength returns length prefixed version of the input with the following format +// [len<8>|input], 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...) } +// toBuffer converts the input to a buffer object that is used to communicate data with the rln lib func toBuffer(data []byte) C.Buffer { dataPtr, dataLen := sliceToPtr(data) return C.Buffer{ @@ -159,3 +108,213 @@ func sliceToPtr(slice []byte) (*C.uchar, C.int) { return (*C.uchar)(unsafe.Pointer(&slice[0])), C.int(len(slice)) } } + +// Hash hashes the plain text supplied in inputs_buffer and then maps it to a field element +// this proc is used to map arbitrary signals to field element for the sake of proof generation +// inputs holds the hash input as a byte slice, the output slice will contain a 32 byte slice +func (r *RLN) Hash(data []byte) (MerkleNode, error) { + // a thin layer on top of the Nim wrapper of the Poseidon hasher + lenPrefData := appendLength(data) + + hashInputBuffer := toBuffer(lenPrefData) + size := int(unsafe.Sizeof(hashInputBuffer)) + in := (*C.Buffer)(C.malloc(C.size_t(size))) + *in = hashInputBuffer + + var output []byte + out := toBuffer(output) + + if !bool(C.signal_to_field(r.ptr, in, &out)) { + return MerkleNode{}, errors.New("failed to hash") + } + + b := C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)) + + var result MerkleNode + copy(result[:], b) + + return result, nil +} + +// GenerateProof generates a proof for the RLN given a KeyPair and the index in a merkle tree. +// The output will containt the proof data and should be parsed as |proof<256>|root<32>|epoch<32>|share_x<32>|share_y<32>|nullifier<32>| +// integers wrapped in <> indicate value sizes in bytes +func (r *RLN) GenerateProof(data []byte, key MembershipKeyPair, index MembershipIndex, epoch Epoch) (*RateLimitProof, error) { + input := serialize(key.IDKey, index, epoch, data) + inputBuf := toBuffer(input) + size := int(unsafe.Sizeof(inputBuf)) + in := (*C.Buffer)(C.malloc(C.size_t(size))) + *in = inputBuf + + var output []byte + out := toBuffer(output) + + if !bool(C.generate_proof(r.ptr, in, &out)) { + return nil, errors.New("could not generate the proof") + } + + proofBytes := C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)) + + if len(proofBytes) != 416 { + return nil, errors.New("invalid proof generated") + } + + // parse the proof as |zkSNARKs<256>|root<32>|epoch<32>|share_x<32>|share_y<32>|nullifier<32>| + + proofOffset := 256 + rootOffset := proofOffset + 32 + epochOffset := rootOffset + 32 + shareXOffset := epochOffset + 32 + shareYOffset := shareXOffset + 32 + nullifierOffset := shareYOffset + 32 + + var zkproof ZKSNARK + var proofRoot, shareX, shareY MerkleNode + var epochR Epoch + var nullifier Nullifier + + copy(zkproof[:], proofBytes[0:proofOffset]) + copy(proofRoot[:], proofBytes[proofOffset:rootOffset]) + copy(epochR[:], proofBytes[rootOffset:epochOffset]) + copy(shareX[:], proofBytes[epochOffset:shareXOffset]) + copy(shareY[:], proofBytes[shareXOffset:shareYOffset]) + copy(nullifier[:], proofBytes[shareYOffset:nullifierOffset]) + + return &RateLimitProof{ + Proof: zkproof, + MerkleRoot: proofRoot, + Epoch: epochR, + ShareX: shareX, + ShareY: shareY, + Nullifier: nullifier, + }, nil +} + +// Verify verifies a proof generated for the RLN. +// proof [ proof<256>| root<32>| epoch<32>| share_x<32>| share_y<32>| nullifier<32> | signal_len<8> | signal ] +func (r *RLN) Verify(data []byte, proof RateLimitProof) bool { + proofBytes := proof.serialize(data) + proofBuf := toBuffer(proofBytes) + size := int(unsafe.Sizeof(proofBuf)) + in := (*C.Buffer)(C.malloc(C.size_t(size))) + *in = proofBuf + + result := uint32(0) + res := C.uint(result) + if !bool(C.verify(r.ptr, in, &res)) { + return false + } + + return uint32(res) == 0 +} + +// InsertMember adds the member to the tree +func (r *RLN) InsertMember(idComm IDCommitment) bool { + buf := toBuffer(idComm[:]) + + size := int(unsafe.Sizeof(buf)) + in := (*C.Buffer)(C.malloc(C.size_t(size))) + *in = buf + + res := C.update_next_member(r.ptr, in) + return bool(res) +} + +// DeleteMember removes an IDCommitment key from the tree. The index +// parameter is the position of the id commitment key to be deleted from the tree. +// The deleted id commitment key is replaced with a zero leaf +func (r *RLN) DeleteMember(index MembershipIndex) bool { + deletionSuccess := bool(C.delete_member(r.ptr, C.ulong(index))) + return deletionSuccess +} + +// GetMerkleRoot reads the Merkle Tree root after insertion +func (r *RLN) GetMerkleRoot() (MerkleNode, error) { + var output []byte + out := toBuffer(output) + + if !bool(C.get_root(r.ptr, &out)) { + return MerkleNode{}, errors.New("could not get the root") + } + + b := C.GoBytes(unsafe.Pointer(out.ptr), C.int(out.len)) + + if len(b) != 32 { + return MerkleNode{}, errors.New("wrong output size") + } + + var result MerkleNode + copy(result[:], b) + + return result, nil +} + +// AddAll adds members to the Merkle tree +func (r *RLN) AddAll(list []IDCommitment) bool { + for _, member := range list { + if !r.InsertMember(member) { + return false + } + } + return true +} + +func ToRLNSignal(wakuMessage *pb.WakuMessage) []byte { + if wakuMessage == nil { + return []byte{} + } + + contentTopicBytes := []byte(wakuMessage.ContentTopic) + return append(wakuMessage.Payload, contentTopicBytes...) +} + +// CalcMerkleRoot returns the root of the Merkle tree that is computed from the supplied list +func CalcMerkleRoot(list []IDCommitment) (MerkleNode, error) { + rln, err := NewRLN() + if err != nil { + return MerkleNode{}, err + } + + // create a Merkle tree + for _, c := range list { + if !rln.InsertMember(c) { + return MerkleNode{}, errors.New("could not add member") + } + } + + return rln.GetMerkleRoot() +} + +// CreateMembershipList produces a list of membership key pairs and also returns the root of a Merkle tree constructed +// out of the identity commitment keys of the generated list. The output of this function is used to initialize a static +// group keys (to test waku-rln-relay in the off-chain mode) +func CreateMembershipList(n int) ([]MembershipKeyPair, MerkleNode, error) { + // initialize a Merkle tree + rln, err := NewRLN() + if err != nil { + return nil, MerkleNode{}, err + } + + var output []MembershipKeyPair + for i := 0; i < n; i++ { + // generate a keypair + keypair, err := rln.MembershipKeyGen() + if err != nil { + return nil, MerkleNode{}, err + } + + output = append(output, *keypair) + + // insert the key to the Merkle tree + if !rln.InsertMember(keypair.IDCommitment) { + return nil, MerkleNode{}, errors.New("could not insert member") + } + } + + root, err := rln.GetMerkleRoot() + if err != nil { + return nil, MerkleNode{}, err + } + + return output, root, nil +} diff --git a/rln/rln_linux64.go b/rln/rln_linux64.go index 4b1afcd..233e510 100644 --- a/rln/rln_linux64.go +++ b/rln/rln_linux64.go @@ -1,3 +1,4 @@ +//go:build !android && linux && amd64 && !musl // +build !android,linux,amd64,!musl package rln diff --git a/rln/rln_test.go b/rln/rln_test.go index 140fdc8..bc70e84 100644 --- a/rln/rln_test.go +++ b/rln/rln_test.go @@ -1,113 +1,255 @@ -package rln_test +package rln import ( + "bytes" "encoding/hex" - "io/ioutil" - "reflect" + "math" "testing" - "github.com/decanus/go-rln/rln" + "github.com/stretchr/testify/suite" ) -func TestNew(t *testing.T) { - params, err := ioutil.ReadFile("./testdata/parameters.key") - if err != nil { - t.Fatal(err) - } - - _, err = rln.New(32, params) - if err != nil { - t.Fatal(err) - } +func TestWakuRLNRelaySuite(t *testing.T) { + suite.Run(t, new(WakuRLNRelaySuite)) } -func TestGenerateKey(t *testing.T) { - params, err := ioutil.ReadFile("./testdata/parameters.key") - if err != nil { - t.Fatal(err) - } - - r, err := rln.New(32, params) - if err != nil { - t.Fatal(err) - } - - k, err := r.GenerateKey() - if err != nil { - t.Fatal(err) - } - - if reflect.DeepEqual(k.Key, [32]byte{}) { - t.Fatal("k.Key was empty") - } - - if reflect.DeepEqual(k.Commitment, [32]byte{}) { - t.Fatal("k.Commitment was empty") - } +type WakuRLNRelaySuite struct { + suite.Suite } -func TestRLN_Hash(t *testing.T) { - // This test is based on tests from: - // https://github.com/status-im/nim-waku/blob/b7998de09d1ef04599a699938da69aecfa63cc6f/tests/v2/test_waku_rln_relay.nim#L527 +func (s *WakuRLNRelaySuite) TestMembershipKeyGen() { + rln, err := NewRLNWithDepth(32) + s.NoError(err) - params, err := ioutil.ReadFile("./testdata/parameters.key") - if err != nil { - t.Fatal(err) - } - - r, err := rln.New(32, params) - if err != nil { - t.Fatal(err) - } - - input := byteArray(32, 1) - - output, err := r.Hash(input) - if err != nil { - t.Fatal(err) - } - - expected := "53a6338cdbf02f0563cec1898e354d0d272c8f98b606c538945c6f41ef101828" - if expected != hex.EncodeToString(output) { - t.Fatalf("value %x did not match expected %s", output, expected) - } + key, err := rln.MembershipKeyGen() + s.NoError(err) + s.Len(key.IDKey, 32) + s.Len(key.IDCommitment, 32) + s.NotEmpty(key.IDKey) + s.NotEmpty(key.IDCommitment) + s.False(bytes.Equal(key.IDCommitment[:], make([]byte, 32))) + s.False(bytes.Equal(key.IDKey[:], make([]byte, 32))) } -func TestRLN_GetRoot(t *testing.T) { - // This test is based on tests from: - // https://github.com/status-im/nim-waku/blob/b7998de09d1ef04599a699938da69aecfa63cc6f/tests/v2/test_waku_rln_relay.nim#L320 +func (s *WakuRLNRelaySuite) TestGetMerkleRoot() { + rln, err := NewRLNWithDepth(32) + s.NoError(err) - params, err := ioutil.ReadFile("./testdata/parameters.key") - if err != nil { - t.Fatal(err) - } + root1, err := rln.GetMerkleRoot() + s.NoError(err) + s.Len(root1, 32) - r, err := rln.New(32, params) - if err != nil { - t.Fatal(err) - } + root2, err := rln.GetMerkleRoot() + s.NoError(err) + s.Len(root2, 32) - root1, err := r.GetRoot() - if err != nil { - t.Fatal(err) - } - - root2, err := r.GetRoot() - if err != nil { - t.Fatal(err) - } - - if hex.EncodeToString(root1) != hex.EncodeToString(root2) { - t.Fatalf("value %x did not match expected %x", root1, root2) - } + s.Equal(root1, root2) } -func byteArray(length int, value byte) []byte { - arr := make([]byte, length) +func (s *WakuRLNRelaySuite) TestInsertMember() { + rln, err := NewRLNWithDepth(32) + s.NoError(err) - for i := 0; i < length; i++ { - arr[i] = value + keypair, err := rln.MembershipKeyGen() + s.NoError(err) + + inserted := rln.InsertMember(keypair.IDCommitment) + s.True(inserted) +} + +func (s *WakuRLNRelaySuite) TestRemoveMember() { + rln, err := NewRLNWithDepth(32) + s.NoError(err) + + deleted := rln.DeleteMember(MembershipIndex(0)) + s.True(deleted) +} + +func (s *WakuRLNRelaySuite) TestMerkleTreeConsistenceBetweenDeletionAndInsertion() { + rln, err := NewRLNWithDepth(32) + s.NoError(err) + + root1, err := rln.GetMerkleRoot() + s.NoError(err) + s.Len(root1, 32) + + keypair, err := rln.MembershipKeyGen() + s.NoError(err) + + inserted := rln.InsertMember(keypair.IDCommitment) + s.True(inserted) + + // read the Merkle Tree root after insertion + root2, err := rln.GetMerkleRoot() + s.NoError(err) + s.Len(root2, 32) + + // delete the first member + deleted_member_index := MembershipIndex(0) + deleted := rln.DeleteMember(deleted_member_index) + s.True(deleted) + + // read the Merkle Tree root after the deletion + root3, err := rln.GetMerkleRoot() + s.NoError(err) + s.Len(root3, 32) + + // the root must change after the insertion + s.NotEqual(root1, root2) + + // The initial root of the tree (empty tree) must be identical to + // the root of the tree after one insertion followed by a deletion + s.Equal(root1, root3) +} + +func (s *WakuRLNRelaySuite) TestHash() { + rln, err := NewRLNWithDepth(32) + s.NoError(err) + + // prepare the input + msg := []byte("Hello") + + hash, err := rln.Hash(msg) + s.NoError(err) + + expectedHash, _ := hex.DecodeString("efb8ac39dc22eaf377fe85b405b99ba78dbc2f3f32494add4501741df946bd1d") + s.Equal(expectedHash, hash[:]) +} + +func (s *WakuRLNRelaySuite) TestCreateListMembershipKeysAndCreateMerkleTreeFromList() { + groupSize := 100 + list, root, err := CreateMembershipList(groupSize) + s.NoError(err) + s.Len(list, groupSize) + s.Len(root, HASH_HEX_SIZE) // check the size of the calculated tree root +} + +func (s *WakuRLNRelaySuite) TestCheckCorrectness() { + groupKeys := STATIC_GROUP_KEYS + + // create a set of MembershipKeyPair objects from groupKeys + groupKeyPairs, err := toMembershipKeyPairs(groupKeys) + s.NoError(err) + + // extract the id commitments + var groupIDCommitments []IDCommitment + for _, c := range groupKeyPairs { + groupIDCommitments = append(groupIDCommitments, c.IDCommitment) } - return arr + // calculate the Merkle tree root out of the extracted id commitments + root, err := CalcMerkleRoot(groupIDCommitments) + s.NoError(err) + + expectedRoot, _ := hex.DecodeString(STATIC_GROUP_MERKLE_ROOT) + + s.Len(groupKeyPairs, STATIC_GROUP_SIZE) + s.Equal(expectedRoot, root[:]) +} + +func (s *WakuRLNRelaySuite) TestValidProof() { + rln, err := NewRLN() + s.NoError(err) + + 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++ { + memberIsAdded := false + if i == index { + // insert the current peer's pk + memberIsAdded = rln.InsertMember(memKeys.IDCommitment) + } else { + // create a new key pair + memberKeys, err := rln.MembershipKeyGen() + s.NoError(err) + + memberIsAdded = rln.InsertMember(memberKeys.IDCommitment) + } + s.True(memberIsAdded) + } + + // prepare the message + msg := []byte("Hello") + + // prepare the epoch + var epoch Epoch + + // generate proof + proofRes, err := rln.GenerateProof(msg, *memKeys, MembershipIndex(index), epoch) + s.NoError(err) + + // verify the proof + verified := rln.Verify(msg, *proofRes) + + s.True(verified) +} + +func (s *WakuRLNRelaySuite) TestInvalidProof() { + rln, err := NewRLN() + s.NoError(err) + + 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++ { + memberIsAdded := false + if i == index { + // insert the current peer's pk + memberIsAdded = rln.InsertMember(memKeys.IDCommitment) + } else { + // create a new key pair + memberKeys, err := rln.MembershipKeyGen() + s.NoError(err) + + memberIsAdded = rln.InsertMember(memberKeys.IDCommitment) + } + s.True(memberIsAdded) + } + + // prepare the message + msg := []byte("Hello") + + // prepare the epoch + var epoch Epoch + + badIndex := 4 + + // generate proof + proofRes, err := rln.GenerateProof(msg, *memKeys, MembershipIndex(badIndex), epoch) + s.NoError(err) + + // verify the proof (should not be verified) + verified := rln.Verify(msg, *proofRes) + + s.False(verified) +} + +func (s *WakuRLNRelaySuite) TestEpochConsistency() { + // check edge cases + var epoch uint64 = math.MaxUint64 + epochBytes := ToEpoch(epoch) + decodedEpoch := epochBytes.Uint64() + + s.Equal(epoch, decodedEpoch) +} + +func (s *WakuRLNRelaySuite) TestEpochComparison() { + // check edge cases + var time1 uint64 = math.MaxUint64 + var time2 uint64 = math.MaxUint64 - 1 + + epoch1 := ToEpoch(time1) + epoch2 := ToEpoch(time2) + + s.Equal(int64(1), Diff(epoch1, epoch2)) + s.Equal(int64(-1), Diff(epoch2, epoch1)) } diff --git a/rln/serialize.go b/rln/serialize.go new file mode 100644 index 0000000..94000d5 --- /dev/null +++ b/rln/serialize.go @@ -0,0 +1,38 @@ +package rln + +import "encoding/binary" + +// serialize converts a RateLimitProof and the data to a byte seq +// this conversion is used in the proofGen function +// the serialization is done as instructed in https://github.com/kilic/rln/blob/7ac74183f8b69b399e3bc96c1ae8ab61c026dc43/src/public.rs#L146 +// [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal ] +func serialize(idKey IDKey, memIndex MembershipIndex, epoch Epoch, msg []byte) []byte { + + memIndexBytes := make([]byte, 8) + binary.LittleEndian.PutUint64(memIndexBytes, uint64(memIndex)) + + lenPrefMsg := appendLength(msg) + + output := append(idKey[:], memIndexBytes...) + output = append(output, epoch[:]...) + output = append(output, lenPrefMsg...) + + return output +} + +// serialize converts a RateLimitProof and data to a byte seq +// this conversion is used in the proof verification proc +// the order of serialization is based on https://github.com/kilic/rln/blob/7ac74183f8b69b399e3bc96c1ae8ab61c026dc43/src/public.rs#L205 +// [ proof<256>| root<32>| epoch<32>| share_x<32>| share_y<32>| nullifier<32> | signal_len<8> | signal ] +func (r RateLimitProof) serialize(data []byte) []byte { + + lenPrefMsg := appendLength(data) + proofBytes := append(r.Proof[:], r.MerkleRoot[:]...) + proofBytes = append(proofBytes, r.Epoch[:]...) + proofBytes = append(proofBytes, r.ShareX[:]...) + proofBytes = append(proofBytes, r.ShareY[:]...) + proofBytes = append(proofBytes, r.Nullifier[:]...) + proofBytes = append(proofBytes, lenPrefMsg...) + + return proofBytes +} diff --git a/rln/testdata/parameters.key b/rln/testdata/parameters.key index 8691479..9829416 100644 Binary files a/rln/testdata/parameters.key and b/rln/testdata/parameters.key differ diff --git a/rln/types.go b/rln/types.go new file mode 100644 index 0000000..86e9b4b --- /dev/null +++ b/rln/types.go @@ -0,0 +1,279 @@ +package rln + +import ( + "bytes" + "encoding/binary" + "time" + + "github.com/decanus/go-rln/rln/pb" +) + +// IDKey is an identity key as defined in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership +type IDKey [32]byte + +// IDCommintment is hash of identity key as defined in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership +type IDCommitment [32]byte + +// Each node of the Merkle tee is a Poseidon hash which is a 32 byte value +type MerkleNode [32]byte + +type Nullifier [32]byte + +type ZKSNARK [256]byte + +// Custom data types defined for waku rln relay ------------------------- + +type MembershipKeyPair struct { + // user's identity key (a secret key) which is selected randomly + // see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership + IDKey IDKey + // hash of user's identity key generated by + // Poseidon hash function implemented in rln lib + // more details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership + IDCommitment IDCommitment +} + +type RateLimitProof struct { + // RateLimitProof holds the public inputs to rln circuit as + // defined in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Public-Inputs + // the `proof` field carries the actual zkSNARK proof + Proof ZKSNARK + // the root of Merkle tree used for the generation of the `proof` + MerkleRoot MerkleNode + // the epoch used for the generation of the `proof` + Epoch Epoch + // shareX and shareY are shares of user's identity key + // these shares are created using Shamir secret sharing scheme + // see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Linear-Equation-amp-SSS + ShareX MerkleNode + ShareY MerkleNode + // nullifier enables linking two messages published during the same epoch + // see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Nullifiers + Nullifier Nullifier +} + +func ToRateLimitProof(msg *pb.WakuMessage) *RateLimitProof { + if msg == nil { + return nil + } + + result := &RateLimitProof{ + Proof: ZKSNARK(Bytes256(msg.RateLimitProof.Proof)), + MerkleRoot: MerkleNode(Bytes32(msg.RateLimitProof.MerkleRoot)), + Epoch: Epoch(Bytes32(msg.RateLimitProof.Epoch)), + ShareX: MerkleNode(Bytes32(msg.RateLimitProof.ShareX)), + ShareY: MerkleNode(Bytes32(msg.RateLimitProof.ShareY)), + Nullifier: Nullifier(Bytes32(msg.RateLimitProof.Nullifier)), + } + + return result +} + +type MembershipIndex uint + +type ProofMetadata struct { + Nullifier Nullifier + ShareX MerkleNode + ShareY MerkleNode +} + +func (p ProofMetadata) Equals(p2 ProofMetadata) bool { + return bytes.Equal(p.Nullifier[:], p2.Nullifier[:]) && bytes.Equal(p.ShareX[:], p2.ShareX[:]) && bytes.Equal(p.ShareY[:], p2.ShareY[:]) +} + +type MessageValidationResult int + +const ( + MessageValidationResult_Unknown MessageValidationResult = iota + MessageValidationResult_Valid + MessageValidationResult_Invalid + MessageValidationResult_Spam +) + +/* +# inputs of the membership contract constructor +# TODO may be able to make these constants private and put them inside the waku_rln_relay_utils +const + MEMBERSHIP_FEE* = 5.u256 +*/ + +// the current implementation of the rln lib only supports a circuit for Merkle tree with depth 32 +const MERKLE_TREE_DEPTH int = 20 + +// TODO the ETH_CLIENT should be an input to the rln-relay, though hardcoded for now +// the current address is the address of ganache-cli when run locally +const ETH_CLIENT = "ws://localhost:8540/" + +// HASH_BIT_SIZE is the size of poseidon hash output in bits +const HASH_BIT_SIZE = 256 + +// HASH_HEX_SIZE is the size of poseidon hash output as the number of bytes +const HASH_HEX_SIZE = int(HASH_BIT_SIZE / 8) + +// temporary variables to test waku-rln-relay performance in the static group mode + +const STATIC_GROUP_SIZE = 100 + +// STATIC_GROUP_KEYS is a static list of 100 membership keys in the form of (identity key, identity commitment) +// keys are created locally, using createMembershipList proc from waku_rln_relay_utils module, and the results are hardcoded in here +// this list is temporary and is created to test the performance of waku-rln-relay for the static groups +// in the later versions, this static hardcoded group will be replaced with a dynamic one +var STATIC_GROUP_KEYS [][]string + +func init() { + STATIC_GROUP_KEYS = [][]string{ + {"e9a4d05b1f539d65c59015a079ee89aabeafbcfc9734342d9559f81601e85417", "b74d3a5b3200ab1126fbee393496f33da497d4d9a7c56693f44d6155c0c34e13"}, + {"27b2bfc25257e53819beaf36ce1070007e04e7aad2e440a1f1fc066f59a61123", "522ce51aff96041e79a8476f508fb9661f146f189e288f83cb4837517cfc0127"}, + {"66392eaae6674267c55fe393d39443ba90317a709d6e8f92a9f3e4abc18eff1d", "e3dc235e48c1811943fc249fecd0f1415a50ebe839ccefb0bd820a76fb77ba2a"}, + {"e7462eebb81405230db8014b052d65fe7b269c3870e40b12cf64668ed6c2d40e", "727df0965e34144ea637be18208cc81e57e423010b3159c20f0ccff45c42212a"}, + {"1ad8528b4c7075013a2d6561a02517b0482c0733dc018ac68774db857deb5004", "5df3a77577135784da2a9ee78f5026092b7d6bb9e6e95882d6cb172c0cb62208"}, + {"aa0ff53bfc50861f871d94df18c3ac0b97f44ceb13436b33490cec5f6ce8e700", "30421d05b905aeaec0473ba29ace034bf73c406866d7dc23007eb9c34a596827"}, + {"0448c0a6ed57b177c4c45de478b58d29f24e7ea842814305443e87188ae24324", "5ea1a704d8972af5a028367c8e3fb48ee61a603c6ea3a4c9247b0f611a6ab002"}, + {"4b6a6edbdd11e69befe3f4a3c976baca320c4bcb188f129b603ebb198f663000", "451d6185e8ad2c8873f034683b9caca43ea7ceb1b839abd3e01c3f19f3e6bd1e"}, + {"c3fba34855b33f025696326d2980ddc3fb47d90459ed6a4488fbb2e4e12ccf2b", "74674a86144ea866ad8fe633e256783bda4a07b997cb412c53a5eaf4cc7b6a0e"}, + {"0c35b8b94a720f1c26d7c6241c9f3ea5332a87cf3730b25ef31b68854c10e405", "6915df8d8ad19ec17be37c299eed762f9b63e841cd7963e13e8db6890dba082d"}, + {"a60b021677da95ba46c8c3411ac77f3e3b06937a8d189517111c045880029909", "bbfcd22ecb44cec6fd0717cd0f21b26e6e8b2c91e1a6cb5d8610e2f2ad41c90f"}, + {"2f4d662e66fbe754b708b87ea3d75a01d2ea4d7bf33c615c2376211dcc3b560f", "c67f7e622c3293028b9f86571e82c49551eb5fd308a35eb663498cffac208810"}, + {"d90a1afa96c14c8d3b989a9cf23d6e8b9907da42724e44a3ac74ae015b6ce22e", "f0795b1bdd0a907252b6ab047642d97be076a16ea69d463f1a4bec00c817202e"}, + {"dfa0764d89c8da10777504e5274f1baccf8b4145deba72b26503474318fb6410", "9f8aa8e833ea2f13cccfb6d9f2f04fd7be9c9f3019540c05c1986b3bce254e25"}, + {"e17490013b6b53a40964ff1067b922d4d73521e32fe394527b39c1bfd4a5e712", "7a8fa23a0e4b14a36f2818a7d98639f6e4934c028da780a6cc658fbf76e80a26"}, + {"7a9328d1075373dddb1b1100e8217ffaa1f9b632911b95a8fdc08870b15a8410", "94b2ae70c046b94873098c19fe18e7b17db2d31fe6a7eb73fea8168395e3c122"}, + {"ce319bb1447da5bf51a88ab3379dbea539b5a431d3c4f131048cf7b05c52161d", "cdfa264ab8a51bbc9fff5732cf544bb06abba7e807a8c252a5f9ce785c6ff22c"}, + {"d3818503bfcbef9ca03fc4472be77cb4936a1720001fc5e54852f769448fd313", "e72792abd906976c75a5670de514894a720c5293cf74338a9c2987640a949c0b"}, + {"4f9b8d118460736eb62602d12d3aed62938d4d4374b8c88704cf40c415c0901e", "2ecbe4588ade31924a1053fe0204950a0b4924878b312e56b2d0522f92a5f01c"}, + {"39b59fd96adaf9633edcc8cef10049cddf5f7df8ac80af8aafa436d62ee7f905", "b94f7a979df8a95fc2766a9a96308ff39a14daf7b7d6bc48591d2ea4c764bf00"}, + {"73cb0d25995d182b361c8237852bafeab8bb951de99f730da2913a239400c322", "da04e6e4446b6bcd54667b741444d826abbc5b76572d28474dfa94db91144606"}, + {"2753423b83bba5bb8b2799bc58125c46fb03ec05e8579d772cdc6e75b0875009", "ee040010ec20e7293431a3692d06416f71162d176a316b0329a76edf6f3fb30d"}, + {"cb73ec9b67355ce6275b51144a0759de28bb9390aab20514ee49a3bd8ce5361b", "c7c6e2ad3efe1f03b398241bddb67b008dd5e8caf1a17db9c33d2e2388d58e0d"}, + {"bdb386d9f3fe5613ede926d80246682a5d32392f7f6c9d818a80d8e7a12e371b", "21d48c74f422ef72cb9db18799916b3c11d0cb99cec808563e2db22047840902"}, + {"60f2fcfe341034449046c1fa330f6aceff737a9837a7d6d3a4885f8afce4a809", "e4c8f26f9e4127511b5ab21f1705913d7beaa2767cb7d033564e36bd2693370c"}, + {"1223d64fb5c44921c1ae66d91543780634c2f7bae7e184e09c4e5447e6d1180b", "290ab84714fc3534c5ba22b2aa7696ac03ed12c9cf1c409a777bac05475ea406"}, + {"b79c593316c42280d316bb7f3b43c7a5f5e29786d1ca6c0424463470eefe2b2f", "f4e44ac9574c4d32ab403e71dd00554eee0d8e34d04611b66ab2e59c49bff025"}, + {"e6548f669ebe655cb6600432e1af14c43da7286e3620289b51cc947517db9c14", "ace261e3964a1dcb389a693f52104018cd475e6856ae37fe4892df9482954902"}, + {"81be54409c9364f4842209e0f79b190afd9df017cc9790e11196d4bf5108f100", "d986b22e422703e065f12b6fd608813028ff913d4ffeb54b19e6537456391b23"}, + {"940ff0d3b4549d1baf7ad900cf6aedde02833b777e39c411e6efe7bcdd2ef305", "d672bb8a6e75b47fdbb365de0516f3fa827b287c9666e64d1b6768e2c8949412"}, + {"b4fe300aa1c8c836b3cc4c167df86d08fb7213200b8d9f7ba7963170e6dc8c0a", "5f7db6a9867f3f5c9fd1955c02cf96056d1225be950cd432818f8f1c16152020"}, + {"2c34a2bdb3738cb78270207dcae40ae47178bf4216bd2044ba124ec49240522a", "8c490c78d7d735ab32493510cc2ec9c3742d3f47e46cfd754859e91271673e15"}, + {"fc03857a3ff92d17d40bf9bb9b99e01e85fe4c698450147dc74cde60b2e9fa2d", "c0a22acdababbc42bba5bc0245a2ef9f2c74b215663440aed37c8e0bd7e00809"}, + {"a267a96a35c63b03788e90bb9a440da9ac832b0be02537b6f0ecc928ea989223", "636ceacda5bce999ca303b7df32e9352af10083c6db6ed93c8a221efc385172d"}, + {"ce4e15a2c1667a9dac4c4732de6c91f8c523c449f8c9be6b895644460717a209", "d55c6523f40b36d2519b30292873bd469aeda6dbdbafe7c5fd405438dcc6bd12"}, + {"4c617cdea4e3cb008c396c59b701375409304d84cfa17fe9d6d91a15fa412306", "a6dc21a9c35418a39c69f2d8e9df738db0b36fecc44eddf364846b84c5362819"}, + {"8c33aa2b3d94f9b11cc62ed1a304b92be370384ebbbf67c886dcd6ce544cc806", "7caca2b1ab8c70b58ba36794a988fd6ec50c2a04dd09d7cd28e67ca1f1401d2c"}, + {"1b6fc8f4007e6cdcf89a496cf0e711b0a3bbdbbae66830450a9744f5c802a228", "c3b79478bd32feb99a0c92001efb97953efdad8c2338ed2ac14a313592c12418"}, + {"0c6837e83ee0f1b1e5fe31bdf0960aefa2162ef7de7c0c886df930839bd4db06", "8b2667b5151ab13f0f87fb014cd3ebb7ab1e92a528f00ebd91b514ea61b8f52b"}, + {"8da38060963597c34544d8b10432a2e34d8eada7d1479f4fa5e96dca32250c27", "7bf525115a8e6f772feb6d4db0f2a6b0d4233e0ff85e180c3249e18f0d08f42e"}, + {"50b0c6d85f6a9d11fc52f1fc9e43b778380bdf936ddfd293940c77e79bc8340d", "bbb9e297de81ef341e032484d7b33b29e7d9e3be1414feaf2bbc0957ba408811"}, + {"6e8fd3ad20cf32ff8ba6e4bd8d4f05f3cc20d88631cbd3aa5f7f98446d725108", "a9fe7404613b040412049a205301f2175b53d7012087047a8dc7501a381f5210"}, + {"c291bb32d69cfef7e80b6dadd2a1198d05ac23eb30be6503d1c4c04350de2028", "f44f8ca09d849551f72a6692c793319eefaa0c02d3301ae79c2f869f4251d422"}, + {"116d4c2e21101f819a87f0de31dec56a4649c9ad9e539b71680dd439b288681d", "9f4df65e05390be63bd6e3e38d8afb6117d5d357d56f35ecf63406096fdd810c"}, + {"1813ed3760299a16e623084a852de9b12caaf8138744f8903a357fa9a2dbb00c", "f37baacccd07bc489f50b851f807c88a425e41dd9dda8068e75cffb8bf653a0f"}, + {"545e62d72cbb89db1c17e7ad8bb0660a74f8bc411b16eb0452d9a2d7c3e5b01e", "96ddc93a86b091c7b1951d7371f80a352d85c38606e450aa2af272e8929fae19"}, + {"0f5d5941474697c21ea6aecc29ff7cadbd28dbf29531431a40aaea3b7acd1514", "e83d0ff3ab4db81fb19c1b6125d7d2e4a34a83a8d463049d06df4870dbb2a525"}, + {"52605bc1f48092f9d5ad4c2a840a60f129e6aef2eef9c92474951ed1e10e381c", "222df3afb8b20685c872f29ebfc7e4056fcdafe1d8a77a9f9ba08ac8f426190c"}, + {"eee8cdee57e9f11ad0174c1514bba4c3a2c2a10d099876195726217445462f0b", "a000e5799ac933154bae228c09b522c714fb9a57f530d1954947277be9db0a24"}, + {"8c7d04dc3916370f8186dcffc92ad482294ab49c9ce36a5bd13473dc7c4d491a", "788e35bcd82efbce15b3444f36330337ce3adb67bfc6329149cd25069ac9eb19"}, + {"004a720f9edabb7f82eb30a78da45aceccbca5eb69583e1e8018ec1359a61f27", "e3d319d64bea8069a649acd33859b22361da799e0296f3d4f5117e16feb18e16"}, + {"38716f1d7cde7e37795a5b2d6d6317eecbf0adc6dcf7dcc6ee02cc25d1efb22f", "95c229d0cfc1485f2be0a23de6e49601a2ea55652beead84a67cd727c21a1301"}, + {"22cac7a49e99f3d071812abb0addafa4bf9a65308769728e4cd53cc7486f6c13", "a2e5b90606809964bc20d776b9cbcaab93a2f25124998ae3bd698d061f7afd00"}, + {"5109c7a41f73baa4787358b72ff1095439602add7a86a034b87b74360ee2e20f", "a31b3e2033ed828b5a51b9428f8f6ea40267259df08fdcd2c0e34dd335bdf90c"}, + {"957a87470f29a135567085c3d6d6ed14885bab4eb659725534a45a9f100a471c", "8f3005df282d5a87fa33405e35a313233d05731e87cfcbe060fa067596fa3013"}, + {"e0dad57606c2b293dc7c841c965cb29736d2411003e9284a0ae94d13e3d03d2e", "0543643ef0b617030dcc292451ebcace8bad20706528cb6aedb98dcea66aba27"}, + {"f1f10938c8a55b6b15b3f12beebb702133401135937c5c3f2d7fba702f24da09", "dc862a8a5ad5107421d550731a7f561e4064878c3654bf88b230cc249e91091d"}, + {"4bbc08d78c9970235778d6bd9939c7b2b1bd88b9d1cde6473663ae96ae776911", "3584be9ce31a7fb3aae8515011f4d3eeb86a573b225a88577e4911050bc35013"}, + {"c8325b31c9295757ca23d8f5256eebc5ccc517d28e00bfda5f4d709441d66713", "b81f360903160485c470625519cb18219b44d8b740273ef742fefc5653daf009"}, + {"69a6b3e22fbe5879efa56cdb5d50605732bf7f311e28ba037916b4db61ae8a14", "10ddf800eb3e67da20575456150cb1f0d49506d97ed4ef2d91b951af48966924"}, + {"c2a0e3586d4bb49f2ef979686c3a9a1619d0d54ac89641d592b4628b19dee401", "bc3ba677f6d13ef9f023d4a3b9f073c3eea910ef90cfd24b7f54414d2d02d315"}, + {"5b89051b79ff37457760d7af2ebc68be955e47eb6cdf306fbd369dc19fc52c05", "7bfe2a9d5bb2ade0f9058ea27a07c867af21670d2b9e84bdcc8967d4cdc4ba11"}, + {"46ac45f35cbc23bf68906933ad29240054a0a1d89c1832ebb54aa1bc32644105", "e891e783d5615a1b8ab838f68f6f2ce4e359510ddd40882d4650327d08a5bd11"}, + {"581e067b37c40caf861c190922f816e6cb850540df7ceb159f96c48c1c70cd23", "0d49fa8c74202369c36f4121eab0aa3ac9206ad3419fc9517a88493b07d6fb25"}, + {"bb7eb4ba2b45a22e14fad963c04eadbe8e7aab6ff912b008c9e7dd2a2c7d3615", "758ed0c8cef51f82508072fa758265f0f0eef6c7b2401b94ebe27a638ce33125"}, + {"a08f3cc9904f672b94d1f5a14dedbdef4ed229da5b66eca0135090d6f0ba0728", "542c952395d241cfa15bd48922e9c7fc292dbdd120daa3d66dad67fb3abb700a"}, + {"105bac5c449441bd5f5cf39b431f703e2e8f6a30a90d86cfdf425ec728fdbd08", "b59206f1d556fb98329a7111e3c89bf1e6a4861ec38c82eafa81cff70b713e0d"}, + {"45df2edfaea234dab99efa9a402c0d2feaa841ff3c990c926473173283d95913", "db008cf922c3a50549373a14f5f18b2dc827bd6e168402dfe3e6ece4cb137527"}, + {"488dd6437c15ef5b85e84407b7e599cc078c195ed2fc27b366ddac7739f1eb14", "0448887f55c677464e7e540adf107ba10fc6713e8a2718fe92cbd4794ef4be17"}, + {"3fe697698f3504e15eb5d509efa91624d9aa4eae24beeb42ffcb3c6ea8372a30", "441ccb28e7c6c1893a58f7513c9b7c1c5d0adf3de452644a837d7e08e1ab8117"}, + {"9bb5801272264c74db75f1c6812747bf338ea6880fa4dd2d51ef651ef73c2e04", "e2eefd80e838c30b3f1fb0313fcfcb1e1556439d0346d17334df83c33247b20e"}, + {"bad37a1467c4fe875b78508656f2816414ef602ae2ccd4e9430d94ca5c1cd911", "21c72ccdbaed2e3ea9dac3881531467b64c9322199127f2ae2fa4bb31bad591d"}, + {"95c72237ccbaedc185b1abfc59059c454175df81bb3ff65e5a61e2cb5263ed0d", "1040728a4775ac5cf7a9c75dda2f0aee1fabd6b202b5e916636e3aec73a09d0d"}, + {"738e8b9af4d199bc95f70b2a9b25e999b39af15c6a02f2eca058326078745f2a", "004835960aa03e101d818907df453cefdfb910b44ad9bd056a83b2ef40a5ca0d"}, + {"0d88caf486f2fe60bfc08697d1b617b586ec880e38e4ff56f145a5db0ab6d12e", "a7b19323815295bc84c50535b62c3d4d53dbfc434441eb3c009568fb8f7b2b1a"}, + {"b37af7fd314d90590fba8ebf730397cfdaa97f86d3f31d1a7ddc817ff303791f", "8296a80eceae97f92784642da34f121e29db2c5f3baf9a2722896db22e98b703"}, + {"6b67dd3051a8cb113431f5a14e279d910b7b4798ccb03ff588cf312ffe366a0b", "9c38cc543a0b793be4a0d66de3b2cd30b1f33d36c4402a165da924d7e6f89a12"}, + {"72fc4c40e406b9d1b34daba614460922fc53951abd6db5834e1f1b07fa319f27", "daa4d50481ba47c4a78ae3848a9b268b1d8e0579b4967ebcdece47d386410d02"}, + {"a4ce5cb2b2a23dcf019f275058a4092901c4793e6ee7d29282e755dd0d0df000", "00749453d23051f3587911c34d52e2c2d093273d2283cd6dfba94d7a89cdb226"}, + {"9e00df0216e8ac8e72abfeab1106373a13699714c691f04a549f6b58ea974521", "0e69dbfd9023b8bb58ce7e17972d7c94d49e8464f9c22161d7564ed32c53ef27"}, + {"fe1a558c6315f425fea7c04dcf6db869acd7b62b1b848200d5709e73d53de71b", "66cd33cc8d61cb807092d76ac0e506014fc55624a39ee2afa67f9ba58eb21022"}, + {"3ca542e17e4cbc74f47afb399b12295d15dfbae5e966509b7e6cae2df61a430a", "57a0df429ed3720dee61ca720a4617243b41472f0c7766cc7ce625afddb3b41b"}, + {"c1a77855e9b0b1f7381c9acd69ff68fdfa65f1f753dcea22de5a28ed088c2b2e", "4fce521d725abb8a30d8c39a2a22f496b374d8512b7a76afd3803f7200c86d19"}, + {"17cda8d590adf3042bbf1452fe3d79b959f284f3df1e15ee3c696286f0ba832e", "8919e92a175b55003379ca6e546a04228aa9da861a9669e0e9b106e4a204d404"}, + {"959fa9337b4b479ce5fcff7ff9096a344acf7fcde2f8852e28904236472f2f02", "79e688ecfece239223b745e4b95460bfcb02aee12b154e15db616fda857dcd06"}, + {"d062d34cbdfbc50004a631e3dd8f21b446673b53830aa71fdcbc741e7d4fb31c", "2203af0127657f4e8a1c5ec44bb25028e64ad388efd0b9bfe2105f4f3ff66d0f"}, + {"d2d3e3034864944914709549ce27068b5f27bd18b0edc940593df2dc5c5dae23", "5ae75206bfdc8f54a8673d5d4c4b464ba1e84ae2410418b5c5e98fa993608113"}, + {"4ab457d6478fb27214345f0bc2e00cbb29cd55bed1f8e05c23b8f7810e134a1f", "3db37711e355ed46ea81bb6e31ae87b37b706a8d17e2aa976c7c7706c8e18d19"}, + {"5aa17884c96ecdaf81e2b343dbf051e4ace41935e53378ac10a4387e2cb0c404", "7118986268a748881f6144fc1008e90b40afc702be53784ed4cbceb8606e0714"}, + {"82f4ca6b751ac067e451ae1d5115806e7a1d14ab444084a8ac48046b88b43b30", "8a09186c2a5cb0f16e273be6a8710620006a77afe7c54149bea3dce906345a02"}, + {"55d5d97de81e0cc4d2ac97e507d4d6d9874cb55e1522b89ed2050ff3c20a4912", "27facefe4e2041e11a21889205af6c11eba73e3e8779b801bf3f7253730f1d04"}, + {"845177f4584f61071ddea21e9a6c0a17e1a9408e0c073047c339498ff383c109", "25bc572d1c861fe80156c2fd440e7d9110be8252723d276e806dcc012f8da103"}, + {"ecec46dfdaf45f49f82ee78fd9c8c747c049de9becaf440f90391c04dd119002", "b922e1a7caf72db69dcc062424c7ce75728d010c4c201c2ed8e635a617c81a1f"}, + {"8e265fd9f2a4b158a5eb4bda000a6124af909e118b7510f0ec418559aad85825", "aed92a21e9933bd2ce6c9f09bb7753b46ea31248b324c12726cff08e464bdd0c"}, + {"99d7181572d3ae637a277dcc0c35b9b98bbb6ecf3cdcc69af3e946a5bfeb520f", "89217b554371a2495ee473f867b2e26ea70d4245aceb462a98dd31a37d2d5330"}, + {"a5e1fd149ae27f34e7902ebf380277c0b7f09f37e8809d25a0b8df2965d24e29", "2d6a16a254cfc3894d5500f8c40feb1e84876bc51c68c381109e83f001b41c2f"}, + {"7fd221da235bb6e5fd0ae047f1aa49615ddbeecfb71ccb976bf3e0534425661c", "9ea41ccc3e09572927b0d9f618e1135d384f33618b6a0f80002f0a70be5eb324"}, + {"b125c1b45daa68f96be6a5b3e4dd24e4a0e49e46226d841eb73754a498c43b21", "360b9c39d25451ae58cf651c530155f91e324292b55475a92506de726f153c18"}, + {"d64536234849ababefa90b84f7b7cacf4b073809aa9b0c35581426521f18d81a", "d2dae030312cd4325bb036aa3436b26b9bed69b4d78d68bd49dbdde3173f1510"}, + {"d1ce3aea6cfb7be132d17e8d76fcbe4b7e34cef3979b4b905acfeff2f6d19724", "be47b76297791f535f4b56f973a19f07ec22d4eede2a41ff23c696089938bb21"}, + } +} + +// STATIC_GROUP_MERKLE_ROOT is the root of the Merkle tree constructed from the STATIC_GROUP_KEYS above +// only identity commitments are used for the Merkle tree construction +// the root is created locally, using createMembershipList proc from waku_rln_relay_utils module, and the result is hardcoded in here +const STATIC_GROUP_MERKLE_ROOT = "a1877a553eff12e1b21632a0545a916a5c5b8060ad7cc6c69956741134397b2d" + +// the rln-relay epoch length in seconds +// TODO: change data type +const EPOCH_UNIT_SECONDS = time.Second * 10 + +// the maximum clock difference between peers in seconds +// TODO: change data type +const MAX_CLOCK_GAP_SECONDS = 20 * time.Second + +// maximum allowed gap between the epochs of messages' RateLimitProofs +const MAX_EPOCH_GAP = int64(MAX_CLOCK_GAP_SECONDS / EPOCH_UNIT_SECONDS) + +type Epoch [32]byte + +func BytesToEpoch(b []byte) Epoch { + var result Epoch + copy(result[:], b) + return result +} + +func ToEpoch(t uint64) Epoch { + var result Epoch + binary.LittleEndian.PutUint64(result[:], t) + return result +} + +func (e Epoch) Uint64() uint64 { + return binary.LittleEndian.Uint64(e[:]) +} + +// CalcEpoch gets time `t` as `float64` with subseconds resolution in the fractional part +// and returns its corresponding rln `Epoch` value +func CalcEpoch(t time.Duration) Epoch { + e := uint64(t / EPOCH_UNIT_SECONDS) + return ToEpoch(e) +} + +// GetCurrentEpoch gets the current rln Epoch time +func GetCurrentEpoch() Epoch { + return ToEpoch(uint64(time.Now().Unix())) +} + +// Diff returns the difference between the two rln `Epoch`s `e1` and `e2` +func Diff(e1, e2 Epoch) int64 { + epoch1 := e1.Uint64() + epoch2 := e2.Uint64() + return int64(epoch1) - int64(epoch2) +} diff --git a/rln/utils.go b/rln/utils.go new file mode 100644 index 0000000..f51a993 --- /dev/null +++ b/rln/utils.go @@ -0,0 +1,36 @@ +package rln + +import "encoding/hex" + +func toMembershipKeyPairs(groupKeys [][]string) ([]MembershipKeyPair, error) { + // groupKeys is sequence of membership key tuples in the form of (identity key, identity commitment) all in the hexadecimal format + // the toMembershipKeyPairs proc populates a sequence of MembershipKeyPairs using the supplied groupKeys + + groupKeyPairs := []MembershipKeyPair{} + for _, pair := range groupKeys { + idKey, err := hex.DecodeString(pair[0]) + if err != nil { + return nil, err + } + idCommitment, err := hex.DecodeString(pair[1]) + if err != nil { + return nil, err + } + + groupKeyPairs = append(groupKeyPairs, MembershipKeyPair{IDKey: IDKey(Bytes32(idKey)), IDCommitment: IDCommitment(Bytes32(idCommitment))}) + } + + return groupKeyPairs, nil +} + +func Bytes32(b []byte) [32]byte { + var result [32]byte + copy(result[:], b) + return result +} + +func Bytes256(b []byte) [256]byte { + var result [256]byte + copy(result[:], b) + return result +} diff --git a/rln/waku_rln_relay.go b/rln/waku_rln_relay.go new file mode 100644 index 0000000..8691a6c --- /dev/null +++ b/rln/waku_rln_relay.go @@ -0,0 +1,296 @@ +package rln + +import ( + "bytes" + "encoding/hex" + "errors" + "math" + + "github.com/decanus/go-rln/rln/pb" +) + +type WakuRLNRelay struct { + MembershipKeyPair MembershipKeyPair + // membershipIndex denotes the index of a leaf in the Merkle tree + // that contains the pk of the current peer + // this index is used to retrieve the peer's authentication path + MembershipIndex MembershipIndex + // MembershipContractAddress*: Address + //ethClientAddress*: string + //ethAccountAddress*: Address + // this field is required for signing transactions + // TODO may need to erase this ethAccountPrivateKey when is not used + // TODO may need to make ethAccountPrivateKey mandatory + //ethAccountPrivateKey*: PrivateKey + RLNInstance *RLN + // the pubsub topic for which rln relay is mounted + PubsubTopic string + // contentTopic should be of type waku_message.ContentTopic, however, due to recursive module dependency, the underlying type of ContentTopic is used instead + // TODO a long-term solution is to place types with recursive dependency inside one file + ContentTopic string + // the log of nullifiers and Shamir shares of the past messages grouped per epoch + NullifierLog map[Epoch][]ProofMetadata +} + +func CalcMerkleRoot(list []IDCommitment) (MerkleNode, error) { + // returns the root of the Merkle tree that is computed from the supplied list + + rln, err := NewRLN() + if err != nil { + return MerkleNode{}, err + } + + // create a Merkle tree + for _, c := range list { + if !rln.InsertMember(c) { + return MerkleNode{}, errors.New("could not add member") + } + } + + return rln.GetMerkleRoot() +} + +func createMembershipList(n int) ([][]string, string, error) { + // createMembershipList produces a sequence of membership key pairs in the form of (identity key, id commitment keys) in the hexadecimal format + // this proc also returns the root of a Merkle tree constructed out of the identity commitment keys of the generated list + // the output of this proc is used to initialize a static group keys (to test waku-rln-relay in the off-chain mode) + + // initialize a Merkle tree + rln, err := NewRLN() + if err != nil { + return nil, "", err + } + + var output [][]string + for i := 0; i < n; i++ { + // generate a keypair + keypair, err := rln.MembershipKeyGen() + if err != nil { + return nil, "", err + } + + output = append(output, []string{hex.EncodeToString(keypair.IDKey[:]), hex.EncodeToString(keypair.IDCommitment[:])}) + + // insert the key to the Merkle tree + if !rln.InsertMember(keypair.IDCommitment) { + return nil, "", errors.New("could not insert member") + } + } + + root, err := rln.GetMerkleRoot() + if err != nil { + return nil, "", err + } + + return output, hex.EncodeToString(root[:]), nil +} + +func RLNRelayStaticSetUp(rlnRelayMemIndex MembershipIndex) ([]IDCommitment, MembershipKeyPair, MembershipIndex, error) { + // static group + groupKeys := STATIC_GROUP_KEYS + groupSize := STATIC_GROUP_SIZE + + // validate the user-supplied membership index + if rlnRelayMemIndex < MembershipIndex(0) || rlnRelayMemIndex >= MembershipIndex(groupSize) { + return nil, MembershipKeyPair{}, 0, errors.New("wrong membership index") + } + + // prepare the outputs from the static group keys + + // create a sequence of MembershipKeyPairs from the group keys (group keys are in string format) + groupKeyPairs, err := toMembershipKeyPairs(groupKeys) + if err != nil { + return nil, MembershipKeyPair{}, 0, errors.New("invalid data on group keypairs") + } + + // extract id commitment keys + var groupOpt []IDCommitment + for _, c := range groupKeyPairs { + groupOpt = append(groupOpt, c.IDCommitment) + } + + // user selected membership key pair + memKeyPairOpt := groupKeyPairs[rlnRelayMemIndex] + memIndexOpt := rlnRelayMemIndex + + return groupOpt, memKeyPairOpt, memIndexOpt, nil +} + +func (rln *WakuRLNRelay) HasDuplicate(msg *pb.WakuMessage) (bool, error) { + // returns true if there is another message in the `nullifierLog` of the `rlnPeer` with the same + // epoch and nullifier as `msg`'s epoch and nullifier but different Shamir secret shares + // otherwise, returns false + + if msg == nil { + return false, errors.New("nil message") + } + + msgProof := ToRateLimitProof(msg) + + // extract the proof metadata of the supplied `msg` + proofMD := ProofMetadata{ + Nullifier: msgProof.Nullifier, + ShareX: msgProof.ShareX, + ShareY: msgProof.ShareY, + } + + proofs, ok := rln.NullifierLog[msgProof.Epoch] + + // check if the epoch exists + if !ok { + return false, nil + } + + for _, p := range proofs { + if p.Equals(proofMD) { + // there is an identical record, ignore rhe mag + return false, nil + } + } + + // check for a message with the same nullifier but different secret shares + matched := false + for _, it := range proofs { + if bytes.Equal(it.Nullifier[:], proofMD.Nullifier[:]) && (!bytes.Equal(it.ShareX[:], proofMD.ShareX[:]) || !bytes.Equal(it.ShareY[:], proofMD.ShareY[:])) { + matched = true + break + } + } + + return matched, nil +} + +func (rln *WakuRLNRelay) UpdateLog(msg *pb.WakuMessage) (bool, error) { + // extracts the `ProofMetadata` of the supplied messages `msg` and + // saves it in the `nullifierLog` of the `rlnPeer` + + if msg == nil { + return false, errors.New("nil message") + } + + msgProof := ToRateLimitProof(msg) + + proofMD := ProofMetadata{ + Nullifier: msgProof.Nullifier, + ShareX: msgProof.ShareX, + ShareY: msgProof.ShareY, + } + + proofs, ok := rln.NullifierLog[msgProof.Epoch] + + // check if the epoch exists + if !ok { + rln.NullifierLog[msgProof.Epoch] = []ProofMetadata{proofMD} + return true, nil + } + + // check if an identical record exists + for _, p := range proofs { + if p.Equals(proofMD) { + return true, nil + } + } + + // add proofMD to the log + proofs = append(proofs, proofMD) + rln.NullifierLog[msgProof.Epoch] = proofs + + return true, nil +} + +// TODO: change optionalTime data type +func (rln *WakuRLNRelay) ValidateMessage(msg *pb.WakuMessage, optionalTime float64) (MessageValidationResult, error) { + // validate the supplied `msg` based on the waku-rln-relay routing protocol i.e., + // the `msg`'s epoch is within MAX_EPOCH_GAP of the current epoch + // the `msg` has valid rate limit proof + // the `msg` does not violate the rate limit + // `timeOption` indicates Unix epoch time (fractional part holds sub-seconds) + // if `timeOption` is supplied, then the current epoch is calculated based on that + + if msg == nil { + return MessageValidationResult_Unknown, errors.New("nil message") + } + + // checks if the `msg`'s epoch is far from the current epoch + // it corresponds to the validation of rln external nullifier + var epoch Epoch + if optionalTime != 0 { + epoch = CalcEpoch(optionalTime) + } else { + // get current rln epoch + epoch = GetCurrentEpoch() + } + + msgProof := ToRateLimitProof(msg) + + // calculate the gaps + gap := Diff(epoch, msgProof.Epoch) + + // validate the epoch + if int64(math.Abs(float64(gap))) >= MAX_EPOCH_GAP { + // message's epoch is too old or too ahead + // accept messages whose epoch is within +-MAX_EPOCH_GAP from the current epoch + //debug "invalid message: epoch gap exceeds a threshold", gap = gap, payload = string.fromBytes(msg.payload) + return MessageValidationResult_Invalid, nil + } + + // verify the proof + contentTopicBytes := []byte(msg.ContentTopic) + input := append(msg.Payload, contentTopicBytes...) + if !rln.RLNInstance.Verify(input, *msgProof) { + // invalid proof + //debug "invalid message: invalid proof", payload = string.fromBytes(msg.payload) + return MessageValidationResult_Invalid, nil + } + + // check if double messaging has happened + hasDup, err := rln.HasDuplicate(msg) + if err != nil { + return MessageValidationResult_Unknown, err + } + + if hasDup { + // debug "invalid message: message is a spam", payload = string.fromBytes(msg.payload) + return MessageValidationResult_Spam, nil + } + + // insert the message to the log + // the result of `updateLog` is discarded because message insertion is guaranteed by the implementation i.e., + // it will never error out + _, err = rln.UpdateLog(msg) + if err != nil { + return MessageValidationResult_Unknown, err + } + + //debug "message is valid", payload = string.fromBytes(msg.payload) + return MessageValidationResult_Valid, nil +} + +// TODO: change senderEpochTIme datatype +func (rln *WakuRLNRelay) AppendRLNProof(msg *pb.WakuMessage, senderEpochTime float64) error { + // returns error if it could not create and append a `RateLimitProof` to the supplied `msg` + // `senderEpochTime` indicates the number of seconds passed since Unix epoch. The fractional part holds sub-seconds. + // The `epoch` field of `RateLimitProof` is derived from the provided `senderEpochTime` (using `calcEpoch()`) + + if msg == nil { + return errors.New("nil message") + } + + input := ToRLNSignal(msg) + + proof, err := rln.RLNInstance.GenerateProof(input, rln.MembershipKeyPair, rln.MembershipIndex, CalcEpoch(senderEpochTime)) + if err != nil { + return err + } + + msg.RateLimitProof = &pb.RateLimitProof{ + Proof: proof.Proof[:], + MerkleRoot: proof.MerkleRoot[:], + Epoch: proof.Epoch[:], + ShareX: proof.ShareX[:], + ShareY: proof.ShareY[:], + Nullifier: proof.Nullifier[:], + } + + return nil +} diff --git a/scripts/Cross.toml b/scripts/Cross.toml new file mode 100644 index 0000000..6a32952 --- /dev/null +++ b/scripts/Cross.toml @@ -0,0 +1,32 @@ +[target.x86_64-pc-windows-gnu] +image = "ghcr.io/cross-rs/x86_64-pc-windows-gnu:local" + +[target.aarch64-unknown-linux-gnu] +image = "ghcr.io/cross-rs/aarch64-unknown-linux-gnu:local" + +[target.x86_64-unknown-linux-gnu] +image = "ghcr.io/cross-rs/x86_64-unknown-linux-gnu:local" + +[target.arm-unknown-linux-gnueabi] +image = "ghcr.io/cross-rs/arm-unknown-linux-gnueabi:local" + +[target.i686-pc-windows-gnu] +image = "ghcr.io/cross-rs/i686-pc-windows-gnu:local" + +[target.i686-unknown-linux-gnu] +image = "ghcr.io/cross-rs/i686-unknown-linux-gnu:local" + +[target.arm-unknown-linux-gnueabihf] +image = "ghcr.io/cross-rs/arm-unknown-linux-gnueabihf:local" + +[target.mips-unknown-linux-gnu] +image = "ghcr.io/cross-rs/mips-unknown-linux-gnu:local" + +[target.mips64-unknown-linux-gnuabi64] +image = "ghcr.io/cross-rs/mips64-unknown-linux-gnuabi64:local" + +[target.mips64el-unknown-linux-gnuabi64] +image = "ghcr.io/cross-rs/mips64el-unknown-linux-gnuabi64:local" + +[target.mipsel-unknown-linux-gnu] +image = "ghcr.io/cross-rs/mipsel-unknown-linux-gnu:local" diff --git a/scripts/build-cross.sh b/scripts/build-cross.sh new file mode 100755 index 0000000..0ddfbf1 --- /dev/null +++ b/scripts/build-cross.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +DIRECTORY=./libs +if [[ -d "$DIRECTORY" ]] +then + echo "$DIRECTORY exists on your filesystem. Delete it and run the script again." + exit 0 +fi + +export RUSTFLAGS="-Ccodegen-units=1" +export CROSS_CONFIG="$PWD/scripts/Cross.toml" + +rustup default stable + +cargo install cross --git https://github.com/cross-rs/cross --branch main +cargo install cargo-lipo +# cargo install cargo-strip + +pushd lib/rln + +cargo clean + +cross build --release --lib --target=aarch64-linux-android +cross build --release --lib --target=armv7-linux-androideabi +cross build --release --lib --target=i686-linux-android +cross build --release --lib --target=x86_64-linux-android +cross build --release --lib --target=x86_64-unknown-linux-musl + +# These depend on https://github.com/cross-rs/cross/pull/591 being merged +# In the meantime, we can follow the instructions from here +# https://github.com/cross-rs/cross/wiki/FAQ#newer-linux-versions +# to build the docker images locally. Once that PR is merged, +# remove the CROSS_CONFIG variable and Cross.toml file + +cross build --release --lib --target=x86_64-pc-windows-gnu +cross build --release --lib --target=aarch64-unknown-linux-gnu +cross build --release --lib --target=x86_64-unknown-linux-gnu +cross build --release --lib --target=arm-unknown-linux-gnueabi +cross build --release --lib --target=i686-pc-windows-gnu +cross build --release --lib --target=i686-unknown-linux-gnu +cross build --release --lib --target=arm-unknown-linux-gnueabihf +cross build --release --lib --target=mips-unknown-linux-gnu +cross build --release --lib --target=mips64-unknown-linux-gnuabi64 +cross build --release --lib --target=mips64el-unknown-linux-gnuabi64 +cross build --release --lib --target=mipsel-unknown-linux-gnu + +# TODO: these work only on iOS +rustup target add aarch64-apple-ios x86_64-apple-ios +cross build --release --target=x86_64-apple-darwin --lib +cross build --release --target=aarch64-apple-darwin --lib +cargo lipo --release --targets=aarch64-apple-ios,x86_64-apple-ios + +popd + +TOOLS_DIR=`dirname $0` +COMPILE_DIR=${TOOLS_DIR}/../lib/rln/target +rm -rf $COMPILE_DIR/x86_64-apple-ios $COMPILE_DIR/aarch64-apple-ios +for platform in `ls ${COMPILE_DIR} | grep -v release | grep -v debug` +do + PLATFORM_DIR=${DIRECTORY}/$platform + mkdir -p ${PLATFORM_DIR} + cp ${COMPILE_DIR}/$platform/release/librln.* ${PLATFORM_DIR} +done diff --git a/scripts/build.sh b/scripts/build.sh old mode 100644 new mode 100755 index 5d6924d..8b9d194 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,3 +1,5 @@ +#!/bin/bash + DIRECTORY=./libs if [[ -d "$DIRECTORY" ]] then @@ -56,4 +58,4 @@ do PLATFORM_DIR=${DIRECTORY}/$platform mkdir -p ${PLATFORM_DIR} cp ${COMPILE_DIR}/$platform/release/librln.* ${PLATFORM_DIR} -done +done \ No newline at end of file