Skip to content

Fix/readme #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 43 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Introduction

This repository is an SDK for connecting external services with Rarimo passport
verification system that may be used in back-end services. Its main purpose is
verification and voting systems that may be used in back-end services. Its main purpose is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
verification and voting systems that may be used in back-end services. Its main purpose is
passport and voting proof verification system that may be used in back-end services. Its main purpose is

providing a convenient methods that can be used in any system without deep
introduction in the Rarimo system structure.

Expand All @@ -20,16 +20,16 @@ import (
)

func main() {
rv := root.NewVerifier(contractCaller, reqTimeout)
passportVerifier := root.NewPoseidonSMTVerifier(rpcURL, contractAddress, reqTimeout)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not general usage. Add headers: Passport, Voting, etc.


v, err := kit.NewVerifier(
kit.PassportVerification,
nil,
kit.WithProofType(kit.GeneralPassport),
kit.WithVerificationKeyFile("key.json"),
kit.WithEventID("304358862882731539112827930982999386691702727710421481944329166126417129570"),
kit.WithAgeAbove(18),
kit.WithCitizenships("UKR"),
kit.WithIdentityVerifier(rv),
kit.WithPassportRootVerifier(passportVerifier),
kit.WithIdentitiesCounter(0),
kit.WithIdentitiesCreationTimestampLimit(1847321000),
)
Expand All @@ -44,20 +44,55 @@ func main() {
}
```

```go
package main

import (
kit "github.com/rarimo/zkverifier-kit"
"github.com/rarimo/zkverifier-kit/root"
)

func main() {
pollVerifier := root.NewProposalSMTVerifier(rpcURL, reqTimeout)

v, err := kit.NewVerifier(
nil,
kit.WithProofType(kit.PollParticipation),
kit.WithVerificationKeyFile("key.json"),
kit.WithEventID("304358862882731539112827930982999386691702727710421481944329166126417129570"),
)
if err != nil {
// ...
}
// data is an abstract event data that you expect to be in proof
err = v.VerifyProof(proof,
kit.WithPollParticipationEventID(pollEventID) ,
kit.WithPollRootVerifier(v.WithContract(pollContract)))
if err != nil {
// ...
}
}
```
Let's break this down.

### Configurable root verifier

Firstly, you instantiate identity root verifier, which will verify the
`IdStateRoot` public signal with contract call. You can refer to our
generated contract bindings in [poseidonsmt](internal/poseidonsmt) package.
generated contract bindings in [poseidonsmt](internal/poseidonsmt) and [proposalsmt](internal/proposalsmt) package.
However, maybe, you would like to create the verifier from config map.

Here is configuration sample that you should have in `config.yaml` of your app:
```yaml
root_verifier:
rpc: https://your-rpc
contract: 0x...
verifier:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add examples of using config. It might be either ProvideVerifier() with specified Type or custom initialization without Provider.

allowed_age: 18
allowed_identity_timestamp: 1715698750
poseidonsmt_root_verifier:
rpc: evm_rpc_url
contract: poseidon_smt_contract_address
request_timeout: 10s
proposalsmt_root_verifier:
rpc: evm_rpc_url
request_timeout: 10s
```

Expand Down
9 changes: 9 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ type VerifyOptions struct {
partEventID string
// voteVerifier - verifies root in PollParticipation proof type
voteVerifier root.Verifier
// skipExpirationCheck - specifies whether to check the expiration date.
// Used for tests only
skipExpirationCheck bool
}

// VerifyOption type alias for function that may add new values to VerifyOptions structure.
Expand Down Expand Up @@ -166,6 +169,12 @@ func WithPollRootVerifier(v root.Verifier) VerifyOption {
}
}

func withSkipExpirationCheck(check bool) VerifyOption {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment that it's only for tests, or make it exported and describe a use case

return func(opts *VerifyOptions) {
opts.skipExpirationCheck = check
}
}

// mergeOptions collects all parameters together and fills VerifyOptions struct
// with it, overwriting existing values
func mergeOptions(withDefaults bool, opts VerifyOptions, options ...VerifyOption) VerifyOptions {
Expand Down
6 changes: 4 additions & 2 deletions passport.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func (v *Verifier) validatePubSignals(zkProof zkptypes.ZKProof) error {

func (v *Verifier) validatePassportSignals(signals PubSignalGetter) error {
err := v.opts.passportVerifier.VerifyRoot(signals.Get(IdStateRoot))
if !errors.Is(err, root.ErrInvalidRoot) {
if err != nil && !errors.Is(err, root.ErrInvalidRoot) {
return err
}

Expand Down Expand Up @@ -145,7 +145,9 @@ func (v *Verifier) validatePassportSignals(signals PubSignalGetter) error {
}

maps.Copy(all, v.validateBirthDate(signals))
maps.Copy(all, v.validatePassportExpiration(signals))
if !v.opts.skipExpirationCheck {
maps.Copy(all, v.validatePassportExpiration(signals))
}
maps.Copy(all, v.validateIdentitiesInputs(signals))

return all.Filter()
Expand Down
50 changes: 27 additions & 23 deletions passport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const (
usaCitizenship = "USA"
engCitizenship = "ENG"

validEventID = "304358862882731539112827930982999386691702727710421481944329166126417129570"
validEventID = "211985299740800702300256033401632392934377086534111448880928528431996790315"
invalidEventID = "AC42D1A986804618C7A793FBE814D9B31E47BE51E082806363DCA6958F3062"

storedRoot = "1fd232b83b1927f2a8ede62ffe15c31d18782dd513e08f4aabeaf2e8e4c32417"
Expand All @@ -37,34 +37,33 @@ const verificationKeyFile = "example_verification_key.json"

var validProof = zkptypes.ZKProof{
Proof: &zkptypes.ProofData{
Protocol: "groth16",
A: []string{
"10580782106790373477261932143775321905443589586433651561536061428214589672484",
"11698250021575150794852451179623994478616360899564591934730721390019157908788",
A: []string{"12996016572939291630814335127078241511084725921569267221560959870881226842779",
"761491852560139542885770222513604531448776143684161133298463831447152162597",
"1",
},
B: [][]string{
{
"21705525629420011147308188725178223733293601519891005372105977395761857543648",
"21430490393915822750736844419186297691953172223086304113869075235715014505478",
"7599497178424536454186364289381353824249712189259655444764200186031301149772",
"758126175915585817034687017843086369456608327321178876731878325331363448399",
},
{
"3610890604725359549886067582256338844864753769852189853964284902205861040749",
"7808595281025880671232006108041019334015054900817419103023248582576073762625",
"6552077155141497820322593297915265785002325660175270629851305329247857575000",
"9398527224370554058809232921797193562676853236790343293937085614424613225502",
},
{
"1",
"0",
},
},
C: []string{
"14487193913320584434009947494902473354673034787917761246001827312658064548420",
"13206968032646449669115920135803893331131897495922885759651807223610673459946",
"5520540944773640715610133783195440292316265697892695003821987613285146498487",
"18240929522954357307751256221496990071805852196144718742156278323268552814849",
"1",
},
Protocol: "groth16",
},
PubSignals: []string{
"7639957125598480790492529006924434106731566948760118579546114507674255247458",
"8558624556173674225153579865966359056844751077624402517288712777973816271870",
"0",
"0",
"0",
Expand All @@ -73,26 +72,26 @@ var validProof = zkptypes.ZKProof{
"5589842",
"0",
"0",
"304358862882731539112827930982999386691702727710421481944329166126417129570",
"11318436481061661812577344400351359194387994145300108534310140806143276292370",
"14393086243856018838405247242117964464658357003864077561407424514652280923159",
"211985299740800702300256033401632392934377086534111448880928528431996790315",
"1388928733714245704395968367156897439973029902189556257928944264186457955333",
"16055556473534063237266173531819244891235292810222332599565643356062398286614",
"23073",
"0",
"1713436478",
"1719823039",
"0",
"1",
"3",
"52983525027888",
"53009295290417",
"55199728611377",
"52983525027888",
"53009295159860",
"55199728480820",
"52983525027888",
"0",
},
}

// converted from EventData field in validProof.PubSignals
var (
validEventData = []byte{25, 6, 2, 14, 30, 0, 10, 9, 4, 11, 4, 3, 28, 3, 22, 1, 20, 16, 30, 11, 27, 30, 25, 22, 30, 10, 15, 14, 25, 5, 25, 18}
invalidEventData = []byte{174}
validEventData = []byte{3, 18, 27, 22, 5, 4, 24, 11, 14, 27, 18, 30, 20, 25, 23, 16, 5, 12, 16, 16, 26, 31, 20, 1, 28, 21, 20, 10, 13, 19, 28, 5}
invalidEventData = []byte{4, 18, 27, 22, 5, 4, 24, 11, 14, 27, 18, 30, 20, 25, 23, 16, 5, 12, 16, 16, 26, 31, 20, 1, 28, 21, 20, 10, 13, 19, 28, 5}
)

var verificationKey []byte
Expand Down Expand Up @@ -200,7 +199,7 @@ func TestVerifyProof(t *testing.T) {
WithProofSelectorValue("23073"),
WithEventData(invalidEventData),
},
want: "pub_signals/event_data: must be a valid value",
want: "pub_signals/event_data: event data does not match.",
},
{
name: "Lower age",
Expand All @@ -215,6 +214,7 @@ func TestVerifyProof(t *testing.T) {
want: "pub_signals/birth_date_upper_bound: dates are not equal",
},
{
// We need new proof for every day for pass this test
name: "Equal age",
initOpts: []VerifyOption{
WithVerificationKeyFile(verificationKeyFile),
Expand Down Expand Up @@ -314,6 +314,7 @@ func TestVerifyProof(t *testing.T) {
want: "",
},
{
// We need new proof for every day for pass this test, because of birthdat validation
name: "All valid options",
initOpts: []VerifyOption{
WithProofType(GlobalPassport),
Expand All @@ -328,6 +329,8 @@ func TestVerifyProof(t *testing.T) {
},
want: "",
},
// TODO: disabled verifier don't return error
// We need provide contract and rpc for bad verifier
{
name: "Invalid identity verifier",
initOpts: []VerifyOption{
Expand Down Expand Up @@ -358,6 +361,7 @@ func TestVerifyProof(t *testing.T) {
key = verificationKey
}

tc.initOpts = append(tc.initOpts, withSkipExpirationCheck(true))
verifier, err := NewVerifier(tc.key, tc.initOpts...)
if err != nil {
t.Fatal(err)
Expand Down